DUICUO

Kubernetesコアコンポーネントの概要 - コントローラー

Kubernetes のリソースオブジェクトには、ポッド、ノード、名前空間、エンドポイント、サービスが含まれます。Kubernetes は、様々なリソースオブジェクトに対してコントローラーも提供しており、オブジェクトの現在の状態(ステータス)を、コミットされる予定の状態(スペック)に近づけることができます。この記事では、コントローラーについて、原則、種類、使用方法の 3 つの側面から解説します。

I. コントローラー原則

1. 一般原則

Kubernetes クラスターでは、コントローラーは API サーバーが提供する (List & Watch) インターフェースを通じて、クラスター内のリソースオブジェクトの状態変化をリアルタイムで監視します。リソースオブジェクトの状態変化を引き起こす障害が発生した場合、コントローラーはその状態を望ましい状態に調整しようとします。

たとえば、ポッドに障害が発生すると、デプロイメント コントローラはすぐに障害を検出し、自動修復プロセスを実行して、クラスター内のポッドが常に期待どおりの動作状態にあることを確認します。

詳細なプロセスを以下の図に示します。

Kubernetes コントローラーは、次の 3 つのステップを定期的に繰り返すことで制御タスクを実行します。

  • API サーバーからリソース オブジェクトの予想される状態と現在の状態を読み取ります。
  • 両者の違いを比較し、コントローラーを実行して実際のリソース オブジェクトを操作し、リソース オブジェクトの実際の状態を仕様で定義された期待される状態に修正します。
  • 変更が正常に実行されると、結果のステータスが API サーバー上のターゲット リソース オブジェクトのステータス フィールドに書き戻されます。

2. コントローラーマネージャー

Kubernetesは、様々なリソースオブジェクト用のコントローラーを提供します。各コントローラーは特定のリソースの制御フローを担当し、コントローラーマネージャーはこれらのコントローラーを管理します。

コントローラーマネージャーは、リソースの実際の状態と期待される状態の間に矛盾を検出すると、対応するコントローラーによって登録されたイベントハンドラーをトリガーし、リソース自体の特性に応じて調整するよう指示します。コントローラーマネージャーと呼ばれるのは、デプロイメントコントローラー、ノードコントローラー、名前空間コントローラー、サービスコントローラーなど、異なるリソースを担当する複数のコントローラーで構成されているためです。これらのコントローラーはそれぞれ明確に定義された役割を持ち、クラスター内のさまざまなリソースの管理を担っています。

3. 周期制御と即時制御

Kubernetes クラスターは多数の制御ループを実行し、それぞれが特定のタスクセットを処理します。API サーバーが大量のリクエストに圧倒されるのを防ぐため、制御ループの実行頻度を低く設定する必要があります。デフォルトでは 5 分に 1 回です。

一方、クライアントから送信された目的の状態を迅速にトリガーするために、コントローラはAPIサーバーに登録し、リソースオブジェクトのイベントをリッスンします。これらのリソースオブジェクトの目的の状態に変更があった場合、Informerコンポーネントによってコントローラに通知され、次の制御ループを待たずに即座に実行されます。

コントローラは、ワーク キューを使用して実行する必要のある制御ループをキューに入れます。これにより、制御対象のリソース オブジェクトが多数ある場合や、リソース オブジェクトが頻繁に変更される場合でも、制御タスクが失われないことが保証されます。

このプロセスはビッグデータ統計を行うプロセスに似ており、リアルタイム計算を使用してタイムリーに結果を生成し、バッチ計算を使用して毎日の統計を生成し、リアルタイム計算の結果を再比較して修正します。

全体的なプロセスを次の図に示します。

II. コントローラーの種類

Kubernetesは、レプリケーションコントローラー、ノードコントローラー、リソース出力コントローラー、ネームスペースコントローラー、サービスアカウントコントローラー、サービスコントローラー、エンドポイントコントローラー、デプロイメントコントローラーなど、さまざまなリソースオブジェクト用のコントローラーを提供します。以下は、よく使用されるコントローラーの一部です。

1. レプリカセットコントローラー

ReplicaSetは、一定数のPodレプリカが常に稼働していることを保証します。レプリカ数が多すぎる場合、ReplicaSetは一部を削除します。レプリカ数が少なすぎる場合、ReplicaSetは一部を作成します。Podを直接作成する場合とは異なり、ReplicaSetは削除または終了されたPodを置き換えます。

ReplicaSets はデプロイメントを通じて管理することをお勧めします。通常、ReplicaSets を直接操作する必要はありません。

ReplicaSetコントローラーでは、Podテンプレートは型のような役割を果たします。型から作成されたものが型から外れると、他のPodとの関連性は失われます。同様に、Podが作成された後は、テンプレートに変更を加えても、既に作成されたPodには影響しません。

2. デプロイメントコントローラ

Deploymentは、アプリケーションのレプリカを管理するためのAPIオブジェクトです。管理者はDeploymentに望ましい状態を記述するだけで、Deploymentは特定の戦略に従って、レプリカセットとPodを管理者が期待する状態に更新します。DeploymentはPodの実行機能を提供し、Podのローリングアップグレード、スケーリング、レプリケーションなどの機能を提供します。一般的には、ステートレスアプリケーションの実行に使用されます。

なお、Deployment は Pod を直接制御するのではなく、前述のように ReplicaSet を通じて Pod を管理します。

デプロイメントリソースオブジェクトを作成した後、デプロイメントコントローラは対応するレプリカセットも自動的に作成します。デプロイメントコントローラは、新しいレプリカセットを自動的に作成することで、デプロイメントのローリングアップグレードをサポートします。

3. ステートフルセットコントローラー

StatefulSetは、Podセットのデプロイメントとスケーリングを管理するために使用され、これらのPodに永続的なストレージと永続的な識別子を提供します。Deploymentとは異なり、StatefulSetは各Podに固定のIDを保持します。これらのPodは同じテンプレートに基づいて作成されますが、交換することはできません。各Podは、スケジュールに関係なく固定のIDを持ちます。

4. デーモンセットコントローラー

DaemonSetは、Podのレプリカがすべてのノードで実行されることを保証します。ノードがクラスターに参加すると、そのノード用に新しいPodが自動的に作成されます。ノードがクラスターから削除されると、これらのPodは回収されます。DaemonSetを削除すると、そのノードが作成したすべてのPodも削除されます。

5. ジョブコントローラ

ジョブは、短命で単発的なタスク(つまり、一度だけ実行されるタスク)のバッチ処理を担当します。ジョブは、バッチ処理タスクの1つ以上のポッドが正常に完了することを保証します。

6. CronJobコントローラ

CronJob は、Cron 式に従って一定の間隔でジョブを実行し、タスクを定期的に処理する役割を担います。

7. ノードコントローラ

kubeletプロセスは起動すると、ノード情報をAPIサーバーに登録し、定期的にステータス情報をAPIサーバーに報告します。APIサーバーはこの情報を受け取った後、etcdで更新します。etcdに保存されるノード情報には、ノードのヘルスステータス、ノードリソース、ノード名、ノードアドレス情報、オペレーティングシステムのバージョン、Dookerのバージョン、kubeletのバージョンなどが含まれます。

ノードのヘルス ステータスには、True、False、不明の 3 つのカテゴリが含まれます。

ノード コントローラは、API サーバーを介してノードに関する関連情報をリアルタイムで取得し、クラスター内の各ノードの制御機能を管理および監視できるようにします。

8. リソースクォータコントローラー

ResourceQuotaコントローラーは、指定されたリソースオブジェクトがシステムの物理リソースを超過しないようにすることで、特定のビジネスロジックの設計または実装上の欠陥によるシステムの誤動作やクラッシュを防止します。例えば、コンテナのCPUとメモリの使用量を制限したり、名前空間内のPod、Service、ページビュー(PV)の数を制限したりできます。

9.サービスコントローラとエンドポイントコントローラ

まず、Service、Endpoints、Podの関係を見てみましょう。下の図に示すように、EndpointsはServiceに対応するすべてのPodレプリカのアクセスアドレスを表し、Endpoints ControllerはすべてのEndpointsオブジェクトの生成と管理を担当するコントローラーです。

エンドポイントコントローラは、サービスとそれに対応するポッドレプリカへの変更を監視します。サービスが削除されたと検出された場合、そのサービスと同じ名前のエンドポイントオブジェクトを削除します。新しいサービスが作成または変更されたと検出された場合、そのサービス情報に基づいて関連するポッドリストを取得し、そのサービスに対応するエンドポイントオブジェクトを作成または更新します。ポッドイベントが検出された場合、対応するサービスのエンドポイントオブジェクトを更新します(対応するエンドポイントリストを追加、削除、または変更します)。

では、エンドポイントオブジェクトはどこで使用されるのでしょうか?答えは、各ノード上のkube-proxyプロセスです。kube-proxyプロセスは各サービスのエンドポイントを取得し、サービスの負荷分散機能を実装します。

サービス コントローラは、サービス内の変更をリッスンし、それに応じて (エンドポイントのリストに基づいて) ルーティング テーブルを作成、削除、または更新します。

III. 管理者の利用

ワークロード コントローラー リソースは通常、3 つの基本コンポーネントで構成されます。

  • セレクタ: Podオブジェクトを一致させて関連付ける
  • 予想されるレプリカ数: クラスター内で実行される制御対象ポッドの予想数。
  • Pod テンプレート: 新しい Pod オブジェクトを作成するために使用されるテンプレート。

ワークロード コントローラー リソースの spec フィールドには通常、レプリカ、セレクター、テンプレートのフィールドが含まれます。ここで、テンプレートは Pod テンプレートを定義するために使用されます。

よく使用されるコントローラーの YAML ファイルは次のとおりです。

1. 展開

レプリカ数が replicas=2 に設定されていると仮定して、Pod グループを管理すると、node01 と node02 にそれぞれ 1 つの Pod が割り当てられます。この場合、node02 がシャットダウンすると、node01 に 2 つの Pod がデプロイされます。

 apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment namespace: test labels: app: nginx-deployment spec: replicas: 2 selector: matchLabels: app: nginx-deployment-tp template: metadata: labels: app: nginx-deployment-tp spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent tolerations: - key: "node.kubernetes.io/unreachable" operator: "Exists" effect: "NoExecute" tolerationSeconds: 30

2. ステートフルセット

StatefulSet はより複雑なワークロードの一つですが、その中核となる機能は依然として Pod のグループを管理することです。例えば、レプリカ数が 2 に設定されているとすると、この Pod グループは以下の特性を持ちます。

  • 起動順序: 最初に pod-0 が起動し、次に pod-1 が起動します。
  • 停止の順序: pod-1 が停止した後、pod-0 が停止します。
  • ステートフル: ポッド ID は変更されず、作成された PVC はポッドにバインドされ、一意の volumeClaimTemplate 構成を持ち、storageClass を使用して PVC と PV を自動的に作成します。
  • 安定したサービス検出:ポッドIDは固定かつステートフルであるため、サービスは必要なポッドを見つけることができます。例えば、特定のポッドにアクセスするには、「curl pod_name.svc_name.namespace.svc.cluster.local」を直接使用できます。
 apiVersion: v1 kind: Service metadata: name: nginx-statefulset-svc namespace: test spec: # ClusterIP | LoadBalancer | type: ClusterIP # headless service clusterIP: None selector: app: nginx-statefulset-tp ports: - name: http port: 80 targetPort: 80 # nodePort: 30080 --- apiVersion: apps/v1 kind: StatefulSet metadata: name: nginx-statefulset namespace: test labels: app: nginx-statefulset spec: replicas: 2 serviceName: nginx-statefulset-svc selector: matchLabels: app: nginx-statefulset-tp template: metadata: labels: app: nginx-statefulset-tp spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent volumeMounts: - name: www mountPath: /usr/share/nginx/html tolerations: - key: "node.kubernetes.io/unreachable" operator: "Exists" effect: "NoExecute" tolerationSeconds: 30 volumeClaimTemplates: - metadata: name: www spec: resources: requests: storage: 100Mi accessModes: - ReadWriteOnce storageClassName: nfs-client

3. デーモンセット

Podのグループを管理する場合、DeploymentやStatefulSetとは異なり、レプリカ数の概念はありません。以下の特徴があります。

  • 各ノードに1つのポッドをデプロイする
  • ノードにデプロイされたポッドは削除されず、すべてのノードのテイントに対する許容度がデフォルトで追加されます。
 apiVersion: apps/v1 kind: DaemonSet metadata: name: nginx-daemonset namespace: test labels: app: nginx-daemonset spec: selector: matchLabels: app: nginx-daemonset-tp template: metadata: labels: app: nginx-daemonset-tp spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent

4. ジョブ

一度実行されて終了するポッド

apiVersion: batch/v1 kind: Job metadata: name: hello namespace: test spec: # 尝试backoffLimit+1次没有成功则退出Job backoffLimit: 2 completions: 3 template: spec: # 仅支持OnFailure Never restartPolicy: Never containers: - name: busybox image: busybox imagePullPolicy: IfNotPresent command: - /bin/sh - -c - echo "Hello My Job"

5. Cronジョブ

apiVersion: batch/v1 kind: CronJob metadata: name: hello namespace: test spec: # ┌───────────── 分钟(0 - 59) # │ ┌───────────── 小时(0 - 23) # │ │ ┌───────────── 月的某天(1 - 31) # │ │ │ ┌───────────── 月份(1 - 12) # │ │ │ │ ┌───────────── 周的某天(0 - 6)(周日到周一;在某些系统上,7 也是星期日) # │ │ │ │ │ 或者是sun,mon,tue,web,thu,fri,sat # │ │ │ │ │ # │ │ │ │ │ # * * * * * schedule: "* * * * *" # Allow - 允许并发# Forbid - 不允许并发丢弃新的job # Replace - 不允许并发丢弃老的job concurrencyPolicy: Allow # 记录成功的job数量successfulJobsHistoryLimit: 3 # 记录失败的job数量failedJobsHistoryLimit: 1 jobTemplate: spec: template: spec: # 仅支持OnFailure Never restartPolicy: Never containers: - name: busybox image: busybox imagePullPolicy: IfNotPresent command: - /bin/sh - -c - echo "Hello My Cron Job"

ジョブに基づいて Cron 式を定義し、スケジュールに従ってジョブを実行します。