photoncloud-monorepo/plans/nixos-deployment-scheduler-roadmap-2026-03-20.md

11 KiB

NixOS Deployment / Scheduler Roadmap (2026-03-20)

背景

このリポジトリにはすでに次の材料がある。

  • NixOS モジュール群: 各サービスの systemd 化とテストクラスタ構成
  • deployer: bare metal/bootstrap 用の phone-home と node inventory
  • deployer-ctl: ChainFire 上の cluster desired state を apply する CLI
  • fleet-scheduler: native service の配置決定
  • node-agent: 各ノードで process/container を reconcile
  • plasmavmc / k8shost: VM と Pod の個別スケジューラ

ただし、これらがまだ 1 本の「Nix から始まるデプロイ経路」になっていない。

現状は、

  • Nix で host configuration を作る経路
  • deployer-ctl の YAML/JSON で cluster state を入れる経路
  • deployer の phone-home で node を登録する経路
  • fleet-scheduler / node-agent で native service を動かす経路

が並立していて、単一正本と責務境界がまだ弱い。

いま見えている重要な不足

1. Nix が単一正本になっていない

  • plasmacloud-cluster.nix / nix-nos / deployer-ctlClusterStateSpec が並立している
  • static topology をどこで持つかが定まっていない
  • node class / pool / enrollment rule / service schedule が Nix から一気通貫で生成されていない

2. bootstrap はあるが「NixOS を適用する agent」がない

  • deployernix_profile を返せる
  • しかし bootstrap ISO は node-config.jsonhostname / ip しか実質使っていない
  • node-agent は process/container 用であり、NixOS generation を apply しない

つまり、NixOS deploymentruntime scheduling が別々で、間をつなぐ node-side reconciler が存在しない。

3. ISO / netboot が generic bootstrap になり切っていない

  • ISO は node01|node02|node03nix/nodes/vm-cluster/$NODE_ID に寄っている
  • real bare metal 用の node class / profile / disk layout 選択器としてはまだ固定的
  • cloud-init endpoint はあるが、本流はまだ「Nix native bootstrap API」ではない

4. first-boot-automation は設計途中で本流に乗っていない

  • モジュールはあるが実利用配線が薄い
  • ChainFire / FlareDB / IAM bootstrap の責務が中途半端
  • 現状の main path は initialPeers と固定 node 定義で成立しており、ここは未整理

5. scheduler の層分離がまだ曖昧

  • fleet-scheduler: native service 配置
  • plasmavmc: VM 配置
  • k8shost: Pod 配置

この 3 つは全部「scheduler」だが、対象が違う。 それぞれの責務を意図的に分離しないと、NixOS 配備責務まで混ざる。

6. MaaS 代替としては inventory / commissioning がまだ弱い

  • machine-id と enrollment rule はある
  • しかし hardware facts, NIC facts, disk facts, BMC/Redfish, power cycle, reprovision, rescue の層は未整備

MaaS を本当に置き換えるなら、少なくとも commission/inventory/reinstall/power の最小セットが必要。

7. CI が bootstrap 経路の閉じ方を保証していない

  • CI は主に build / fmt / clippy / unit test
  • deployer + fleet-scheduler + node-agent + test-cluster の end-to-end は publishable gate になっていない

目標アーキテクチャ

原則

Nix を static desired state の単一正本にする。
動的な reconcile は PhotonCloud の各 agent / control plane に任せる。

分け方は以下。

1. Static layer: Nix

ここで定義するもの:

  • cluster / datacenter / rack / VLAN / BGP / IP pool
  • node class / pool / hardware policy
  • bootstrap seed set
  • disk layout policy
  • host profile
  • native service の desired policy
  • install image / bootstrap image の生成

Terraform の static な部分はここで置き換える。

2. Bootstrap layer: deployer

ここでやること:

  • node discovery
  • enrollment rule による class/pool/profile 決定
  • machine-id/MAC/DMI 等と node-id の束縛
  • install-time secrets / SSH host key / TLS 発行
  • install plan の返却

cloud-init / MaaS の bootstrap 部分をここで置き換える。

3. Node system reconcile layer: 新しい nix-agent 相当

ここでやること:

  • desired NixOS generation / flake attr / closure を受け取る
  • closure を取得
  • switch-to-configuration を実行
  • activation 成功/失敗を report
  • 世代 rollback と health gating

ここがない限り、NixOS デプロイは phone-home 後に止まる。

これは既存 node-agent の責務とは別物なので、最初は別 agent に分ける方が安全。

4. Native runtime layer: fleet-scheduler + node-agent

ここでやること:

  • stateless / movable な native service を worker pool 上に配置
  • process/container の desired state を ChainFire に書く
  • node-agent が実行と health を担う

Kubernetes Deployment/DaemonSet/Service のうち、PhotonCloud 自前 native service 用の部分をここで置き換える。

5. Tenant workload layer: plasmavmc / k8shost

ここは別 scheduler のままでよい。

  • VM は plasmavmc
  • Pod は k8shost

これらは NixOS host deployment とは分離して扱う。

やるべきこと

Phase 0: 単一正本を決める

最優先はここ。

  1. Nix を cluster source of truth に固定する
  2. deployer-ctl の YAML/JSON は hand-written ではなく Nix から生成する
  3. plasmacloud-clusternix-nos の重複生成ロジックを統一する

推奨:

  • nix/lib/cluster-schema.nix を作る
  • そこから次を生成する
    • nixosConfigurations.<node>
    • bootstrap 用 install plan
    • ClusterStateSpec 相当の JSON
    • test-cluster 用 topology

Phase 1: generic bootstrap を完成させる

  1. ISO / netboot を node 固定実装から profile/class ベースへ変更する
  2. deployer の返却値を node-config ではなく install-plan に寄せる
  3. install-plan には最低限以下を含める
    • node id
    • hostname
    • primary IP / network facts
    • disk layout ref
    • flake attr or system profile ref
    • SSH host key / TLS / bootstrap token
  4. ISO 側は nix_profile を実際に使って install target を決める
  5. disko 参照も node 固定 path ではなく profile/class から生成する

この段階で、cloud-init endpoint は compatibility として残してもよいが、本流ではなくすべき。

Phase 2: NixOS apply agent を入れる

  1. node-agent とは別に nix-agent を追加する
  2. responsibilities:
    • desired generation の取得
    • closure prefetch
    • activation
    • success/failure/report
    • rollback
  3. state model を ChainFire に持つ
    • nodes/<id>/desired-system
    • nodes/<id>/observed-system
    • deployments/<generation-id>
  4. health gate を入れる
    • reboot required
    • activation timeout
    • rollback on failed health check

これで初めて「Terraform なしで host rollout する基盤」になる。

Phase 3: native service scheduling を Nix と接続する

  1. ServiceSpec / PlacementPolicy を Nix から生成する
  2. deployer-ctl apply を human CLI ではなく generator/exporter の受け口にする
  3. fleet-scheduler は以下だけに責務を限定する
    • node selection
    • rollout budget
    • failover
    • publication trigger
  4. node-agent は以下だけに責務を限定する
    • process/container reconcile
    • health reporting
    • observed state update

重要:

  • ChainFire
  • FlareDB
  • IAM bootstrap
  • Deployer 自体
  • Scheduler 自体

のような基盤コアは、最初は scheduler 対象にせず NixOS 固定配置のままにする方がよい。
いきなり全部 movable service にすると bootstrap が壊れやすい。

Phase 4: inventory / MaaS 代替を広げる

  1. phone-home payload に hardware facts を追加する
    • CPU
    • memory
    • disks
    • NICs
    • virtualization capability
    • serial / DMI
  2. enrollment rule を machine-id 依存から広げる
    • MAC
    • DMI
    • hardware traits
    • rack / TOR port metadata
  3. node lifecycle を増やす
    • discovered
    • commissioned
    • install-pending
    • installing
    • active
    • draining
    • reprovisioning
    • rescue
  4. 余力があれば Redfish/IPMI を追加する
    • power on/off
    • reboot
    • virtual media

ここまで来ると MaaS の最小代替になる。

Phase 5: validation path を本流化する

  1. nix/test-cluster に bootstrap end-to-end を追加する
    • generic ISO/netboot
    • deployer enrollment
    • install-plan
    • install
    • first boot
    • nix-agent apply
  2. fleet-scheduler native runtime flow を CI gate に入れる
  3. node loss / reboot / reprovision / rollback の試験を追加する

実装優先順位

P0

  • Nix を single source of truth に固定
  • nix_profile を実際の install/apply 経路に接続
  • generic install-plan を定義
  • node 固定 ISO install path を撤廃
  • nix-agent の最小版を作る

P1

  • Nix -> ClusterStateSpec generator
  • fleet-schedulernode-agent の Nix-generated service spec 化
  • hardware inventory / enrollment 強化
  • bootstrap E2E を nix/test-cluster に組み込み

P2

  • Redfish/IPMI
  • reprovision / rescue
  • publication と host rollout の連携
  • drain / cordon / maintenance window

このリポジトリに対する具体的な backlog

  1. nix_profile を受け取って実際に install target を決める bootstrap API と ISO 処理を作る
  2. nix/nodes/vm-cluster/node01 のような node 固定構成を、class/profile 生成へ寄せる
  3. deployer-ctl 用の YAML を手書きせず、Nix から JSON export する generator を追加する
  4. first-boot-automation は使うなら bootstrap API 契約に合わせて作り直す。使わないなら一旦凍結する
  5. node-agent とは別に nix-agent crate と NixOS module を追加する
  6. deployer に hardware inventory と install state report を足す
  7. nix/test-cluster に bare-metal-like bootstrap scenario を追加する
  8. CI で deployer/scripts/verify-deployer-bootstrap-e2e.shverify-fleet-scheduler-e2e.sh 相当を gate に入れる

結論

このプロジェクトで不足しているのは、scheduler 単体ではない。
足りていないのは次の 1 本の経路である。

Nix cluster declaration -> bootstrap/install plan generation -> deployer enrollment -> NixOS installation -> node-side NixOS reconcile -> native service scheduling -> runtime health/rollback

いまは各部品はあるが、1 本の pipeline になっていない。
最優先でやるべきは、Nix を単一正本に固定し、その宣言から

  • host install
  • host rollout
  • native service scheduling

の 3 つを生成・reconcile できるようにすること。