node-rotation-controller
Karpenter 管理ノードを、メンテナンスウィンドウ内で graceful に先回りローテーションする Kubernetes コントローラー。Karpenter の forceful な expireAfter が発火する前に、make-before-break で置換する。
EKS Auto Mode および Karpenter v1+ 環境向け。
English: docs/getting-started
クイックスタート
前提条件
- Karpenter v1+ がインストール済みのクラスタ(
karpenter.sh/v1CRD が提供されている) expireAfterが設定されたNodePoolが 1 つ以上存在- Helm 3.12+
インストール
helm install node-rotation-controller \
oci://ghcr.io/akashisn/charts/node-rotation-controller \
--namespace node-rotation-system --create-namespace \
--set-json 'rotationPolicies=[{
"spec": {
"nodePoolSelector": {"matchLabels": {"workload": "api"}},
"maintenanceWindows": [{
"timezone": "Asia/Tokyo",
"days": ["Wed", "Sat"],
"start": "02:00",
"end": "06:00"
}]
}
}]'これにより、コントローラー(leader election 付き 2 レプリカ)、RBAC、RotationPolicy CRD、surge placeholder 用の負優先度 PriorityClass がインストールされる。
workload: apiは対象 NodePool が持つラベルに合わせる。maintenanceWindowsは運用に合わせて調整する。
動作確認
# コントローラーが起動していることを確認
kubectl -n node-rotation-system get pods
# NodePool に対する導出スケジュールを確認
kubectl get rotationpolicy -o wide
# メトリクスの確認(Prometheus がある場合)
kubectl port-forward -n node-rotation-system svc/node-rotation-controller-metrics 8080:8080
curl -s localhost:8080/metrics | grep noderotation_シミュレーターで事前確認
本番適用の前に、ポリシーシミュレーターで各ノードがいつローテーションされるか可視化できる。
仕組み
主要な特性:
- Make-before-break — 旧ノードの drain 前に代替ノードが
Readyになる - Karpenter を迂回しない — コントローラーは
NodeClaimを削除し、Karpenter の termination controller が Eviction API で drain する(PDB が適用される) - ウィンドウ有界 — ローテーション開始はウィンドウ内のみ。進行中のローテーションはウィンドウを跨いでも完遂する
- 安全なフォールバック — コントローラーが不在でも
expireAfterは通常通り発火する(コントローラーなしの場合より悪くならない)
なぜ必要か
Karpenter はノードの disruption を 2 種類に分類している:
| 分類 | 例 | Disruption Budgets | 代替の事前起動 |
|---|---|---|---|
| Graceful | Drift, Consolidation | 適用される | する(make-before-break) |
| Forceful | Expiration, Spot Interruption | 適用されない | しない |
Expiration が意図的に Forceful なのは、セキュリティパッチが誤設定された PDB でブロックされるのを防ぐためである(公式 forceful-expiration design)。EKS Auto Mode はさらに 21 日のノード寿命 hard cap を強制する。
帰結: ノードは予測不能なタイミングで 必ず Force drain される。Karpenter は drain 開始の 後から 代替を起動するため、ピーク営業時間帯と衝突しうる。本コントローラーはこのローテーションをメンテナンスウィンドウ内に前倒しし、make-before-break で実行する。
スコープ外
- Karpenter Consolidation / Drift / Disruption Budgets の置き換え — 共存する
- Spot 中断 — AWS Node Termination Handler を使う
- OS パッチ起因の再起動 — kured を使う
- アプリケーション側 warm-up —
readinessProbe/readinessGate/ ALB slow start の領分
設定
chart は rotationPolicies のエントリごとに 1 つの RotationPolicy をレンダリングする。最小構成:
rotationPolicies:
- spec:
nodePoolSelector:
matchLabels:
workload: api
maintenanceWindows:
- timezone: Asia/Tokyo
days: [Wed, Sat]
start: "02:00"
end: "06:00"
# minRotationChances: 2 # K — 失効前に保証するウィンドウ回数(既定 2)
# surge:
# readyTimeout: 15m # 代替ノードの Ready 待ち上限
# cooldownAfter: 10m # 連続ローテーション間の休止
# forcefulFallback:
# enabled: false # opt-in: graceful surge が間に合わない場合に surge-less で回す- NodePool ごとのポリシー。 エントリを追加すれば NodePool ごとに別のウィンドウや surge 設定を与えられる。
- 自前のポリシー。
rotationPolicies: []にして独自のRotationPolicyオブジェクトを適用可能。examples/にすぐ流用できるマニフェストがある。 - 完全なスキーマ。 仕様 §5.4 と
values.yamlを参照。
互換性
互換性の契約は 安定版 karpenter.sh/v1 CRD サーフェス であり、特定の Karpenter マイナーではない。
- ランタイム対象: EKS Auto Mode、および任意の Karpenter v1+ クラスタ
- クラウド API 不使用: Kubernetes API オブジェクト(
NodeClaim/NodePool、Node、Pod)のみで動作 - Fail-fast プリフライト:
karpenter.sh/v1が提供されない・読み取れない場合は即座に終了
必須フィールドの一覧は互換性ポリシーを参照。
プロジェクト状況
Pre-1.0 — CRD スキーマ(v1alpha1)と設定サーフェスは minor リリース間で変わりうる。
コアの surge パス、forceful fallback、earliest-deadline 順序付け、全ランタイム安全性は実 EKS Auto Mode クラスタで E2E 検証済み(12 時間 tight-race soak 含む)。v1.0 に向けて残る項目は、同一 AZ の実容量枯渇(ICE)によるロールバックのみ。ロードマップと検証済み前提を参照。
プロジェクト構成
├── docs/specification/ 仕様書(英語)
├── docs/ja/specification/ 日本語訳
├── docs/runbook.md 運用ランブック
├── charts/ Helm chart
├── examples/ すぐ流用できる RotationPolicy マニフェスト
├── cmd/ コントローラーエントリポイント
└── internal/ Reconciler、ステートマシン、surge、window、policy、metrics開発
aqua と make が必要。全ツールは aqua.yaml でバージョン固定。
| コマンド | 用途 |
|---|---|
make build | マネージャーバイナリをビルド |
make test | ユニットテスト + envtest スモークテスト |
make lint | golangci-lint |
make helm-lint | Helm chart の lint とレンダリング |
make docker-build | コンテナイメージのビルド |
開発ワークフローは CONTRIBUTING.md を参照。
参加するには
本プロジェクトは pre-1.0 で活発に開発中。設計へのフィードバックも実装の貢献も、GitHub の Issue と PR で歓迎する。
開発ワークフローは CONTRIBUTING.md、コミュニティ規範は CODE_OF_CONDUCT.md を参照。
ライセンス
Apache 2.0 — LICENSE