Karpenter
AWSが開発したKubernetes向けの Node Autoscaler
Cluster Autoscalerの後継的ポジション
website
github
Karpenterの動き
1. K8sに「このPod動かして」と頼む
2. スケジューラが「どのNodeにも空きがない or 条件に合うNodeがない」と判断
→ Pod は Pending(保留)状態になる
3. Karpenter が Pending Pod を見つけて「このPodが要求するCPU/メモリ/ラベルを満たすEC2はこれだな」と判断
4. EC2を起動し、K8sのNodeとして登録
5. Pod がそこにスケジュールされて起動
Karpenter は kubernetes.io/hostname を含む affinity を拒否する
Karpenter のソースコード (pkg/apis/v1/labels.go) で
kubernetes.io/hostname は RestrictedLabels として明示的に定義されている。
provisioner.go の validateAffinity がこれを検知すると、その Pod は「新ノード作成のシミュレーション対象から除外」される。
理由は Karpenter の動作モデルにある:
1. Karpenter は「Pendingな Pod を見て、最適なノードを計算で決めて作る」プロビジョナー
Pod の affinity を全部読んで「こういうスペックのノードがあれば乗る」を逆算する
2. kubernetes.io/hostname は "ノードができてから決まる" ラベル
新ノードの hostname はクラウドプロバイダーが命名するので、Karpenter が事前に決められない
「hostname が X というノードを作って」と言われても応えられない
3. NotIn [失敗ノード] も意味を成さない
今作ろうとしている新ノードの hostname は失敗ノードとは別物(重複しない)ことは自明
シミュレーション的には「常に満たされる制約」だが、Karpenter は安全側に倒して 「そういう Pod は新ノード作成のトリガーにしない」 と判断
4. 内部的に hostname-placeholder のような擬似値を使うフローもあり、本物の kubernetes.io/hostname 制約と衝突するのを避けたい
要するに、「hostname ベースのスケジューリング = 既存ノードを前提とした制約」 と Karpenter は解釈していて、「新ノードを作って解決する」というKarpenterの責務とは噛み合わない、という設計思想。