photoncloud-monorepo/plans/photoncloud-radical-redesign.md

42 KiB
Raw Permalink Blame History

PhotonCloud 抜本的再設計案 - 詳細版

概要

本設計案は、PhotonCloudシステムを「リソース抽象化レイヤー」を中心とした統一的なアーキテクチャへと再設計するものです。特に、コンピュートリソースVM、コンテナ、将来的にはサーバーレスを統一的に扱えるようにし、コントロールプレーンとデータプレーンを完全に分離することを目標とします。

重要な設計原則: 各ソフトウェアが単体で動作することを前提とし、OpenStackのように全てを動作させないといけない状況を避けます。


1. リソース抽象化レイヤー設計

1.1 抽象化の階層構造

graph TB
    subgraph Resource_Abstraction_Layers [リソース抽象化レイヤー]
        direction TB
        
        subgraph Layer3 [L3: サービス抽象化]
            SVC[Service Interface<br/>S3互換 / Kubernetes API / gRPC]
        end
        
        subgraph Layer2 [L2: リソース抽象化]
            RAL[Resource Abstraction Layer<br/>Compute / Network / Storage]
        end
        
        subgraph Layer1 [L1: プロバイダ抽象化]
            PA[Provider Abstraction<br/>Firecracker / KVM / Containerd / CSI / CNI]
        end
        
        subgraph Layer0 [L0: インフラ実装]
            INF[Infrastructure<br/>HW / ハイパーバイザー / ネットワーク機器]
        end
    end
    
    SVC --> RAL
    RAL --> PA
    PA --> INF

1.2 統一リソースモデル

すべてのリソースは以下の共通構造を持ちます:

// photon-proto/proto/photon/resource.proto
syntax = "proto3";
package photon.resource;

// 全リソースの基底メタデータ
message ResourceMetadata {
    string id = 1;                    // UUID
    string name = 2;                  // 人間可読名
    string namespace = 3;             // マルチテナント用
    string resource_type = 4;         // リソースタイプ識別子
    map<string, string> labels = 5;   // タグ/ラベル
    map<string, string> annotations = 6; // メタデータ
    string created_at = 7;            // RFC3339
    string updated_at = 8;            // RFC3339
    string created_by = 9;            // 作成者ID
    ResourceStatus status = 10;       // 現在のステータス
    string agent_id = 11;             // 管理エージェントID
    string region = 12;               // 配置リージョン
    string zone = 13;                 // 配置ゾーン
}

// リソースステータス
message ResourceStatus {
    enum Phase {
        PENDING = 0;      // 作成待ち
        CREATING = 1;     // 作成中
        RUNNING = 2;      // 実行中/利用可能
        UPDATING = 3;     // 更新中
        DELETING = 4;     // 削除中
        DELETED = 5;      // 削除済み
        ERROR = 6;        // エラー状態
        SUSPENDED = 7;    // 一時停止
    }
    Phase phase = 1;
    string message = 2;   // 人間可読なステータス説明
    int64 observed_generation = 3;
}

// リソース仕様の抽象化
message ResourceSpec {
    string resource_type = 1;
    bytes spec_data = 2;  // タイプ固有の仕様protobuf Any相当
}

// 統一リソース操作サービス
service ResourceService {
    rpc Create(CreateRequest) returns (CreateResponse);
    rpc Get(GetRequest) returns (GetResponse);
    rpc Update(UpdateRequest) returns (UpdateResponse);
    rpc Delete(DeleteRequest) returns (DeleteResponse);
    rpc List(ListRequest) returns (stream ListResponse);
    rpc Watch(WatchRequest) returns (stream WatchResponse);
    rpc ExecuteAction(ActionRequest) returns (ActionResponse);
}

1.3 コンピュートリソースの統一抽象化

Firecracker microVMと通常のVM、コンテナ、Kubernetes Podを同じ「計算資源」として扱います

// photon-proto/proto/photon/compute.proto
syntax = "proto3";
package photon.compute;

import "photon/resource.proto";

// コンピュートインスタンスVMとコンテナの統一
message ComputeInstance {
    photon.resource.ResourceMetadata metadata = 1;
    ComputeInstanceSpec spec = 2;
}

message ComputeInstanceSpec {
    // バックエンドタイプで実装を切り替え
    oneof backend {
        FirecrackerSpec firecracker = 1;
        KvmSpec kvm = 2;
        ContainerSpec container = 3;
        KubernetesPodSpec k8s_pod = 4;
    }
    
    // 共通設定
    ComputeResources resources = 10;
    NetworkAttachment network = 11;
    repeated StorageAttachment storage = 12;
    string user_data = 13;  // cloud-init等
}

message ComputeResources {
    int32 vcpu = 1;
    int64 memory_mb = 2;
    int64 disk_gb = 3;
    string cpu_arch = 4;  // x86_64, arm64
}

message FirecrackerSpec {
    string kernel_image = 1;
    string rootfs_image = 2;
    map<string, string> machine_config = 3;
}

message KvmSpec {
    string disk_image = 1;
    string machine_type = 2;  // q35, pc
    bool enable_kvm = 3;
}

message ContainerSpec {
    string image = 1;
    repeated string command = 2;
    repeated string args = 3;
    map<string, string> env = 4;
}

message KubernetesPodSpec {
    string cluster_id = 1;
    bytes pod_spec = 2;  // Kubernetes PodSpec serialized
}

1.4 ネットワークリソース抽象化

// photon-proto/proto/photon/network.proto
syntax = "proto3";
package photon.network;

import "photon/resource.proto";

// VPC
message Vpc {
    photon.resource.ResourceMetadata metadata = 1;
    VpcSpec spec = 2;
}

message VpcSpec {
    string cidr_block = 1;
    bool enable_dns_hostnames = 2;
    bool enable_dns_support = 3;
}

// サブネット
message Subnet {
    photon.resource.ResourceMetadata metadata = 1;
    SubnetSpec spec = 2;
}

message SubnetSpec {
    string vpc_id = 1;
    string cidr_block = 2;
    string availability_zone = 3;
}

// ロードバランサー
message LoadBalancer {
    photon.resource.ResourceMetadata metadata = 1;
    LoadBalancerSpec spec = 2;
}

message LoadBalancerSpec {
    enum Type {
        L4 = 0;
        L7 = 1;
    }
    Type type = 1;
    repeated string subnet_ids = 2;
    repeated Listener listeners = 3;
}

message Listener {
    int32 port = 1;
    string protocol = 2;  // TCP, UDP, HTTP, HTTPS
    string target_group_id = 3;
}

// DNSゾーンとレコード
message DnsZone {
    photon.resource.ResourceMetadata metadata = 1;
    DnsZoneSpec spec = 2;
}

message DnsZoneSpec {
    string name = 1;  // example.com
    bool is_private = 2;
    string vpc_id = 3;  // private zone用
}

1.5 ストレージリソース抽象化

// photon-proto/proto/photon/storage.proto
syntax = "proto3";
package photon.storage;

import "photon/resource.proto";

// ブロックストレージボリューム
message Volume {
    photon.resource.ResourceMetadata metadata = 1;
    VolumeSpec spec = 2;
}

message VolumeSpec {
    int64 size_gb = 1;
    enum VolumeType {
        STANDARD = 0;
        SSD = 1;
        NVME = 2;
    }
    VolumeType type = 2;
    bool encrypted = 3;
    string kms_key_id = 4;
}

// オブジェクトストレージバケット
message Bucket {
    photon.resource.ResourceMetadata metadata = 1;
    BucketSpec spec = 2;
}

message BucketSpec {
    string region = 1;
    bool versioning_enabled = 2;
    repeated LifecycleRule lifecycle_rules = 3;
}

message LifecycleRule {
    int32 expiration_days = 1;
    string prefix = 2;
}

// ファイルシステム
message Filesystem {
    photon.resource.ResourceMetadata metadata = 1;
    FilesystemSpec spec = 2;
}

message FilesystemSpec {
    enum Type {
        NFS = 0;
        EFS = 1;
    }
    Type type = 1;
    int64 size_gb = 2;
    string performance_mode = 3;
}

2. コンポーネント統合・グルーピング案

2.1 統合マトリックス

コンポーネントA コンポーネントB 統合可能性 統合後名称 備考
fiberlb prismnet ◎ 高 photonnet ネットワークサービス統合
fiberlb flashdns ◎ 高 photonnet DNS-LB連携
prismnet flashdns ○ 中〜高 photonnet VPC内DNS統合
iam mtls-agent ◎ 高 photonauth セキュリティ基盤統合
plasmavmc k8shost ○ 中 photon-compute コンピュート層統合(検討)
chainfire flaredb × - 統合困難

2.2 新ディレクトリ構造

/home/centra/cloud/
├── Cargo.toml                           # ルートワークスペース
│
├── photon-common/                       # 共通基盤(新規)
│   ├── Cargo.toml
│   └── crates/
│       ├── photon-sdk/                  # リソース操作SDK
│       ├── photon-grpc/                 # gRPC共通実装
│       ├── photon-config/               # 設定管理
│       ├── photon-telemetry/            # モニタリング
│       ├── photon-error/                # 共通エラー型
│       └── photon-resource-model/       # リソースモデル定義
│
├── photon-control-plane/                # コントロールプレーン(新規)
│   ├── Cargo.toml
│   └── crates/
│       ├── photon-api-gateway/          # 統一APIゲートウェイ
│       ├── photon-resource-manager/     # リソースライフサイクル管理
│       ├── photon-scheduler/            # グローバルスケジューラ
│       ├── photon-identity/             # 統合認証サービス
│       └── photon-eventbus/             # イベント基盤
│
├── photon-data-plane/                   # データプレーン(新規)
│   ├── Cargo.toml
│   └── crates/
│       ├── photon-agent/                # 統一エージェント
│       ├── photon-agent-sdk/            # エージェントプラグインSDK
│       ├── photon-compute-provider/     # コンピュートリソース提供
│       ├── photon-network-provider/     # ネットワークリソース提供
│       └── photon-storage-provider/     # ストレージリソース提供
│
├── photonnet/                           # 統合: fiberlb + prismnet + flashdns
│   ├── Cargo.toml
│   └── crates/
│       ├── photonnet-types/             # 共通ネットワーク型
│       ├── photonnet-core/              # VPC/IPAM基盤
│       ├── photonnet-lb/                # ロードバランサー
│       ├── photonnet-dns/               # DNSサーバー
│       └── photonnet-server/            # 統合サーバー
│
├── photonauth/                          # 統合: iam + mtls-agent
│   ├── Cargo.toml
│   └── crates/
│       ├── photonauth-types/            # 認証・認可型
│       ├── photonauth-authn/            # 認証サービス
│       ├── photonauth-authz/            # 認可・ポリシー評価
│       ├── photonauth-mtls/             # mTLS証明書管理
│       ├── photonauth-audit/            # 監査ログ
│       └── photonauth-server/           # 統合サーバー
│
├── photon-proto/                        # 統一proto定義
│   └── proto/
│       ├── photon/resource.proto        # リソース基底定義
│       ├── photon/compute.proto         # コンピュートリソース
│       ├── photon/network.proto         # ネットワークリソース
│       ├── photon/storage.proto         # ストレージリソース
│       └── photon/identity.proto        # アデンティティリソース
│
├── chainfire/                           # 既存分散KV・状態保存
│   └── ...
│
├── flaredb/                             # 既存分散SQL
│   └── ...
│
├── lightningstor/                       # 既存(オブジェクトストレージ)
│   └── ...
│
├── plasmavmc/                           # 段階的移行対象VM管理
│   └── ...
│
├── k8shost/                             # 段階的移行対象K8sホスト
│   └── ...
│
├── apigateway/                          # 既存L7ゲートウェイ
│   └── ...
│
├── creditservice/                       # 既存(課金サービス)
│   └── ...
│
├── nightlight/                          # 既存(監視・メトリクス)
│   └── ...
│
└── nix/
    └── modules/
        ├── photon-common.nix
        ├── photon-control-plane.nix
        ├── photon-data-plane.nix
        ├── photonnet.nix
        ├── photonauth.nix
        └── ...

2.3 photon-common共通基盤詳細設計

// photon-common/crates/photon-error/src/lib.rs
use thiserror::Error;

/// PhotonCloud共通エラー型
#[derive(Error, Debug, Clone)]
pub enum PhotonError {
    #[error("storage error: {0}")]
    Storage(#[from] StorageError),
    
    #[error("network error: {0}")]
    Network(#[from] NetworkError),
    
    #[error("consensus error: {0}")]
    Consensus(#[from] ConsensusError),
    
    #[error("configuration error: {0}")]
    Config(String),
    
    #[error("invalid argument: {0}")]
    InvalidArgument(String),
    
    #[error("not found: {0}")]
    NotFound(String),
    
    #[error("already exists: {0}")]
    AlreadyExists(String),
    
    #[error("permission denied: {0}")]
    PermissionDenied(String),
    
    #[error("unauthenticated: {0}")]
    Unauthenticated(String),
    
    #[error("timeout: {0}")]
    Timeout(String),
    
    #[error("internal error: {0}")]
    Internal(String),
}

pub type PhotonResult<T> = std::result::Result<T, PhotonError>;

2.4 photonnetネットワーク統合詳細設計

// photonnet/crates/photonnet-core/src/vpc.rs
use photon_resource_model::*;

/// VPC管理トレイト
#[async_trait]
pub trait VpcManager: ResourceProvider {
    /// VPC作成
    async fn create_vpc(&self, spec: VpcSpec) -> PhotonResult<Vpc>;
    
    /// サブネット作成
    async fn create_subnet(&self, vpc_id: &str, spec: SubnetSpec) -> PhotonResult<Subnet>;
    
    /// IPAM統合
    async fn allocate_ip(&self, subnet_id: &str) -> PhotonResult<IpAllocation>;
    
    /// VPC間ピアリング
    async fn create_peering(&self, vpc1: &str, vpc2: &str) -> PhotonResult<VpcPeering>;
}

// photonnet/crates/photonnet-lb/src/lib.rs
use photon_resource_model::*;

/// ロードバランサープロバイダ
#[async_trait]
pub trait LoadBalancerProvider: ResourceProvider {
    /// LB作成
    async fn create_lb(&self, spec: LoadBalancerSpec) -> PhotonResult<LoadBalancer>;
    
    /// ターゲットグループ管理
    async fn register_target(&self, tg_id: &str, target: Target) -> PhotonResult<()>;
    
    /// ヘルスチェック統合
    async fn configure_health_check(&self, tg_id: &str, config: HealthCheckConfig) -> PhotonResult<()>;
}

// photonnet/crates/photonnet-dns/src/lib.rs
use photon_resource_model::*;

/// DNSプロバイダ
#[async_trait]
pub trait DnsProvider: ResourceProvider {
    /// ゾーン作成
    async fn create_zone(&self, spec: DnsZoneSpec) -> PhotonResult<DnsZone>;
    
    /// レコード管理
    async fn manage_record(&self, zone_id: &str, record: DnsRecord) -> PhotonResult<()>;
    
    /// サービスディスカバリ統合
    async fn register_service(&self, service: ServiceRecord) -> PhotonResult<()>;
}

2.5 photonauth認証統合詳細設計

// photonauth/crates/photonauth-types/src/lib.rs

/// 統一認証トークン
#[derive(Debug, Clone)]
pub struct PhotonToken {
    pub subject: String,           // ユーザー/サービスID
    pub issuer: String,            // 発行者
    pub audience: Vec<String>,     // 対象サービス
    pub issued_at: chrono::DateTime<chrono::Utc>,
    pub expires_at: chrono::DateTime<chrono::Utc>,
    pub scopes: Vec<String>,       // 権限スコープ
    pub claims: HashMap<String, serde_json::Value>,
}

// photonauth/crates/photonauth-authn/src/lib.rs

/// 認証サービス
#[async_trait]
pub trait AuthenticationService {
    /// パスワード認証
    async fn authenticate_password(&self, username: &str, password: &str) -> PhotonResult<PhotonToken>;
    
    /// トークン検証
    async fn verify_token(&self, token: &str) -> PhotonResult<TokenClaims>;
    
    /// サービス間認証
    async fn authenticate_service(&self, service_id: &str, secret: &str) -> PhotonResult<ServiceToken>;
}

// photonauth/crates/photonauth-mtls/src/lib.rs

/// mTLS証明書管理
#[async_trait]
pub trait MtlsManager {
    /// サービス証明書発行
    async fn issue_service_certificate(&self, service_id: &str) -> PhotonResult<Certificate>;
    
    /// 証明書ローテーション
    async fn rotate_certificate(&self, cert_id: &str) -> PhotonResult<Certificate>;
    
    /// 証明書失効
    async fn revoke_certificate(&self, cert_id: &str) -> PhotonResult<()>;
    
    /// 信頼アンカー取得
    async fn get_trust_anchor(&self) -> PhotonResult<TrustAnchor>;
}

3. コントロールプレーン/データプレーン分離設計

3.1 アーキテクチャ全体図

graph TB
    subgraph PhotonCloud_Control_Plane [PhotonCloud Control Plane]
        AG[API Gateway<br/>photon-api-gateway]
        RM[Resource Manager<br/>photon-resource-manager]
        SCH[Scheduler<br/>photon-scheduler]
        IS[Identity Service<br/>photon-identity]
        EB[Event Bus<br/>photon-eventbus]
        CH[chainfire<br/>State Store]
    end

    subgraph PhotonCloud_Data_Plane [PhotonCloud Data Plane]
        subgraph Unified_Agent_Framework [Unified Agent Framework]
            UA[Unified Agent<br/>photon-agent]
            PM[Plugin Manager]
        end
        
        subgraph Resource_Providers [Resource Providers]
            CP[Compute Provider<br/>VM + K8s統合]
            NP[Network Provider<br/>LB + VPC + DNS]
            SP[Storage Provider<br/>Object + Block]
        end
    end

    subgraph External_Systems [External Systems]
        CLI[Cloud CLI]
        SDK[SDK Clients]
        LEG[Legacy API Clients]
    end

    External_Systems -->|gRPC/REST| AG
    AG -->|Authenticate| IS
    AG -->|Resource Ops| RM
    RM -->|Schedule| SCH
    RM -->|Events| EB
    RM -->|State| CH
    SCH -->|Placement| UA
    EB -->|Notify| UA
    UA -->|Plugin Load| PM
    PM -->|Manage| CP
    PM -->|Manage| NP
    PM -->|Manage| SP

3.2 責務の分離

レイヤー 責務 コンポーネント
コントロールプレーン API受付、認証、スケジューリング、状態管理、イベント発行 API Gateway, Resource Manager, Scheduler, Identity, EventBus
データプレーン 実際のリソース操作、ハイパーバイザー連携、ネットワーク設定 Unified Agent, Resource Providers

3.3 通信シーケンスVM作成例

sequenceDiagram
    participant Client
    participant AG as API Gateway
    participant IS as Identity Service
    participant RM as Resource Manager
    participant SCH as Scheduler
    participant EB as Event Bus
    participant UA as Unified Agent
    participant CP as Compute Provider
    participant CH as chainfire

    Client->>AG: Create ComputeInstance
    AG->>IS: Authenticate & Authorize
    IS-->>AG: Token Valid
    
    AG->>RM: Create Resource
    RM->>CH: Store Desired State
    RM->>SCH: Schedule Resource
    
    SCH->>CH: Find Suitable Agent
    SCH-->>RM: Agent Selected
    
    RM->>EB: Publish ResourceCreated Event
    RM-->>AG: Accepted (Async)
    AG-->>Client: 202 Accepted + Operation ID
    
    EB->>UA: Notify ResourceCreated
    UA->>CP: Create Resource
    CP-->>UA: Resource Ready
    
    UA->>CH: Update Actual State
    UA->>EB: Publish ResourceReady Event
    
    RM->>CH: Watch State Changes
    CH-->>RM: State Updated

3.4 コントロールプレーンコンポーネント詳細

API Gateway

// photon-control-plane/crates/photon-api-gateway/src/lib.rs
pub struct ApiGateway {
    resource_manager: ResourceManagerClient,
    identity_service: IdentityServiceClient,
    event_bus: EventBusClient,
}

impl ApiGateway {
    /// 統一APIエンドポイント
    pub async fn handle_resource_request(
        &self,
        request: ResourceRequest,
    ) -> Result<ApiResponse, ApiError> {
        // 認証
        let claims = self.identity_service.authenticate(&request.token).await?;
        
        // 認可
        self.identity_service.authorize(
            &claims,
            &request.resource_type,
            &request.action,
        ).await?;
        
        // リソースマネージャーへ転送
        let operation = self.resource_manager.submit(request).await?;
        
        // 非同期処理として受理
        Ok(ApiResponse::accepted(operation.id))
    }
    
    /// 互換性レイヤー既存APIサポート
    pub async fn handle_legacy_request(
        &self,
        service: &str,
        request: LegacyRequest,
    ) -> Result<ApiResponse, ApiError> {
        // 既存APIを新リソースモデルに変換
        let resource_request = self.translate_legacy_request(service, request)?;
        self.handle_resource_request(resource_request).await
    }
}

Resource Manager

// photon-control-plane/crates/photon-resource-manager/src/lib.rs
pub struct ResourceManager {
    state_store: Arc<dyn StateStore>,
    scheduler: Arc<dyn Scheduler>,
    event_bus: Arc<dyn EventBus>,
    provider_registry: ProviderRegistry,
}

impl ResourceManager {
    /// リソース作成リクエスト処理
    pub async fn create_resource(
        &self,
        request: CreateResourceRequest,
    ) -> Result<Operation, ResourceError> {
        // 1. リソースID生成
        let resource_id = ResourceId::generate();
        
        // 2. Desired State保存
        let desired_state = ResourceState::desired(
            resource_id.clone(),
            request.spec.clone(),
        );
        self.state_store.put(&resource_id, &desired_state).await?;
        
        // 3. スケジューリング
        let placement = self.scheduler.schedule(&request.spec).await?;
        
        // 4. Operation作成
        let operation = Operation::new(OperationType::Create, resource_id.clone());
        
        // 5. イベント発行
        self.event_bus.publish(ResourceEvent::Created {
            resource_id: resource_id.clone(),
            spec: request.spec,
            target_agent: placement.agent_id,
        }).await?;
        
        Ok(operation)
    }
    
    /// 状態同期ループ(リコンシリエーション)
    pub async fn reconciliation_loop(&self) {
        loop {
            // Desired StateとActual Stateの差分を検出
            let drifted = self.state_store.find_drifted().await;
            
            for resource in drifted {
                // 調整イベント発行
                self.event_bus.publish(ResourceEvent::Reconcile {
                    resource_id: resource.id,
                    desired: resource.desired,
                    actual: resource.actual,
                }).await.ok();
            }
            
            tokio::time::sleep(Duration::from_secs(30)).await;
        }
    }
}

Scheduler

// photon-control-plane/crates/photon-scheduler/src/lib.rs
pub struct Scheduler {
    agent_registry: Arc<dyn AgentRegistry>,
    placement_engine: PlacementEngine,
}

impl Scheduler {
    /// リソース配置決定
    pub async fn schedule(
        &self,
        spec: &ResourceSpec,
    ) -> Result<Placement, ScheduleError> {
        // 1. 要件を満たすエージェントをフィルタリング
        let candidates = self.agent_registry
            .find_capable(spec.resource_type())
            .await?;
        
        // 2. スコアリング
        let scored: Vec<ScoredAgent> = candidates
            .into_iter()
            .map(|agent| {
                let score = self.placement_engine.score(&agent, spec);
                ScoredAgent { agent, score }
            })
            .filter(|s| s.score > 0.0)
            .collect();
        
        // 3. 最適なエージェントを選択
        let selected = scored.into_iter()
            .max_by(|a, b| a.score.partial_cmp(&b.score).unwrap())
            .ok_or(ScheduleError::NoSuitableAgent)?;
        
        Ok(Placement {
            agent_id: selected.agent.id,
            region: selected.agent.region,
            zone: selected.agent.zone,
        })
    }
}

3.5 データプレーンUnified Agent詳細設計

// photon-data-plane/crates/photon-agent/src/lib.rs
pub struct PhotonAgent {
    config: AgentConfig,
    plugin_manager: PluginManager,
    resource_controller: ResourceController,
    heartbeat: HeartbeatService,
    telemetry: TelemetryService,
}

impl PhotonAgent {
    pub async fn run(self) -> Result<(), AgentError> {
        // 1. プラグイン読み込み
        self.plugin_manager.load_plugins().await?;
        
        // 2. コントロールプレーンへ登録
        self.heartbeat.register().await?;
        
        // 3. 並行タスク実行
        tokio::select! {
            _ = self.heartbeat.run() => {},
            _ = self.resource_controller.run() => {},
            _ = self.telemetry.run() => {},
            _ = self.handle_events() => {},
        }
        
        Ok(())
    }
}

/// プラグインマネージャー
pub struct PluginManager {
    plugins: HashMap<ResourceType, Box<dyn ResourceProviderPlugin>>,
    plugin_dir: PathBuf,
}

impl PluginManager {
    pub async fn load_plugins(&mut self) -> Result<(), PluginError> {
        for entry in fs::read_dir(&self.plugin_dir)? {
            let path = entry?.path();
            if path.extension() == Some("so".as_ref()) {
                let plugin = unsafe { self.load_plugin(&path)? };
                
                for resource_type in plugin.supported_types() {
                    info!("Registering plugin for {:?}", resource_type);
                    self.plugins.insert(resource_type, plugin.box_clone());
                }
            }
        }
        Ok(())
    }
}

/// プラグイントレイト
#[async_trait]
pub trait ResourceProviderPlugin: Send + Sync {
    fn supported_types(&self) -> Vec<ResourceType>;
    
    async fn initialize(&mut self, config: PluginConfig) -> Result<(), PluginError>;
    
    async fn create_resource(
        &self,
        spec: ResourceSpec,
    ) -> Result<ResourceState, PluginError>;
    
    async fn delete_resource(&self, id: &ResourceId) -> Result<(), PluginError>;
    
    async fn execute_action(
        &self,
        id: &ResourceId,
        action: &str,
        params: serde_json::Value,
    ) -> Result<ActionResult, PluginError>;
    
    fn box_clone(&self) -> Box<dyn ResourceProviderPlugin>;
}

4. 単体運用と統合のバランス設計

4.1 コンポーネントの独立性マトリックス

コンポーネント 単体運用 必須/オプション 依存関係 最小構成
lightningstor ◎ 完全独立 オプション なし 単独でS3互換API提供可能
flashdns ◎ 完全独立 オプション なし 単独でDNSサーバーとして動作
fiberlb ◎ 完全独立 オプション なし 単独でLBとして動作
chainfire ○ 準独立 推奨 なし 状態保存に使用
flaredb ◎ 完全独立 オプション なし 単独でSQL DBとして動作
plasmavmc △ 制限あり オプション chainfire VM管理のみ
k8shost △ 制限あり オプション chainfire, prismnet K8sホストのみ
photonnet ○ 準独立 推奨 chainfire ネットワーク統合
photonauth ○ 準独立 推奨 chainfire 認証統合

4.2 最小構成パターン

パターン1: オブジェクトストレージのみlightningstor単体

graph LR
    A[Client] -->|S3 API| B[lightningstor]
    B -->|Metadata| C[Local RocksDB]
    B -->|Data| D[Local Filesystem]
# 最小構成: lightningstorのみ
services.lightningstor = {
  enable = true;
  s3Api = {
    enable = true;
    port = 9000;
  };
  storage = {
    backend = "filesystem";
    path = "/var/lib/lightningstor";
  };
};

パターン2: DNSのみflashdns単体

graph LR
    A[Client] -->|DNS Query| B[flashdns]
    B -->|Records| C[Local Storage]
# 最小構成: flashdnsのみ
services.flashdns = {
  enable = true;
  port = 53;
  zones = [
    { name = "example.com"; file = "/etc/dns/example.com.zone"; }
  ];
};

パターン3: VM管理のみplasmavmc単体

graph LR
    A[Client] -->|API| B[plasmavmc]
    B -->|State| C[chainfire]
    B -->|VM| D[Firecracker/KVM]
# 最小構成: plasmavmc + chainfire
services.chainfire = {
  enable = true;
  nodeId = "vm-node-1";
};

services.plasmavmc = {
  enable = true;
  chainfireEndpoint = "localhost:2379";
  hypervisor = "firecracker";
};

パターン4: 完全統合構成

graph TB
    subgraph Control_Plane [Control Plane]
        AG[API Gateway]
        RM[Resource Manager]
    end
    
    subgraph Data_Plane [Data Plane]
        UA[Unified Agent]
    end
    
    subgraph Services [Services]
        S[Storage Provider]
        N[Network Provider]
        C[Compute Provider]
    end
    
    AG --> RM
    RM --> UA
    UA --> S
    UA --> N
    UA --> C

4.3 段階的な機能追加

graph LR
    A[最小構成] -->|+ PhotonNet| B[ネットワーク統合]
    B -->|+ PhotonAuth| C[認証統合]
    C -->|+ Control Plane| D[完全統合]
    
    A -->|+ Storage Provider| E[ストレージ強化]
    B -->|+ Network Provider| F[ネットワーク強化]
段階 追加コンポーネント 機能
レベル0 lightningstor単体 S3互換オブジェクトストレージ
レベル1 + flashdns単体 権威DNSサーバー
レベル2 + fiberlb単体 L4/L7ロードバランサー
レベル3 + photonnet統合 VPC/IPAM/DNS統合
レベル4 + photonauth統合 認証・認可・mTLS統合
レベル5 + Control Plane 統一リソース管理

5. イベント駆動設計

5.1 イベントスキーマ

// photon-proto/proto/photon/event.proto
syntax = "proto3";
package photon.event;

import "photon/resource.proto";

// イベントエンベロープ
message Event {
    string event_id = 1;
    string event_type = 2;
    string timestamp = 3;  // RFC3339
    string source = 4;     // イベント発行元
    
    oneof payload {
        ResourceEvent resource_event = 10;
        AgentEvent agent_event = 11;
        SystemEvent system_event = 12;
        AuditEvent audit_event = 13;
    }
}

// リソース関連イベント
message ResourceEvent {
    string resource_id = 1;
    string resource_type = 2;
    
    oneof event {
        ResourceCreated created = 10;
        ResourceUpdated updated = 11;
        ResourceDeleted deleted = 12;
        ResourceStateChanged state_changed = 13;
        ResourceActionExecuted action_executed = 14;
    }
}

message ResourceCreated {
    photon.resource.ResourceSpec spec = 1;
    string target_agent = 2;
}

message ResourceStateChanged {
    photon.resource.ResourceStatus old_status = 1;
    photon.resource.ResourceStatus new_status = 2;
    string reason = 3;
}

// エージェントイベント
message AgentEvent {
    string agent_id = 1;
    
    oneof event {
        AgentRegistered registered = 10;
        AgentHeartbeat heartbeat = 11;
        AgentDisconnected disconnected = 12;
        AgentCapacityChanged capacity_changed = 13;
    }
}

message AgentHeartbeat {
    map<string, int32> resource_counts = 1;
    ResourceMetrics metrics = 2;
}

// 監査イベント(自動生成)
message AuditEvent {
    string actor_id = 1;
    string action = 2;
    string resource_id = 3;
    bool success = 4;
    map<string, string> metadata = 5;
}

5.2 イベントフロー例VM作成

sequenceDiagram
    participant Client
    participant RM as Resource Manager
    participant EB as Event Bus
    participant SCH as Scheduler
    participant UA as Unified Agent
    participant CP as Compute Provider
    participant Audit as Audit Logger

    Client->>RM: Create VM Request
    RM->>EB: Publish ResourceCreated
    
    par 並行処理
        EB->>Audit: Log Audit Event
        EB->>SCH: Trigger Scheduling
        RM->>RM: Start Timeout Timer
    end
    
    SCH->>EB: Publish AgentAssigned
    EB->>UA: Notify Assignment
    
    UA->>CP: Create VM
    CP-->>UA: VM Created
    
    UA->>EB: Publish ResourceStateChanged<br/>PENDING → RUNNING
    
    EB->>RM: Update State
    EB->>Client: WebSocket Push Notification
    
    alt 失敗時
        CP-->>UA: Error
        UA->>EB: Publish ResourceStateChanged<br/>PENDING → ERROR
        EB->>RM: Mark Failed
        EB->>SCH: Trigger Reschedule
    end

6. 移行戦略

6.1 段階的移行フェーズ

gantt
    title PhotonCloud移行ロードマップ
    dateFormat  YYYY-MM
    
    section Phase 0: 準備
    共通基盤設計           :done, p0_design, 2026-01, 1M
    
    section Phase 1: 共通基盤構築
    photon-common開発      :active, p1_common, after p0_design, 2M
    photon-proto定義       :p1_proto, after p0_design, 1M
    chainfire統合          :p1_cf, after p1_common, 1M
    
    section Phase 2: コントロールプレーン
    EventBus実装           :p2_event, after p1_proto, 1M
    Resource Manager       :p2_rm, after p2_event, 2M
    Scheduler              :p2_sch, after p2_rm, 1M
    Identity Service       :p2_id, after p2_rm, 2M
    API Gateway            :p2_api, after p2_rm, 2M
    
    section Phase 3: データプレーン
    Unified Agent          :p3_agent, after p2_sch, 2M
    Compute Provider       :p3_compute, after p3_agent, 2M
    Network Provider       :p3_net, after p3_agent, 2M
    Storage Provider       :p3_storage, after p3_agent, 2M
    
    section Phase 4: 統合
    レガシー統合レイヤー    :p4_compat, after p3_compute, 1M
    段階的移行            :p4_migrate, after p4_compat, 3M
    レガシー削除            :p4_cleanup, after p4_migrate, 2M

6.2 各フェーズの詳細

Phase 1: 共通基盤構築月1-3

タスク 説明 成果物
photon-common エラー、設定、gRPC、メトリクスの共通実装 共通ライブラリ群
photon-proto 統一リソースモデルのProto定義 protoファイル群
chainfire統合 状態保存バックエンドとしてchainfire統合 chainfireアダプター

Phase 2: コントロールプレーン構築月3-7

タスク 説明 依存関係
EventBus メッセージキュー/NATSベースのイベント基盤 photon-common
Resource Manager リソースライフサイクル管理 EventBus, chainfire
Scheduler リソース配置スケジューラ Resource Manager
Identity Service iam + mtls-agent統合 photon-common
API Gateway 統一APIゲートウェイ互換性レイヤー付き 上記全部

Phase 3: データプレーン構築月5-9

タスク 説明 成果物
Unified Agent 統一エージェントフレームワーク photon-agent
Compute Provider VM + K8s統合プロバイダ photon-compute-provider
Network Provider fiberlb+prismnet+flashdns統合 photon-network-provider
Storage Provider lightningstor + 必要に応じてflaredb統合 photon-storage-provider

Phase 4: 統合と移行月8-15

タスク 説明 アプローチ
互換性レイヤー 既存APIを新アーキテクチャに変換 アダプターパターン
段階的移行 コンポーネントごとに新システムへ移行 ストラングラーフィグパターン
レガシー削除 完全移行後のクリーンアップ -

6.3 互換性維持戦略

// photon-control-plane/crates/photon-api-gateway/src/compat/mod.rs

/// 既存APIとの互換性レイヤー
pub struct CompatibilityLayer {
    resource_manager: Arc<ResourceManager>,
    translators: HashMap<String, Box<dyn ApiTranslator>>,
}

impl CompatibilityLayer {
    /// plasmavmc APIリクエストを変換
    pub async fn handle_plasmavmc_request(
        &self,
        request: PlasmavmcRequest,
    ) -> Result<ApiResponse, ApiError> {
        // plasmavmcのVM作成を新リソースモデルに変換
        let resource_request = match request {
            PlasmavmcRequest::CreateVm { name, spec } => {
                ResourceRequest {
                    resource_type: ResourceType::ComputeInstance,
                    action: ResourceAction::Create,
                    spec: ResourceSpec::Compute(ComputeInstanceSpec {
                        metadata: ResourceMetadata {
                            name,
                            ..Default::default()
                        },
                        backend: ComputeBackend::Firecracker(spec.into()),
                        resources: spec.resources,
                        ..Default::default()
                    }),
                }
            }
            // その他のリクエストタイプ...
        };
        
        self.resource_manager.submit(resource_request).await
    }
    
    /// k8shost APIリクエストを変換
    pub async fn handle_k8shost_request(
        &self,
        request: K8shostRequest,
    ) -> Result<ApiResponse, ApiError> {
        // Pod作成をComputeInstanceとして扱う
        let resource_request = match request {
            K8shostRequest::CreatePod { cluster_id, pod_spec } => {
                ResourceRequest {
                    resource_type: ResourceType::ComputeInstance,
                    action: ResourceAction::Create,
                    spec: ResourceSpec::Compute(ComputeInstanceSpec {
                        backend: ComputeBackend::KubernetesPod(KubernetesPodSpec {
                            cluster_id,
                            pod_spec: serde_json::to_vec(&pod_spec)?,
                        }),
                        ..Default::default()
                    }),
                }
            }
            // その他のリクエストタイプ...
        };
        
        self.resource_manager.submit(resource_request).await
    }
}

7. リスクと緩和策

7.1 技術的リスク

リスク 確率 影響 緩和策
移行中のサービス停止 ブルー/グリーンデプロイ、段階的ロールアウト
パフォーマンス低下 継続的ベンチマーク、プロファイリング、最適化
データ整合性の問題 分散トランザクション、イベントソーシング、検証レイヤー
複雑性増大 明確なドメイン境界、徹底したドキュメント、段階的実装
プラグイン互換性 安定したプラグインAPI、バージョニング、テストスイート
循環依存 厳格なアーキテクチャレビュー、依存関係可視化ツール

7.2 組織的リスク

リスク 確率 影響 緩和策
学習コスト ドキュメント、ワークショップ、ペアプログラミング
移行疲れ 明確なマイルストーン、小さな勝利の設定
レガシー知識の消失 知識移行文書化、オンボーディング強化

7.3 移行成功のためのチェックリスト

  • 各フェーズの包括的テストスイート
  • 本番負荷を模倣したステージング環境
  • ロールバック手順の文書化と演習
  • モニタリングとアラート体制の整備
  • インシデント対応手順の更新
  • パフォーマンス基準の定義と測定

8. まとめ

8.1 新アーキテクチャのメリット

  1. 統一されたリソースモデル: VM、コンテナ、ネットワーク、ストレージを統一的に扱える
  2. 明確な責務分離: コントロールプレーンとデータプレーンの分離により、スケーラビリティ向上
  3. プラグイン可能なエージェント: 新しいリソースタイプの追加が容易
  4. イベント駆動: 非同期処理の標準化により、システムの柔軟性向上
  5. 段階的移行: 既存システムの段階的な移行が可能
  6. 単体運用の維持: 各コンポーネントが独立して動作可能

8.2 設計の核心

graph TB
    subgraph Core_Principles [設計の核心]
        CP[Control/Data Plane<br/>Separation]
        RA[Resource Abstraction]
        ED[Event-Driven]
        SO[Standalone Operation]
        PI[Plugin Architecture]
    end
    
    CP --> RA
    RA --> ED
    ED --> SO
    SO --> PI

8.3 次のステップ

  1. 設計レビュー: 本設計案の詳細レビューと承認
  2. PoC実装: photon-common + 簡易Resource Managerのプロトタイプ
  3. チーム編成: 各コンポーネントの移行担当者決定
  4. Phase 1の開発開始: 共通基盤の構築

本ドキュメントは設計検討用です。実装前に詳細レビューを実施してください。