Kubernetes Kubernetes

Kubernetes クラスターの仕組み:コントロールプレーンとノード

クラスターを動かすコンポーネントと、kubectl apply から実行中のコンテナまでの間に何が起きるか。

12 min learn.level.初級

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 のマニフェストを適用したとします。次のようなことが起きます。

  1. kubectl が kubeconfig を読み取り、マニフェストを HTTPS で API サーバーに送ります。
  2. API サーバーはあなたを認証、認可し、オブジェクトを検証し、etcd に保存して、応答します。
  3. Deployment コントローラーが新しい Deployment に気づいて ReplicaSet を作成し、ReplicaSet コントローラーが Pod オブジェクトを作成します。この時点で、Pod は存在しますが、ノードには割り当てられていません。
  4. スケジューラーが、ノードのない Pod に気づき、それぞれにノードを選び、その決定を API サーバー経由で記録します。
  5. 選ばれたノードの kubelet が、自分に割り当てられた Pod を見つけ、コンテナランタイムにイメージを pull してコンテナを起動するよう指示します。
  6. 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 は、望ましい状態と実際の状態の差にすぎず、コントローラーが最終的に修正します。

人気のガイド