4.6. Pod トポロジー分散制約を使用した Pod 配置の制御
Pod トポロジーの分散制約を使用すると、ノード、ゾーン、リージョン、またはその他のユーザー定義のトポロジードメイン全体にわたる Pod の配置を詳細に制御できます。障害ドメイン全体に Pod を分散すると、高可用性とより効率的なリソース利用を実現できます。
4.6.1. 使用例
- 管理者として、ワークロードを 2 個から 15 個の Pod 間で自動的にスケーリングしたいと考えています。Pod が 2 つしかない場合は、単一障害点を回避するために、Pod が同じノードに配置されないようにする必要があります。
- 管理者として、レイテンシーとネットワークコストを削減するために、Pod を複数のインフラストラクチャーゾーンに均等に分散し、問題が発生した場合にクラスターが自己修復できることを確認したいと考えています。
4.6.2. 重要な留意事項
- Red Hat OpenShift Service on AWS クラスター内の Pod は、デプロイメント、ステートフルセット、デーモンセットなどの ワークロードコントローラー によって管理されます。これらのコントローラーは、クラスター内のノード間で Pod がどのように分散およびスケーリングされるかなど、Pod のグループの望ましい状態を定義します。混乱を避けるために、グループ内のすべての Pod に同じ Pod トポロジーの分散制約を設定する必要があります。デプロイメントなどのワークロードコントローラーを使用する場合、通常は Pod テンプレートがこれを処理します。
-
異なる Pod トポロジーの分散制約を混在させると、Red Hat OpenShift Service on AWS の動作が混同され、トラブルシューティングが困難になる可能性があります。トポロジードメイン内のすべてのノードに一貫したラベルが付けられていることを確認することで、これを回避できます。Red Hat OpenShift Service on AWS は、
kubernetes.io/hostname
などのよく知られたラベルを自動的に入力します。これにより、ノードに手動でラベルを付ける必要がなくなります。これらのラベルは重要なトポロジー情報を提供し、クラスター全体で一貫したノードラベル付けを保証します。 - 制約により、分散される際に同じ namespace 内の Pod のみが一致し、グループ化されます。
- 複数の Pod トポロジー分散制約を指定できますが、それらが互いに競合しないようにする必要があります。Pod を配置するには、すべての Pod トポロジー分散制約を満たしている必要があります。
4.6.3. skew と maxSkew
スキューとは、ゾーンやノードなどの異なるトポロジードメイン間で指定されたラベルセレクターに一致する Pod の数の差を指します。
スキューは、各ドメイン内の Pod の数と、スケジュールされている Pod の数が最も少ないドメイン内の Pod 数との絶対差をとることで、各ドメインごとに計算されます。maxSkew
値を設定すると、スケジューラーはバランスの取れた Pod 分散を維持するようになります。
4.6.3.1. スキューの計算例
3 つのゾーン (A、B、C) があり、これらのゾーンに Pod を均等に分散したいと考えています。ゾーン A に Pod が 5 個、ゾーン B に Pod が 3 個、ゾーン C に Pod が 2 個ある場合、偏りを見つけるには、各ゾーンに現在ある Pod の数から、スケジュールされている Pod の数が最も少ないドメインの Pod の数を減算します。つまり、ゾーン A のスキューは 3、ゾーン B のスキューは 1、ゾーン C のスキューは 0 です。
4.6.3.2. maxSkew パラメーター
maxSkew
パラメーターは、任意の 2 つのトポロジードメイン間の Pod 数の最大許容差、つまりスキューを定義します。maxSkew
が 1
に設定されている場合、トポロジードメイン内の Pod の数は、他のドメインとの差が 1 を超えてはなりません。スキューが maxSkew
を超える場合、スケジューラーは制約に従ってスキューを減らす方法で新しい Pod を配置しようとします。
前のスキュー計算例を使用すると、スキュー値はデフォルトの maxSkew
値 1
を超えます。スケジューラーは、スキューを減らして、負荷がバランスよく分散されるように、ゾーン B とゾーン C に新しい Pod を配置し、トポロジードメインがスキュー 1 を超えないようにします。
4.6.4. Pod トポロジー分散制約の設定例
グループ化する Pod を指定し、それらの Pod が分散されるトポロジードメインと、許可できるスキューを指定します。
以下の例は、Pod トポロジー設定分散制約の設定を示しています。
指定されたラベルに一致する Pod をゾーンに基づいて分散する例
apiVersion: v1 kind: Pod metadata: name: my-pod labels: region: us-east spec: securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault topologySpreadConstraints: - maxSkew: 1 1 topologyKey: topology.kubernetes.io/zone 2 whenUnsatisfiable: DoNotSchedule 3 labelSelector: 4 matchLabels: region: us-east 5 matchLabelKeys: - my-pod-label 6 containers: - image: "docker.io/ocpqe/hello-pod" name: hello-pod securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL]
- 1
- 任意の 2 つのトポロジードメイン間の Pod 数の最大差。デフォルトは
1
で、0
の値を指定することはできません。 - 2
- ノードラベルのキー。このキーと同じ値を持つノードは同じトポロジーにあると見なされます。
- 3
- 分散制約を満たさない場合に Pod を処理する方法です。デフォルトは
DoNotSchedule
であり、これはスケジューラーに Pod をスケジュールしないように指示します。ScheduleAnyway
に設定して Pod を依然としてスケジュールできますが、スケジューラーはクラスターがさらに不均衡な状態になるのを防ぐためにスキューの適用を優先します。 - 4
- 制約を満たすために、分散される際に、このラベルセレクターに一致する Pod はグループとしてカウントされ、認識されます。ラベルセレクターを指定してください。指定しないと、Pod が一致しません。
- 5
- 今後適切にカウントされるようにするには、この
Pod
仕様がこのラベルセレクターに一致するようにラベルを設定していることも確認してください。 - 6
- 拡散を計算する Pod を選択するための Pod ラベルキーのリスト。
単一 Pod トポロジーの分散制約を示す例
kind: Pod apiVersion: v1 metadata: name: my-pod labels: region: us-east spec: securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault topologySpreadConstraints: - maxSkew: 1 topologyKey: topology.kubernetes.io/zone whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: region: us-east containers: - image: "docker.io/ocpqe/hello-pod" name: hello-pod securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL]
前の例では、Pod トポロジーの分散制約が 1 つある Pod
仕様を定義しています。これは region: us-east
というラベルが付いた Pod で一致し、ゾーン間で分散され、スキューの 1
を指定し、これらの要件を満たさない場合に Pod をスケジュールしません。
複数の Pod トポロジー分散制約を示す例
kind: Pod apiVersion: v1 metadata: name: my-pod-2 labels: region: us-east spec: securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault topologySpreadConstraints: - maxSkew: 1 topologyKey: node whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: region: us-east - maxSkew: 1 topologyKey: rack whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: region: us-east containers: - image: "docker.io/ocpqe/hello-pod" name: hello-pod securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL]
上記の例では、Pod
トポロジー分散制約が 2 つある Pod 仕様を定義します。どちらも region: us-east
というラベルの付いた Pod に一致し、スキューを 1
に指定し、これらの要件を満たしていない場合は Pod はスケジュールされません。
最初の制約は、ユーザー定義ラベルの node
に基づいて Pod を分散し、2 つ目の制約はユーザー定義ラベルの rack
に基づいて Pod を分散します。Pod がスケジュールされるには、両方の制約を満たす必要があります。