photoncloud-monorepo/plans/photoncloud-design-patterns-analysis.md

20 KiB
Raw Permalink Blame History

PhotonCloudシステム 設計パターン分析と改善案

1. 統合可能性マトリクス

1.1 コンポーネント間統合可能性評価

コンポーネントA コンポーネントB 統合可能性 理由 統合複雑度
fiberlb prismnet ◎ 高 両方ともネットワーク層サービス、L4/L7 LBとVPC/IPAMは補完的
fiberlb flashdns ◎ 高 DNSとLBは密接に連携、サービスディスカバリに必須
prismnet flashdns ○ 中〜高 VPC内DNS統合は自然だが、責務が異なる
chainfire flaredb △ 中 両方ともRocksDB+分散だが、Raft実装とAPIが異なる
chainfire lightningstor × KVとObject Storageは用途が大きく異なる -
flaredb lightningstor × SQL DBとObject Storageは統合困難 -
plasmavmc k8shost ○ 中 両方ともコンピュート層だが、実装技術が異なる
iam mtls-agent ◎ 高 認証・認可とmTLSはセキュリティ基盤として統合可能
apigateway fiberlb ○ 中 L7機能の重複あり、統合で一貫性向上
creditservice chainfire × 不可 ビジネスロジックとインフラストレージは分離すべき -
nightlight chainfire △ 低 メトリクスストレージとKVは統合困難 -

1.2 統合候補グループ

graph TB
    subgraph ネットワークサービス統合候補 [ネットワークサービス統合候補]
        F[fiberlb<br/>L4/L7 LB]
        P[prismnet<br/>VPC/IPAM]
        D[flashdns<br/>DNS]
    end

    subgraph ストレージサービス [ストレージサービス: 統合困難]
        C[chainfire<br/>分散KV]
        L[flaredb<br/>分散SQL]
        S[lightningstor<br/>Object Storage]
    end

    subgraph コンピュートサービス [コンピュートサービス]
        V[plasmavmc<br/>VM管理]
        K[k8shost<br/>K8sホスト]
    end

    subgraph セキュリティ基盤統合候補 [セキュリティ基盤統合候補]
        I[iam<br/>認証認可]
        M[mtls-agent<br/>mTLS]
    end

    subgraph 独立サービス [独立サービス]
        A[apigateway<br/>API GW]
        CS[creditservice<br/>課金]
        N[nightlight<br/>監視]
    end

    F <--> D
    P <--> D
    F -.->|L7ルーティング| A

2. 推奨統合案

2.1 統合案1: ネットワークサービス統合fiberlb + prismnet + flashdns

統合後名称: photonnetPhoton Network Services

統合内容

  • core: 共通ネットワーク型定義、VPC/IPAM基盤
  • lb: L4/L7ロードバランサーfiberlbの機能
  • dns: 権威DNSサーバーflashdnsの機能
  • vpc: VPCとネットワークセグメント管理prismnetの機能

利点

  1. 一貫したネットワークポリシー: VPC、LB、DNSを統一的に管理
  2. サービスディスカバリの統合: DNSレコードとLBバックエンドの自動連携
  3. 設定の一元化: ネットワーク関連設定の重複排除
  4. 相互運用性の向上: VPC内DNS、LBヘルスチェックの自動DNS更新

欠点とリスク

リスク 影響 緩和策
単一障害点の集中 各サブサービスは独立してデプロイ可能にする
開発速度の低下 クレート分割を維持し、インターフェースで疎結合に
既存APIの破壊的変更 gRPCサービスは別名で維持し、段階的に移行

実装アプローチ

photonnet/
├── Cargo.toml              # ワークスペースルート
├── crates/
│   ├── photonnet-types/    # 共通型定義
│   ├── photonnet-core/     # VPC/IPAM基盤
│   ├── photonnet-lb/       # ロードバランサー
│   ├── photonnet-dns/      # DNSサーバー
│   └── photonnet-server/   # 統合サーバー
└── proto/
    ├── vpc.proto
    ├── lb.proto
    └── dns.proto

2.2 統合案2: セキュリティ基盤統合iam + mtls-agent

統合後名称: photonauthPhoton Auth & Security

統合内容

  • authn: 認証サービスIAMのトークン発行
  • authz: 認可・ポリシー評価IAMの既存機能
  • mtls: mTLS証明書管理mtls-agentの機能
  • audit: 監査ログ統合

利点

  1. 統一セキュリティポリシー: 認証、認可、通信暗号化の一元管理
  2. ゼロトラストアーキテクチャ: サービス間通信の自動mTLS化
  3. 証明書とIDの統合: サービスIDと証明書のライフサイクル管理

リスクと緩和策

リスク 緩和策
IAMの複雑化 クレート分割を維持、オプション機能として提供
循環依存 iam-service-authクレートを共通基盤化

2.3 統合案3: ストレージサービスchainfire + flaredb- 推奨しない

判断: 統合しない

理由:

  1. 異なるRaft実装: chainfireは独自Raft、flaredbはopenraft
  2. 異なるAPIセマンティクス: KV vs SQL
  3. 異なるスケーリング特性: メタデータKVとデータSQL
  4. 統合コストが利益を上回る

代替案: 共通ストレージ基盤ライブラリの共有(後述)

2.4 統合案4: コンピュートサービスplasmavmc + k8shost- 慎重に検討

判断: 部分的統合を検討

統合可能な要素

  • リソーススケジューラ: VMとK8sのリソース要求を統合キュー
  • ネットワーク統合: 両方ともprismnet→photonnetを使用
  • ストレージ統合: 両方ともlightningstorを使用

統合しない要素

  • ハイパーバイザー層: KVMとFirecrackerは分離
  • K8sコントロールプレーン: 標準K8sを維持

3. 共通基盤設計案

3.1 photon-common ワークスペース

新しい共通基盤ライブラリ群を作成します。

photon-common/
├── Cargo.toml
├── crates/
│   ├── photon-error/       # 共通エラーハンドリング
│   ├── photon-config/      # 設定管理
│   ├── photon-grpc/        # gRPCサービス基盤
│   ├── photon-metrics/     # メトリクス共通
│   ├── photon-storage/     # ストレージ抽象化
│   └── photon-nix/         # NixOSモジュール基盤

3.2 photon-error: 共通エラーハンドリングライブラリ

// 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),
}

/// HTTP/gRPCステータスコード変換
trait HttpStatus {
    fn http_status(&self) -> u16;
    fn grpc_code(&self) -> tonic::Code;
}

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

3.3 photon-config: 共通設定管理ライブラリ

// crates/photon-config/src/lib.rs
use serde::{Deserialize, Serialize};
use std::net::SocketAddr;
use std::path::PathBuf;

/// 全サービス共通の基本設定
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BaseConfig {
    /// サービス名
    pub service_name: String,
    /// ードID
    pub node_id: String,
    /// ログレベル
    pub log_level: String,
    /// メトリクス設定
    pub metrics: MetricsConfig,
}

/// ネットワーク設定共通構造
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NetworkConfig {
    /// gRPCアドレス
    pub grpc_addr: SocketAddr,
    /// HTTP/RESTアドレス
    pub http_addr: Option<SocketAddr>,
    /// TLS設定
    pub tls: Option<TlsConfig>,
}

/// TLS設定T027パターン統一
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TlsConfig {
    pub cert_file: PathBuf,
    pub key_file: PathBuf,
    pub ca_file: Option<PathBuf>,
    #[serde(default)]
    pub require_client_cert: bool,
}

/// 設定ローダー
pub struct ConfigLoader<T: serde::de::DeserializeOwned> {
    prefix: String,
    _phantom: std::marker::PhantomData<T>,
}

impl<T: serde::de::DeserializeOwned> ConfigLoader<T> {
    pub fn new(prefix: &str) -> Self {
        Self {
            prefix: prefix.to_string(),
            _phantom: std::marker::PhantomData,
        }
    }
    
    /// config-rsベースの階層的設定読み込み
    pub fn load(&self) -> anyhow::Result<T> {
        use config::{Config, Environment, File};
        
        Config::builder()
            .add_source(File::with_name(&format!("{}", self.prefix)))
            .add_source(
                Environment::with_prefix(&self.prefix.to_uppercase())
                    .separator("__")
            )
            .build()?
            .try_deserialize()
            .map_err(Into::into)
    }
}

3.4 photon-grpc: 共通gRPCサービス基盤

// crates/photon-grpc/src/lib.rs
use tonic::transport::Server;
use tonic_health::server::health_reporter;

/// 標準的なgRPCサーバー構築ヘルパー
pub struct GrpcServerBuilder {
    service_name: String,
    config: NetworkConfig,
}

impl GrpcServerBuilder {
    pub fn new(service_name: &str, config: NetworkConfig) -> Self {
        Self {
            service_name: service_name.to_string(),
            config,
        }
    }
    
    /// ヘルスチェックサービスを追加
    pub fn with_health_check(self) -> (Self, HealthReporter) {
        let (reporter, service) = health_reporter();
        // ...
        (self, reporter)
    }
    
    /// メトリクスエンドポイントを追加
    pub fn with_metrics(self, port: u16) -> Self {
        // Prometheusエクスポーター設定
        // ...
        self
    }
    
    /// 認証インターセプターを追加
    pub fn with_auth(self, auth_service: Arc<dyn AuthInterceptor>) -> Self {
        // ...
        self
    }
    
    /// サーバーを構築
    pub async fn build(self) -> anyhow::Result<Server> {
        // ...
    }
}

/// サービス登録マクロ
#[macro_export]
macro_rules! register_service {
    ($server:expr, $service:ty, $impl:expr) => {
        $server.add_service(<$service>::new($impl))
    };
}

3.5 photon-nix: 共通NixOSモジュール基盤

# crates/photon-nix/lib/service-module.nix
{ config, lib, pkgs, ... }:

with lib;

let
  # 共通オプション定義ヘルパー
  mkPhotonService = { name, description, defaultPort, extraOptions ? {} }:
    { options, config, ... }:
    let cfg = config.services.${name};
    in {
      options.services.${name} = {
        enable = mkEnableOption "${name} service";
        
        nodeId = mkOption {
          type = types.str;
          default = config.networking.hostName;
          description = "Unique node identifier";
        };
        
        port = mkOption {
          type = types.port;
          default = defaultPort;
          description = "gRPC service port";
        };
        
        dataDir = mkOption {
          type = types.path;
          default = "/var/lib/${name}";
          description = "Data directory";
        };
        
        package = mkOption {
          type = types.package;
          default = pkgs.${name};
          description = "Package to use";
        };
        
        # 追加オプションをマージ
      } // extraOptions;
      
      config = mkIf cfg.enable {
        # 共通ユーザー設定
        users.users.${name} = {
          isSystemUser = true;
          group = name;
          home = cfg.dataDir;
        };
        users.groups.${name} = {};
        
        # 共通systemd設定
        systemd.services.${name} = {
          description = "${description}";
          wantedBy = [ "multi-user.target" ];
          after = [ "network.target" ];
          
          serviceConfig = {
            Type = "simple";
            User = name;
            Group = name;
            Restart = "on-failure";
            RestartSec = "10s";
            StateDirectory = name;
            NoNewPrivileges = true;
            PrivateTmp = true;
            ProtectSystem = "strict";
            ProtectHome = true;
            ReadWritePaths = [ cfg.dataDir ];
          };
        };
      };
    };
in {
  inherit mkPhotonService;
}

4. ワークスペース再設計案

4.1 推奨ディレクトリ構造

/home/centra/cloud/
├── Cargo.toml                    # ルートワークスペース
├── photon-common/                # 新規: 共通基盤
│   ├── Cargo.toml
│   └── crates/
│       ├── photon-error/
│       ├── photon-config/
│       ├── photon-grpc/
│       ├── photon-metrics/
│       ├── photon-storage/
│       └── photon-nix/
│
├── photonnet/                    # 統合: fiberlb + prismnet + flashdns
│   ├── Cargo.toml
│   └── crates/
│       ├── photonnet-types/
│       ├── photonnet-core/
│       ├── photonnet-lb/
│       ├── photonnet-dns/
│       └── photonnet-server/
│
├── photonauth/                   # 統合: iam + mtls-agent
│   ├── Cargo.toml
│   └── crates/
│       ├── photonauth-types/
│       ├── photonauth-authn/
│       ├── photonauth-authz/
│       ├── photonauth-mtls/
│       ├── photonauth-audit/
│       └── photonauth-server/
│
├── chainfire/                    # 既存(依存関係のみ更新)
│   └── ...
│
├── flaredb/                      # 既存(依存関係のみ更新)
│   └── ...
│
├── lightningstor/                # 既存(依存関係のみ更新)
│   └── ...
│
├── plasmavmc/                    # 既存(依存関係のみ更新)
│   └── ...
│
├── k8shost/                      # 既存(依存関係のみ更新)
│   └── ...
│
├── apigateway/                   # 既存(依存関係のみ更新)
│   └── ...
│
├── creditservice/                # 既存(依存関係のみ更新)
│   └── ...
│
├── nightlight/                   # 既存(依存関係のみ更新)
│   └── ...
│
└── nix/
    └── modules/
        ├── photon-common.nix     # 共通NixOS設定
        ├── chainfire.nix
        ├── flaredb.nix
        └── ...

4.2 ルートCargo.toml

[workspace]
resolver = "2"
members = [
    # 共通基盤
    "photon-common/crates/*",
    
    # 統合サービス
    "photonnet/crates/*",
    "photonauth/crates/*",
    
    # 独立ストレージサービス
    "chainfire/crates/*",
    "chainfire/chainfire-client",
    "flaredb/crates/*",
    "lightningstor/crates/*",
    
    # コンピュートサービス
    "plasmavmc/crates/*",
    "k8shost/crates/*",
    
    # その他サービス
    "apigateway/crates/*",
    "creditservice/crates/*",
    "creditservice/creditservice-client",
    "nightlight/crates/*",
]

[workspace.package]
version = "0.1.0"
edition = "2021"
license = "MIT OR Apache-2.0"
rust-version = "1.75"
authors = ["PhotonCloud Contributors"]
repository = "https://github.com/photoncloud/photoncloud"

[workspace.dependencies]
# Photon共通ライブラリ
photon-error = { path = "photon-common/crates/photon-error" }
photon-config = { path = "photon-common/crates/photon-config" }
photon-grpc = { path = "photon-common/crates/photon-grpc" }
photon-metrics = { path = "photon-common/crates/photon-metrics" }
photon-storage = { path = "photon-common/crates/photon-storage" }

# 統合サービス
photonnet-types = { path = "photonnet/crates/photonnet-types" }
photonnet-core = { path = "photonnet/crates/photonnet-core" }
photonauth-types = { path = "photonauth/crates/photonauth-types" }

# ストレージクライアント
chainfire-client = { path = "chainfire/chainfire-client" }
flaredb-client = { path = "flaredb/crates/flaredb-client" }

# 外部依存(統一バージョン)
tokio = { version = "1.40", features = ["full"] }
tonic = { version = "0.12", features = ["tls", "tls-roots"] }
serde = { version = "1.0", features = ["derive"] }
thiserror = "1.0"
anyhow = "1.0"
tracing = "0.1"
metrics = "0.23"

5. 移行ロードマップ

5.1 フェーズ1: 短期1-3ヶ月- 共通基盤構築

タスク 優先度 依存関係 成果物
photon-error作成 最高 なし 共通エラーライブラリ
photon-config作成 最高 photon-error 統一設定管理
photon-metrics作成 なし 統一メトリクス
chainfire移行 photon-* chainfireの共通基盤化
flaredb移行 photon-* flaredbの共通基盤化

5.2 フェーズ2: 中期3-6ヶ月- ネットワークサービス統合

タスク 優先度 依存関係 成果物
photonnet-types設計 最高 photon-* 統合型定義
fiberlb→photonnet-lb移行 photonnet-types LB機能移行
flashdns→photonnet-dns移行 photonnet-types DNS機能移行
prismnet→photonnet-core移行 photonnet-types VPC機能移行
photonnet-server統合 上記全部 統合サーバー

5.3 フェーズ3: 長期6-12ヶ月- セキュリティ統合と最適化

タスク 優先度 依存関係 成果物
photonauth設計 photon-* セキュリティ統合設計
iam→photonauth移行 photonauth設計 認証認可統合
mtls-agent統合 photonauth mTLS統合
コンポーネント間連携強化 全部 最適化

5.4 移行図

gantt
    title PhotonCloud移行ロードマップ
    dateFormat  YYYY-MM
    section Phase1: 共通基盤
    photon-error開発       :done, p1e, 2026-01, 1M
    photon-config開発      :active, p1c, after p1e, 1M
    photon-metrics開発     :p1m, after p1e, 1M
    chainfire移行          :p1cf, after p1c, 1M
    flaredb移行            :p1fd, after p1c, 1M
    
    section Phase2: ネットワーク統合
    photonnet設計          :p2d, after p1cf, 1M
    fiberlb移行            :p2f, after p2d, 2M
    flashdns移行           :p2d2, after p2d, 2M
    prismnet移行           :p2p, after p2d, 2M
    photonnet統合テスト    :p2t, after p2f, 1M
    
    section Phase3: セキュリティ統合
    photonauth設計         :p3d, after p2t, 1M
    iam移行                :p3i, after p3d, 2M
    mtls統合               :p3m, after p3d, 2M
    最終統合               :p3f, after p3m, 1M

6. リスクと緩和策

リスク 確率 影響 緩和策
移行中の回帰バグ 包括的テストスイート、段階的ロールアウト
パフォーマンス低下 ベンチマーク継続、プロファイリング
チーム学習コスト ドキュメント整備、ペアプログラミング
循環依存の発生 厳格なアーキテクチャレビュー
古いコードの技術負債 移行期間中の並行メンテナンス

7. 次のステップ

  1. 設計レビュー: 本設計案の承認を得る
  2. PoC実装: photon-errorとphoton-configのプロトタイプ
  3. 移行計画詳細化: 各フェーズの詳細タスク分解
  4. チーム編成: 各コンポーネントの移行担当者決定
  5. CI/CD更新: 新しいワークスペース構造への対応

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