## ベアメタル向けサービスメッシュ移行計画 本ドキュメントでは、既存の PhotonCloud サービス群を、 Deployer/NodeAgent+mTLS Agent ベースのサービスメッシュ風アーキテクチャに 段階的に移行するためのマイルストーンを定義する。 ### 1. 現状整理フェーズ(完了済み前提) - `baremetal/first-boot`: - 役割: 初回ブート時のクラスタ join・基本サービス起動。 - 常駐ではなく oneshot 系 systemd unit 群。 - `deployer/`: - 役割: Phone Home によるノード登録と最低限の Node/Config 管理。 - まだ常駐型 NodeAgent や ServiceInstance Reconcile は未実装。 - mTLS: - 各サービスごとに ad-hoc な TLS/mTLS 設定が存在。 - dev ではしばしば平文/`-k` での接続。 ### 2. フェーズ 1: Chainfire モデルと Deployer 拡張 **目的**: Chainfire をクラスタ状態のソース・オブ・トゥルースにする土台を作る。 - **M1-1**: `specifications/deployer/README.md` に定義した `Cluster / Node / Service / ServiceInstance / MTLSPolicy` モデルを Chainfire 上に作成。 - PoC 用に `photoncloud-ctl` 的な小さな CLI で CRUD を実装。 - **M1-2**: `deployer-server` が `NodeInfo` を Chainfire にも書き出すように拡張。 - 既存のローカルストレージ(ファイル or メモリ)は残しつつ、 Chainfire を **optional backend** として追加。 - **M1-3**: 管理 API に「サービス配置」を表すエンドポイントを追加。 - 例: `/api/v1/admin/services/{service}/instances` で、 Node とインスタンス数を指定できるようにし、内部で ServiceInstance を生成。 ### 3. フェーズ 2: NodeAgent(常駐型 Reconciler)の導入 **目的**: 各ノードで Desired State → Observed State の Reconcile を開始する。 - **M2-1**: `plasmacloud-reconciler` を NodeAgent として再定義/拡張。 - `--node-id` と `--chainfire-endpoint` を引数に取り、無限ループで動作。 - **M2-2**: NodeAgent が自ノードの `Node` と `ServiceInstance` を watch し、 ログ出力のみ行う「read-only モード」を実装。 - まだ systemd 操作やプロセス起動はしない。 - **M2-3**: systemd 統合(ベアメタルノード側)。 - NixOS モジュールで `services.node-agent.enable = true;` を追加。 - 既存 first-boot の後に NodeAgent を常駐させる。 ### 4. フェーズ 3: サービスプロセス管理の Reconcile **目的**: NodeAgent が実際にサービスプロセスを起動/停止できるようにする。 - **M3-1**: 各サービスの NixOS モジュールを見直し、 `enable = false` をデフォルトにした上で、 NodeAgent から `systemctl start/stop` で制御しやすい形に整理。 - **M3-2**: NodeAgent 内に「ServiceInstance → systemd unit 名」のマッピングを追加。 - 例: `service="chainfire" → unit="chainfire.service"` - 単純な 1:1 マッピングからスタート。 - **M3-3**: Reconcile ループにプロセス制御を追加。 - Desired にあるのに起動していなければ `systemctl start`。 - Desired にないのに起動していれば `systemctl stop`。 - **M3-4**: 起動結果/ヘルスを Chainfire にフィードバック。 - `instances/{service}/{instance_id}.state` を `ready` / `unhealthy` に更新。 ### 5. フェーズ 4: mTLS Agent の導入(プレーンプロキシ) **目的**: サービスメッシュの「形」を先に作り、まだ TLS を強制しない。 - **M4-1**: 新クレート `mtls-agent`(名称要検討)を作成。 - 最初は平文 TCP/HTTP プロキシとして実装。 - ローカル app_port ←→ mesh_port の中継のみを行う。 - **M4-2**: NodeAgent が ServiceInstance 起動時に、 mTLS Agent を隣に起動するフローを追加。 - config ファイル生成 → `systemctl start mtls-agent@{service}` など。 - **M4-3**: Chainfire 上の ServiceInstance に `mesh_port` を登録。 - 他サービスからの接続先として mesh_port を使う用意をする。 - **M4-4**: 一部サービス間通信(例: `apigateway → creditservice`)を mTLS Agent 経由に切り替える PoC。 - アプリ側は `client-common` 抽象を通じて `http://127.0.0.1:` を叩く。 ### 6. フェーズ 5: mTLS 対応とポリシー制御 **目的**: mTLS/TLS/平文を Chainfire のポリシーで切り替えられるようにする。 - **M5-1**: mTLS Agent に TLS/mTLS 機能を実装。 - dev では平文、stg/prod では mTLS をデフォルトに。 - 証明書/鍵は既存の T031 TLS 自動化の成果物を利用。 - **M5-2**: Chainfire の `MTLSPolicy` を反映するロジックを Agent に実装。 - `(source_service, target_service)` と Cluster の `environment` からモード決定。 - **M5-3**: Deployer から `MTLSPolicy` を編集できる管理 API を追加。 - 例: `/api/v1/admin/mtls/policies`。 - **M5-4**: ステージング環境で「全経路 mTLS on」を試験。 - 問題があればポリシーを `permissive` や `plain` に戻せることを確認。 ### 7. フェーズ 6: 既存 ad-hoc mTLS 実装の段階的削除 **目的**: サービスコードから mTLS 実装を徐々に削除し、Agent に集約する。 - **M6-1**: 既存の各サービスから「直接 TLS ソケットを開いているコード」を列挙。 - `grep` ベースで `rustls`, `native-tls`, `tls` 関連を洗い出し。 - **M6-2**: 重要なサービスから順に、通信経路を `client-common` 抽象経由に置き換え。 - まずは dev 環境でのみ mTLS Agent 経由にする feature flag を導入。 - **M6-3**: 本番で mTLS Agent 経由通信が安定したら、 対象サービスから ad-hoc な TLS 設定を削除。 - **M6-4**: 最終的に、サービス側は「平文 HTTP/gRPC over localhost」という前提のみを持ち、 セキュリティ/暗号化はすべて mTLS Agent に移譲。 ### 8. 段階ごとのロールバック戦略 - 各フェーズは **Chainfire のキー空間と Deployer 設定で制御** できるようにする。 - 例: NodeAgent を停止すれば、従来通り first-boot ベースの静的構成に戻せる。 - 例: `MTLSPolicy` を削除すれば、Agent は平文モードに戻る(または完全停止)。 - NodeAgent/mTLS Agent を導入するときは、必ず 「全てのノードで Agent を止めると従来構成に戻る」状態を維持したまま進める。