photoncloud-monorepo/docs/nixos-deployment-challenges.md

448 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# NixOSデプロイメントの課題と改善案
## 概要
このドキュメントは、PhotonCloudプロジェクトにおけるNixOSベースのベアメタルデプロイメントに関する現状分析、課題、および改善案をまとめたものです。
## 目次
1. [現状の実装状況](#現状の実装状況)
2. [課題の分析](#課題の分析)
3. [他のシステムとの比較](#他のシステムとの比較)
4. [スケーリングの課題](#スケーリングの課題)
5. [改善案](#改善案)
6. [優先度とロードマップ](#優先度とロードマップ)
---
## 現状の実装状況
### 実装済みの機能
#### A. Netboot → nixos-anywhere でのインストール経路
- **netbootイメージ**: `nix/images/*``baremetal/image-builder/build-images.sh` で生成可能
- **PXEサーバー**: `chainfire/baremetal/pxe-server/assets` へのコピーまで想定済み
- **VMクラスタ検証**: `baremetal/vm-cluster/` にスクリプトが揃っている
- **デプロイフロー**: PXE起動 → SSH接続 → disko + nixos-install=nixos-anywhereの流れが確立
**評価**: deploy-rs/colmena系よりベアメタル寄りの王道路線として成立している。
**ただし**: 速度は**バイナリキャッシュの有無**と**再ビルドの頻度**に大きく依存する。
#### B. Bootstrap ISOphone-home → 自動パーティション → nixos-install経路
- **ISO生成**: `nix/iso/plasmacloud-iso.nix` に実装済み
- **自動化フロー**:
- Deployerへの `POST /api/v1/phone-home`
- `disko` 実行
- `nixos-install --flake ...`
- **Deployer API**: `deployer/` にHTTP API実装あり`/api/v1/phone-home`
**評価**: 形は整っているが、**本番でのゼロタッチ運用**には未成熟。
#### C. 構成管理NixOSモジュール + クラスタ設定生成)
- **サービスモジュール**: `nix/modules/` に各サービスがモジュール化済み
- **cluster-config.json生成**: `plasmacloud.cluster``nix/modules/plasmacloud-cluster.nix`)で `/etc/nixos/secrets/cluster-config.json` を生成
### 実装済み機能 ✅
#### (1) トポロジ→cluster-config→first-bootの一貫したルート
-`plasmacloud-cluster.nix` でクラスタトポロジから `cluster-config.json` を自動生成
-`environment.etc."nixos/secrets/cluster-config.json"` でファイルが自動配置される
-`first-boot-automation.nix` がcluster-config.jsonを読み込んでサービス間の接続を自動化
#### (2) Deployerの実運用要件
- ✅ SSH host key 生成: `LocalStorage.get_or_generate_ssh_host_key()` で ED25519 鍵を生成・永続化
- ✅ TLS証明書配布: `LocalStorage.get_or_generate_tls_cert()` で自己署名証明書を生成・永続化
- ✅ machine-id → node割当: pre_register API + in-memory fallback 実装済み
- ✅ ChainFire非依存: `local_state_path` がデフォルトで設定され、LocalStorage を優先使用
#### (3) netbootイメージの最適化
-`netboot-base.nix`: 超軽量インストーラ専用イメージ(サービスバイナリなし)
-`netboot-worker.nix`: netboot-base.nix をベースに使用
-`netboot-control-plane.nix`: netboot-base.nix をベースに使用
- ✅ サービスバイナリは nixos-anywhere でインストール時に追加netboot には含めない)
### 残りの改善点
#### ISOの最適化Phase 2以降
- ISOは `isoImage.contents = [ { source = ../../.; ... } ]` で **リポジトリ丸ごとISOに埋め込み**になっており、変更のたびに再パック&評価対象が増えやすい
- 将来的には必要なファイルのみを含めるように最適化する
---
## 課題の分析
### 「途方もない時間がかかる」問題の根本原因
#### 最大のボトルネック: Rustパッケージの `src = ./.` が重すぎる
`flake.nix` のRustビルドは `src = repoSrc = ./.;` になっており、これにより:
- `docs/``baremetal/` など **ビルドに無関係な変更でも全Rustパッケージが再ビルド**され得る
- さらに最悪なのは、`deployer/target/` のような **巨大で変動する成果物ディレクトリが混入している場合、毎回ソースハッシュが変わってキャッシュが死ぬ**こと
- 結果:毎回「初回ビルド」に近い時間が発生
**ここが直るだけで「体感の遅さ」が一段落ちる可能性が高い。**
#### その他のボトルネック
1. **netbootイメージが肥大化**
- サービスバイナリや重いツールをnetbootに含めている
- initrd配布もビルドも遅くなる
2. **ISOにリポジトリ全体を埋め込み**
- 変更のたびにISO再ビルドが必要
- 評価対象が増える
**注意**:
- **リモートバイナリキャッシュCachix/Atticは後回し**Phase 3で実装
- Deployer[Bootstrapper]では**ローカルNixストアのキャッシュ**を活用する前提
---
## 他のシステムとの比較
### cloud-init との比較
**cloud-initの得意領域**: 既に焼いたOSイメージ主にクラウドVMに対して、初回起動時にユーザデータ/メタデータで「最後のひと押し」をする
**このプロジェクトの得意領域**: そもそもOSとサービス構成をNixで宣言し、**同一の入力から同一のシステム**を作る(= cloud-initより上流
**評価**:
- **置き換え関係というより補完**。cloud-initは「既存OSに後付けで整える」方向、NixOSは「最初からそれがOSの本体」。
- 速度面は、**バイナリキャッシュがあるなら** NixOSでも十分実用レンジに寄るが、**キャッシュ無しだとcloud-init既成イメージ前提の圧勝**になりがち。
### Ansible との比較
**Ansibleの強み**: 既存の多様なOSに対して、成熟したエコシステムで「変更差分を適用」しやすい
**NixOSの強み**: 変更適用が「宣言→生成→スイッチ」で、**ドリフト/雪片化を構造的に起こしにくい**
**評価**:
- **同じ「構成管理」領域ではかなり戦える**。特にクラスタ基盤あなたのプロジェクトのコアみたいに「全ード同質で、更新頻度も高く、止められない」世界はNixが刺さりやすい。
- ただし現状だと、Ansibleが当たり前に持っている **実運用の周辺機能**(インベントリ、秘密情報配布の標準手、実行ログ/監査、段階ロールアウト、失敗時の自動復旧/再試行設計が、Nix側では自作領域になりがち。ここをDeployerで埋める設計。
### OpenStackIronic等のベアメタルとの比較
**Ironicの強みDay0の王者**:
- IPMI/Redfish等のBMCで電源制御
- PXE/iPXE、インスペクションハードウェア自動検出
- クリーニングディスク消去、RAID/BIOS設定
- 大規模・マルチテナント前提の運用(権限、クオータ、ネットワーク統合)
**このプロジェクトの現状**:
- PXE/Netboot・ISO・disko・nixos-install・first-boot は揃っている
- でも **BMC連携/インスペクション/クリーニング/多数ノードの状態機械**は薄いDeployerがその芽
**評価**:
- **Ironicの「同じ土俵」ではまだ厳しい**(特に「台数が増えた時に壊れない運用」)。
- 逆に言うと、Ironicが重い/過剰な環境単一DC・少〜中規模・同一HW寄り・「クラウド基盤自体をNixOSでガチガチに固めたい」では、**NixOS方式は運用コストと一貫性で勝ち筋がある**。
**実務的な勝ち筋**:
- **小〜中規模はNixOS主導で十分戦える**(ただしキャッシュ導入と、ビルド入力の安定化が必須)。
- **大規模/多拠点/多機種/マルチテナントのDay0は、Ironic相当の機能をどこかで用意する必要がある**。
- 現実解は「**Day0はIronicや既存のプロビジョナに寄せて、Day1/Day2をNixOSで統一**」が強い。
---
## スケーリングの課題
### 10,000台規模での問題点
#### 1. Deployerサーバーが単一インスタンス前提
- `axum::serve(listener, app)` で単一HTTPサーバーとして動作
- 10,000台が同時にPhone Homeすると、**単一プロセスが全リクエストを処理**する必要がある
- CPU/メモリ/ネットワークI/Oがボトルネック
#### 2. 状態管理はChainFireで分散可能だが、Deployer側の調整がない
- ChainFireはRaftベースで分散可能
- しかし、**Deployerインスタンス間の調整**(リーダー選出、ジョブ分散、ロック)がない
- 複数Deployerを起動しても、**同じジョブを重複実行**する可能性
#### 3. デプロイジョブの管理がない
- Phone Homeはあるが、**「nixos-anywhereを実行する」ジョブの管理**がない
- 10,000台を順次デプロイする場合、**キューイング/並列制御/リトライ**が必要
### 他のシステムとの比較(スケーリング設計)
#### OpenStack Ironic
```
API層: 複数インスタンス + ロードバランサー
ワーカー層: 複数conductorで並列処理
状態管理: PostgreSQL共有DB
ジョブキュー: RabbitMQ分散キュー
```
#### Ansible Tower
```
Web層: 複数インスタンス
ワーカー層: Celery workersスケーラブル
状態管理: PostgreSQL
ジョブキュー: Redis
```
#### Kubernetes Controller
```
コントローラー層: 複数インスタンス + Leader Election
状態管理: etcd
並列処理: ワーカーPodで分散
```
### 10,000台規模での性能見積もり
**現状(単一インスタンス)**:
- Phone Home: **10,000リクエスト ÷ 1サーバー = 10,000リクエスト/サーバー**
- デプロイ: **順次実行 = 10,000台 ÷ 1ワーカー = 非常に遅い**
**改善後API層10台 + ワーカー100台**:
- Phone Home: **10,000リクエスト ÷ 10サーバー = 1,000リクエスト/サーバー**10倍高速化
- デプロイ: **10,000台 ÷ 100ワーカー = 100台/ワーカー**(並列実行で大幅短縮)
**例**: 1台あたり10分かかる場合
- 現状: **10,000台 × 10分 = 100,000分約69日**
- 改善後: **100台/ワーカー × 10分 = 1,000分約17時間**
---
## 改善案
### Deployer[Bootstrapper]の位置づけ
現状のDeployer実装は **Deployer[Bootstrapper]** として位置づけ、以下の前提で設計する:
- **実行環境**: 仮設マシンや手元のマシンdeploy-rsのように
- **役割**: 0→1の初期デプロイクラスタの最初の数台
- **独立性**: 他のソフトウェアChainFire、FlareDB等から**完全に独立**している必要がある
- **キャッシュ前提**: 手元/仮設マシンにはNixストアのキャッシュがあるため、リビルドは多くないはず
**将来の移行**: ある程度デプロイが進んだら、完全に自動なデプロイ環境キャッシュ実装済み、ISOはオブジェクトストレージ、スケーラブルに移行する。ただし、この完全自動デプロイ環境の実装は**他のソフトウェアが安定してから**にしたい。
### 将来リモートflake化 + バイナリキャッシュPhase 3以降
**目的**: ビルド時間を大幅に短縮(完全自動デプロイ環境用)
**実装内容**Phase 3で実装:
1. **リモートにflakeを置く**GitHub等
- **注意**: 現在のコードベースは大胆に変更される可能性があるため、GitHubへの公開は後回し
2. **バイナリキャッシュを用意**Cachix、セルフホストならattic等
3. `flake.nix``nixConfig` と、`nix/images/netboot-base.nix` / 各ノード設定に **substituters/trusted-public-keys** を入れて、netboot/ISO/インストール時のnixが自動でキャッシュを引くようにする
**効果**: nixos-anywhere の実体が「ビルド」から「ダウンロード」に変わる。
**優先度**: **Phase 3以降**完全自動デプロイ環境の実装時。Deployer[Bootstrapper]では**ローカルで動くことを優先**し、キャッシュ系は後回し。
### P0: `src = ./.` をやめ、ソースをフィルタする ✅ 実装済み
**目的**: 無関係な変更で再ビルドが発生しないようにする
**実装内容** (`flake.nix``repoSrc`):
```nix
repoSrc = pkgs.lib.cleanSourceWith {
src = ./.;
filter = path: type:
! (dropPrefix [ "docs/" "baremetal/" ".git/" ".cccc/" "result" "result-" ] ||
base == "target" ||
dropSuffix [ ".qcow2" ".img" ".iso" ".qcow" ]);
};
```
**除外されるファイル/ディレクトリ**:
-`**/target/`Cargoビルド成果物
-`docs/`, `baremetal/`Rustビルドに不要
-`.git/`, `.cccc/`, `result*`Nix成果物
-`.qcow2`, `.img`, `.iso`, `.qcow`(大きなバイナリファイル)
**効果**: ソース変更がなければNixのキャッシュが効き、再ビルドを回避。
### P1: netbootは「最小のインストーラ」に寄せる ✅ 実装済み
**目的**: netbootイメージのサイズとビルド時間を削減
**実装内容** (`nix/images/netboot-base.nix`):
-`netboot-base.nix`: 最小限のインストーラツールのみdisko, parted, curl, jq等
- ✅ サービスバイナリや仮想化ツールは含めない
- 役割netbootは「SSHで入れてnixos-anywhereできる」だけに絞る
- サービスは **インストール後のNixOS構成**で入れる方が速く・安全
**効果**: initrd配布もビルドも速くなる。
### P1: トポロジ生成とfirst-bootの接続を完成させる ✅ 実装済み
**目的**: 構成管理の運用ループを完成させる
**実装内容**:
-`plasmacloud-cluster.nix`: クラスタトポロジ定義と `cluster-config.json` の自動生成
-`first-boot-automation.nix`: cluster-config.json を読み込んでChainfire/FlareDB/IAMへの自動接続
-`environment.etc."nixos/secrets/cluster-config.json"` でファイル配置
**効果**: 「構成管理」が「運用の自動化」に直結する。
### P2: ISOルートは「本番のゼロタッチ」に必要な要件を埋めるPhase 2以降
**目的**: ISOベースの自動デプロイを本番対応にする
**実装内容**:
- ✅ Deployerの鍵・証明書生成は実装済み`LocalStorage.get_or_generate_*`
- TODO: ISO内で disko を同梱してローカル実行に寄せる(現状はネットワーク依存)
### P1: Deployer[Bootstrapper]の独立性確保 ✅ 実装済み
**目的**: 他のソフトウェアChainFire、FlareDB等に依存しない独立したデプロイツールにする
**実装内容** (`deployer/crates/deployer-server/`):
-`LocalStorage`: ローカルファイルベースのストレージChainFire不要
-`config.local_state_path`: デフォルトで `/var/lib/deployer/state` に設定
-`state.init_storage()`: `local_state_path` があれば LocalStorage を優先使用
- ✅ Phone Home API: 簡易HTTPサーバーとして動作ChainFire不要
- ✅ SSH host key / TLS証明書: LocalStorage で永続化
**効果**: ChainFire等が動いていなくても、Deployer[Bootstrapper]だけでデプロイが可能。
**将来**: Phase 3 で ChainFire との統合を実装(大規模デプロイ用)。
### (将来)完全自動デプロイ環境の設計
**目的**: 大規模デプロイ10,000台規模に対応した、完全に自動化されたデプロイ環境
**実装内容**Phase 3で実装:
- **API層のStateless化**: Phone Homeリクエストを複数APIサーバーで分散処理
- **ワーカー層の追加**: デプロイジョブを並列実行ChainFireベースのジョブキュー
- **ISOのオブジェクトストレージ配布**: LightningStor等にISOを保存し、高速配布
- **バイナリキャッシュの完全実装**: すべてのビルド成果物をキャッシュ
**効果**: マシンをいくら増やしても高速でデプロイできる。
**前提条件**: 他のソフトウェアChainFire、FlareDB、LightningStor等が安定してから実装する。
---
## 優先度とロードマップ
### Phase 1: Deployer[Bootstrapper]の改善 ✅ 完了
**目標**: 0→1の初期デプロイを高速化・安定化**ローカルで動くことを優先**
1.**`src` フィルタリング**`target/``docs/` を除外)
- `flake.nix``repoSrc` で実装済み
- ソース変更がなければ、Nixのキャッシュが効き、Cargoの再ビルドも避けられる
2.**Deployer[Bootstrapper]の独立性確保**
- `LocalStorage` でChainFire非依存
- `local_state_path` がデフォルトで設定
3.**netbootイメージの最小化**(サービスバイナリを除外)
- `netboot-base.nix` を最適化
- `netboot-worker.nix`, `netboot-control-plane.nix` が netboot-base をベースに使用
4.**トポロジ→first-boot接続**
- `plasmacloud-cluster.nix` でクラスタトポロジ定義と cluster-config.json を自動生成
- `first-boot-automation.nix` でサービス間の自動接続
5.**SSH/TLS鍵生成**
- `phone_home.rs` で ED25519 鍵と自己署名証明書を生成・永続化
**達成効果**:
- Deployer[Bootstrapper]が他のソフトウェアから独立し、安定して動作
- ソース変更がなければ、ビルド時間が大幅に短縮
- Cachix/Attic連携なしでもローカルで動作
**実行環境**: 手元/仮設マシンNixストアのキャッシュがある前提
### Phase 2: 他のソフトウェアの安定化(数ヶ月)
**目標**: ChainFire、FlareDB、IAM等のコアサービスの安定化
1. **コアサービスの機能完成**
2. **クラスタ運用の安定化**
3. **監視・ログ・バックアップ等の運用基盤の整備**
**期待効果**: 完全自動デプロイ環境を構築する基盤が整う
### Phase 3: 完全自動デプロイ環境の実装将来、Phase 2完了後
**目標**: 大規模デプロイ10,000台規模に対応した、完全に自動化されたデプロイ環境
1. **リモートflake化** + **バイナリキャッシュ導入**Cachix/attic
- GitHub等への公開コードベースが安定してから
- Cachix/Attic連携によるバイナリキャッシュ
2. **API層のStateless化** + **ワーカー層の追加**
3. **ジョブキューの実装**ChainFireベース
4. **ISOのオブジェクトストレージ配布**LightningStor等
5. **Deployerの鍵・証明書・インベントリ管理の実装**
**期待効果**:
- マシンをいくら増やしても高速でデプロイできる
- 完全に自動化されたゼロタッチデプロイが可能
**前提条件**:
- Phase 2他のソフトウェアの安定化が完了していること
- コードベースが安定し、GitHub等への公開が可能になったこと
---
## まとめ
### 現状の評価
このプロジェクトは、**NixOSベースのベアメタル配備に必要な部品がすべて揃い、Phase 1が完了**している:
#### ✅ Phase 1 完了項目
1. **Deployer[Bootstrapper]の独立性**: LocalStorage でChainFire非依存
2. **キャッシュ効率化**: `repoSrc` フィルタリングで不要ファイルを除外
3. **netboot最小化**: `netboot-base.nix` でインストーラ専用イメージ
4. **トポロジ→first-boot接続**: cluster-config.json 自動生成
5. **SSH/TLS鍵生成**: ED25519 鍵と自己署名証明書の生成・永続化
#### 残りの課題
1. **完全自動デプロイ環境の未実装**: 大規模デプロイに対応するための基盤Phase 3で実装
### 段階的なアプローチ
**Phase 1 ✅ 完了**: Deployer[Bootstrapper]の改善
- 0→1の初期デプロイを高速化・安定化
- 他のソフトウェアから独立
- 手元/仮設マシンで実行可能
**Phase 2現在**: 他のソフトウェアの安定化
- ChainFire、FlareDB、IAM等のコアサービスの安定化
- クラスタ運用の確立
**Phase 3将来**: 完全自動デプロイ環境の実装
- 大規模デプロイ10,000台規模に対応
- 完全に自動化されたゼロタッチデプロイ
- Phase 2完了後に実装
### 達成済みの成功条件
1.**Deployer[Bootstrapper]の独立性**: 他のソフトウェアが動いていなくても、デプロイが可能
2.**ローカルでの動作優先**: Cachix/Attic連携なしでも、ローカルNixストアのキャッシュで動作
3.**キャッシュの効率化**: `src` フィルタリングで、ソース変更がなければNixのキャッシュが効く
4.**トポロジ→first-boot接続**: plasmacloud-cluster.nix からの設定生成が機能
5.**SSH/TLS鍵の永続化**: LocalStorage で鍵を永続化
### 次のステップ
1. ~~Phase 1を最優先で実装~~**完了**
2. **Phase 2で他のソフトウェアを安定化**(基盤の確立)
3. **Phase 3で完全自動デプロイ環境を実装**(大規模対応)
- コードベースが安定してから、リモートflake化とバイナリキャッシュを実装
**Phase 1が完了し、0→1のデプロイが可能になった。次はPhase 2でコアサービスの安定化を進める。**
---
## 参考資料
- [NixOS Netboot](https://nixos.wiki/wiki/Netboot)
- [nixos-anywhere](https://github.com/nix-community/nixos-anywhere)
- [disko](https://github.com/nix-community/disko)
- [Cachix](https://www.cachix.org/)
- [attic](https://github.com/zhaofengli/attic)