Kubernetes クラスターの仕組み:コントロールプレーンとノード
クラスターを動かすコンポーネントと、kubectl apply から実行中のコンテナまでの間に何が起きるか。
Kubernetes クラスターは、協調して動作するプロセスの集合です。それぞれが何をしているかを知ると、スケジューリングからトラブルシューティングまで、他のあらゆることを推論しやすくなります。このガイドでは、コンポーネントを紹介し、1 つのリクエストが実行中のコンテナに至るまでを追います。
コントロールプレーンとワーカーノード
コントロールプレーンは、クラスターに関する意思決定を行います。ワーカーノードは、ワークロードを実行します。minikube のようなローカルクラスターでは、1 つのノードが両方の役割を担います。本番クラスターは通常、可用性のために複数のコントロールプレーンノードを持ちます。唯一のノードを失うと、クラスター内で何も変更できなくなりますが、すでに実行中のワークロードは、通常しばらくの間、動作し続けます。アプリケーションの Pod がそこにスケジュールされないよう、コントロールプレーンノードには通常 taint が付けられます。
コントロールプレーンのコンポーネント
- kube-apiserver は玄関口です。すべてのクライアント(
kubectl、ダッシュボード、スクリプト、他のコンポーネント)が、HTTP API 経由でこれと通信します。リクエストを認証、認可し、オブジェクトを検証し、etcd を読み書きする唯一のコンポーネントです。 - etcd は、クラスターのすべての状態を保持する、一貫性のあるキーバリューストアです。どのノードが存在するか、どの Pod を実行すべきか、その現在のステータスなどです。クラスターの記憶のように扱ってください。バックアップを取ってください。失うと、すべてを追跡できなくなるからです。
- kube-scheduler は、まだノードのない各 Pod に対して、リソース要求、制約、利用可能な容量に基づいて、ノードを選びます。
- kube-controller-manager は、コントローラーを実行します。コントローラーは、望ましい状態と実際の状態を比較し、その差に対して動作する制御ループです。Deployment、ReplicaSet、Node のコントローラーはすべてここにあります。
- cloud-controller-manager(クラウドプロバイダー上のみ)は、ロードバランサーやノードのライフサイクルなどについて、プロバイダーと統合します。
ノードのコンポーネント
- kubelet は、すべてのノード上のエージェントです。自分のノードに割り当てられた Pod を監視し、そのコンテナが実行され、正常であることを確認し、ステータスを報告します。
- コンテナランタイムは、実際にコンテナを実行します。通常は containerd または CRI-O で、Container Runtime Interface を介して接続されます。Kubernetes は、もう Docker Engine と直接通信しません(dockershim は 1.24 で削除されました)が、イメージは公開された OCI 標準に従っているため、Docker でビルドしたイメージは引き続き動作します。
- kube-proxy は、各ノード上で、Service のアドレスを適切な Pod に到達させるネットワークルールを維持します。
- ネットワークプラグイン(CNI)は、Pod に IP アドレスとノード間の接続性を与えます。
kubectl apply から実行中のコンテナまでのリクエストを追う
Deployment のマニフェストを適用したとします。次のようなことが起きます。
kubectlが kubeconfig を読み取り、マニフェストを HTTPS で API サーバーに送ります。- API サーバーはあなたを認証、認可し、オブジェクトを検証し、etcd に保存して、応答します。
- Deployment コントローラーが新しい Deployment に気づいて ReplicaSet を作成し、ReplicaSet コントローラーが Pod オブジェクトを作成します。この時点で、Pod は存在しますが、ノードには割り当てられていません。
- スケジューラーが、ノードのない Pod に気づき、それぞれにノードを選び、その決定を API サーバー経由で記録します。
- 選ばれたノードの kubelet が、自分に割り当てられた Pod を見つけ、コンテナランタイムにイメージを pull してコンテナを起動するよう指示します。
- kubelet が進捗を API サーバーに報告し、API サーバーはそれを etcd に保存します。それが
kubectl get podsの読み取るものです。
コンポーネント同士が、直接互いを呼び出すことは決してないことに注目してください。それぞれが、関心のあるオブジェクトについて API サーバーを監視し、反応します。この疎結合が、何も失うことなく、ほとんどのコンポーネントを再起動できる理由です。必要な状態は etcd にあります。
この順序は、Kubernetes が記録するイベントで確認できます。
kubectl create deployment demo --image=nginx:1.25
kubectl get events --sort-by=.metadata.creationTimestamp
Scheduled、Pulling、Pulled、Created、Started を探してください。これらは、スケジューラーと kubelet がそれぞれの役割を果たしているものです。
自分のクラスターのコンポーネントを見る
kubectl get nodes -o wide
kubectl get pods -n kube-system
minikube や kubeadm で構築されたクラスターでは、コントロールプレーンのコンポーネントが、kube-proxy やネットワークプラグインと並んで、kube-system namespace の Pod として動作しているのが見えます。マネージドサービス(EKS、GKE、AKS)では、プロバイダーがコントロールプレーンを代わりに動かしており、自分のワーカーノードだけが見えます。
この設計が実際に意味すること
- API サーバーがボトルネック。 すべてがそこを通るため、その保護とサイジングが重要です。
- etcd の健全性がクラスターの健全性。 バックアップを取り、本番では冗長に実行してください。
- 障害は想定内。 死んだノード、クラッシュしたコンポーネント、削除された Pod は、望ましい状態と実際の状態の差にすぎず、コントローラーが最終的に修正します。
人気のガイド
-
Kubernetes とは何か、そしてそれが解決する問題 コンテナだけではスケールしなくなる理由と、Kubernetes がマシンの集まりを 1 つのプラットフォームに変える方法。 -
Deployment:スケーリング、自己修復、ローリングアップデート Pod のレプリカを実行し、ダウンタイムなしで更新し、リリースがうまくいかなかったときにロールバックします。 -
Service:短命な Pod のための安定したネットワーキング Pod に安定したアドレスを与え、クラスターの内外に公開し、誰が誰と通信できるかを制限します。 -
失敗する Pod をデバッグする:describe、logs、exec、port-forward Pod が Pending のまま、クラッシュする、応答しない原因を突き止めるための、繰り返し使えるチェックリスト。