Kubernetes 1.31で外部クラウドプロバイダ移行が完了した今こそ知っておきたい、クラスタブートストラップの落とし穴と対処法
背景 ― in‑tree 依存の完全排除と新たな4コンポーネント
Kubernetes 1.31 では歴史上最大のマイグレーションとして in‑tree cloud provider のコードが完全に削除 され、代わりに Cloud Controller Manager(CCM)や CSI など 4 つのサブシステム が誕生しました。この結果、既存インストーラ(kOps, Cluster API など)は CCM を独立デプロイ する追加ステップが必須となり、クラスタ初期化時の依存関係がより複雑になっています。
CCMとは何者か
CCM はかつて kube‑controller‑manager や kubelet 内にあったクラウド固有ロジックを肩代わりし、Node 初期化や LoadBalancer Service 生成などを担当 する制御プレーンコンポーネントです。特に Node Controller が重要で、kubelet が登録した Node オブジェクトへ IP アドレスやリージョン等のメタデータを付与し、初期 taint を除去してノードを Ready にします。
"卵鶏問題"とは
- kubelet は
--cloud-provider=external
付きで起動すると、Node にnode.cloudprovider.kubernetes.io/uninitialized
(NoSchedule) を自動付与 - CCM がスケジュールされて taint を外さない限り ほかの Pod は配置不可
- ところが CCM 自身が Deployment/DaemonSet として Kubernetes のスケジューラに依存 すると、taint のせいで CCM も動けず 相互待ち に陥る——これが "鶏🐔が先か卵🥚が先か" 問題です。
さらに CNI がクラウド IP を待つ場合は node.kubernetes.io/not-ready
(NoExecute) も加わり、ノードが永遠に NotReady のまま停滞する例も報告されています。
具体的な発生パターン
パターン | 典型的症状 | 原因となる taint |
---|---|---|
未初期化 taint 依存 | CCM Pod がそもそもスケジュールされず、すべてのノードが Unschedulable | node.cloudprovider.kubernetes.io/uninitialized |
NotReady 依存 | CNI が IP 不在で初期化できず、ノードが永久に NotReady | node.kubernetes.io/not-ready |
どちらも CCM が動けないことで連鎖的に CNI や他システムが起動不能に陥ります。
ベストプラクティス ― "CCM をまず動かす"ための4か条
-
hostNetwork: true
を設定
クラウド API へ直にアクセスでき、CNI 依存を解消します。 -
Deployment / DaemonSet +リーダーエレクション
高可用性を保ちつつ競合を防止しましょう。 -
制御プレーンノードにピン留め
nodeSelector
または PodAffinity でコントロールプレーン上にだけ配置し、 必要なら PodAntiAffinity でホスト分散を図ります。 -
適切な Tolerations を付与
node.cloudprovider.kubernetes.io/uninitialized
node.kubernetes.io/not-ready
-
node-role.kubernetes.io/control-plane
/master
……を NoSchedule/NoExecute で許容 して、ブートストラップ段階でも必ず実行できるようにします。
参考マニフェスト(抜粋)
spec:
hostNetwork: true
nodeSelector:
node-role.kubernetes.io/control-plane: ""
tolerations:
- key: node.cloudprovider.kubernetes.io/uninitialized
effect: NoSchedule
operator: Exists
- key: node.kubernetes.io/not-ready
effect: NoExecute
operator: Exists
replicas: 2 # Leader election 有効を忘れずに
Tip: PodAutoscaler 連動でレプリカ数を増減しても性能は向上しません。 一度にアクティブなのはリーダー1台だけなので、冗長化目的の固定レプリカで十分です。
ホステッド・コントロールプレーンの場合
CCM を 別クラスタ に置く Hosted Control Plane パターンでは、ネットワーク経路や認証方式が異なるため、上記の self‑managed 向けガイダンスがそのまま通用しない点に注意してください。インフラ要件に合わせて接続トポロジと権限設計を再検討しましょう。
まとめ
- CCM は Node 初期化の鍵。動き出せないとクラスタ全体が停止する
- taint とネットワーク依存を断ち切る 設計が"卵鶏問題"の根絶策
- Kubernetes 1.31 以降を導入するすべての運用者は、自身の ブートストラップ手順と Manifest を点検し、CCM が確実に稼働できる配置になっているか今すぐ確認しよう
これらを押さえておけば、今後のクラウドプロバイダ移行や制御プレーンモダナイズも安心して進められます🐔🥚
参考
この記事は、 本家ブログ、 https://kubernetes.io/blog/2025/02/14/cloud-controller-manager-chicken-egg-problem/?utm_source=chatgpt.com の紹介です。