高可用性と高性能は、分散ジョブに不可欠です。 ACK Proクラスターでは、Kubernetesネイティブのスケジューリングセマンティクスを使用して、分散ジョブをゾーン全体に分散して高可用性を実現できます。 また、Kubernetesネイティブのスケジューリングセマンティクスを使用して、アフィニティ設定に基づいて特定のゾーンに分散ジョブをデプロイし、高いパフォーマンスを実現することもできます。
前提条件
Kubernetes 1.20以降を実行するACK Proクラスターが作成されます。 詳細については、「ACK管理クラスターの作成」をご参照ください。
ACK Proクラスターのkube-schedulerコンポーネントは、次の表の要件を満たしています。
ACK ProクラスターKubernetesバージョン
kube-schedulerバージョン (最小要件)
1.28
1.28.3-aliyun-5.9
1.26
1.26.3-aliyun-5.9
1.24
1.24.6-aliyun-5.9
1.22
1.22.15-aliyun-5.9
1.22よりも早い
説明Elastic Container Instanceベースのポッドをゾーンに分散してアフィニティを設定するには、Kubernetesバージョンのクラスターを更新します。 詳細については、「ACKクラスターの更新」をご参照ください。
非対応
説明Elastic Container Instanceベースのポッドをゾーンに分散してアフィニティを設定するには、kube-schedulerのバージョンを更新します。 詳細については、「kube-scheduler」をご参照ください。
Elastic Container Instanceベースのポッドをスケジュールするときは、eci-profile ConfigMapで目的のvSwitchを指定していることを確認してください。 詳細については、「eci-profileの設定」をご参照ください。
Elastic Container Instanceベースのポッドは、
nodeAffinity
、podAffinity
、およびtopologySpreadConstraints
パラメーターがポッドに設定されている場合、またはポッドが既存のリソースポリシーと一致している場合にのみ、ゾーン間に分散できます。説明ARMアーキテクチャを使用する仮想ノードにポッドをスケジュールする場合は、ノードの汚染を許容するように
tolerations
パラメーターを設定する必要があります。クラスターで仮想ノードスケジューリングが有効になり、クラスターのKubernetesバージョンとコンポーネントバージョンが要件を満たしています。
注意事項
Elastic Container Instanceベースのポッドをゾーンに分散する場合、
topologyKey
パラメーターをtopology.kubernetes.io/zone
にのみ設定できます。Elastic Container Instanceベースのポッドをゾーン間に分散する場合、ポッドの分散先のvSwitchの優先順位を指定するためのアノテーションを追加することはできません。 ポッドを分散できるvSwitchの優先度を指定した場合、ポッドをゾーンに分散することはできません。
FastFailedモードでは、Elastic Container Instanceベースのポッドをゾーン全体に広げることはできません。 ポッドに対してFastFailedモードが有効になっている場合、ポッドをゾーン間に広げることはできません。
用語
ポッドトポロジの広がりとアフィニティの詳細については、「ポッドトポロジの広がりの制約」および「ポッドをノードに割り当てる」をご参照ください。 用語の詳細については、「NodeAffinity」、「PodAffinity」、および「maxSkew」をご参照ください。
Elastic Container Instanceベースのポッドをゾーン間で拡散し、アフィニティを設定する
次の例は、Elastic Container Instanceベースのポッドをゾーン全体に分散し、Kubernetes 1.22を実行するACK Proクラスターでアフィニティを設定する方法を示しています。
例1: トポロジ拡散制約を使用してElastic Container Instanceベースのポッドをゾーン全体に拡散する
トポロジ拡散制約をワークロードの構成に追加します。
次の手順を実行して、ポッドの構成の
[Spec]
パラメーター、またはデプロイやジョブなどのワークロードの構成の[Spec]
パラメーターでトポロジスプレッド制約を指定します。topologySpreadConstraints: - maxSkew: <integer> minDomains: <integer> # This parameter is optional and is in the Beta phase in Kubernetes 1.25 and later. topologyKey: <string> whenUnsatisfiable: <string> labelSelector: <object> matchLabelKeys: <list> # This parameter is optional and is in the Beta phase in Kubernetes 1.27 and later. nodeAffinityPolicy: [Honor|Ignore] # This parameter is optional and is in the Beta phase in Kubernetes 1.26 and later. nodeTaintsPolicy: [Honor|Ignore] # This parameter is optional and is in the Beta phase in Kubernetes 1.26 and later.
この例では、ポッドが複数のゾーンに均等に分散されているDeploymentが作成されます。 次のコードブロックは、デプロイのYAMLテンプレートを示しています。
パラメーター
説明
preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: type operator: NotIn values: - virtual-kubelet
設定では、ポッドがECS (Elastic Compute Service) ノードに優先的にスケジュールされることを指定します。
パラメーターの詳細については、 ノードアフィニティ。
topologySpreadConstraints: - maxSkew: 1 topologyKey: topology.kubernetes.io/zone whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: app: with-pod-topology-spread
設定では、ポッドが複数のゾーンに均等に展開されるように指定します。
パラメーターの詳細については、 topologySpreadConstraintsフィールド
tolerations: - key: "virtual-kubelet.io/provider" operator: "Exists" effect: "NoSchedule"
kube-schedulerは、仮想ノードの汚染を許容して、ポッドを仮想ノードにスケジュールします。
パラメーターの詳細については、 テイントと寛容。
説明ポッドをARMベースの仮想ノードにスケジュールする場合は、ARMベースの仮想ノードの汚染を許容する許容範囲をポッドに追加する必要があります。
ワークロードを作成します。
deployment.yaml
という名前のファイルを作成し、上記のYAMLテンプレートをファイルにコピーします。 次に、次のコマンドを実行して、クラスターにデプロイを作成します。kubectl apply -f deployment.yaml
ワークロードのスケジューリング結果を確認します。
次のコマンドを実行して、デプロイがポッドをデプロイするノードを照会します。
kubectl get po -lapp=with-pod-topology-spread -ocustom-columns=NAME:.metadata.name,NODE:.spec.nodeName --no-headers | grep -v "<none>"
次のコマンドを実行して、各ゾーンのDeploymentによって作成されたポッドの数を照会します。
kubectl get po -lapp=with-pod-topology-spread -ocustom-columns=NODE:.spec.nodeName --no-headers | grep -v "<none>" | xargs -I {} kubectl get no {} -ojson | jq '.metadata.labels["topology.kubernetes.io/zone"]' | sort | uniq -c
例2: 特定のゾーンにポッドを配置するためのポッドアフィニティとノードアフィニティの設定
ワークロードの構成にアフィニティを追加します。
この例では、ポッドが1つのゾーンにデプロイされているDeploymentが作成されます。 次のコードブロックは、デプロイのYAMLテンプレートを示しています。
パラメーター
説明
podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - with-affinity topologyKey: topology.kubernetes.io/zone
この構成では、すべてのポッドが単一のゾーンにデプロイされるように指定します。
パラメーターの詳細については、 ノードアフィニティ。
nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: type operator: NotIn values: - virtual-kubelet
設定は、ポッドが優先的にECSノードにスケジュールされることを指定します。
パラメーターの詳細については、 ノードアフィニティ。
tolerations: - key: "virtual-kubelet.io/provider" operator: "Exists" effect: "NoSchedule"
kube-schedulerは、仮想ノードの汚染を許容して、ポッドを仮想ノードにスケジュールします。
パラメーターの詳細については、 テイントと寛容。
特定のゾーンにポッドをデプロイする場合は、
podAffinity
パラメーターを削除し、nodeAffinity
パラメーターに次の制約を追加します。requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: topology.kubernetes.io/zone operator: In values: - cn-beijing-a
ワークロードを作成します。
deployment.yaml
という名前のファイルを作成し、上記のYAMLテンプレートをファイルにコピーします。 次に、次のコマンドを実行して、クラスターにデプロイを作成します。kubectl apply -f deployment.yaml
ワークロードのスケジューリング結果を確認します。
次のコマンドを実行して、デプロイがポッドをデプロイするノードを照会します。
kubectl get po -lapp=with-affinity -ocustom-columns=NAME:.metadata.name,NODE:.spec.nodeName --no-headers | grep -v "<none>"
次のコマンドを実行して、各ゾーンのDeploymentによって作成されたポッドの数を照会します。
kubectl get po -lapp=with-affinity -ocustom-columns=NODE:.spec.nodeName --no-headers | grep -v "<none>" | xargs -I {} kubectl get no {} -ojson | jq '.metadata.labels["topology.kubernetes.io/zone"]' | sort | uniq -c
厳密なElastic Containerインスタンスベースのポッドトポロジの広がり
デフォルトでは、システムにElastic Container Instanceベースのポッドをゾーン全体に分散させる場合、kube-schedulerはワークロードのポッドをすべてのゾーンに均等にデプロイします。 ただし、Elastic Container Instanceベースのポッドが一部のゾーンで作成されない場合があります。 次の図は、maxSkewパラメーターが1に設定されている場合のスケジューリング結果を示しています。 maxSkewの詳細については、 maxSkewを使用します。
ゾーンBおよびゾーンCのElastic Container Instanceベースのポッドの作成に失敗した場合、2つのElastic Container InstanceベースのポッドがゾーンAで実行され、Elastic Container InstanceベースのポッドはゾーンBまたはゾーンCで実行されません。これは、maxSkewパラメーターで指定された制約に違反します。
ACK Proクラスターでは、厳格なElastic Container Instanceベースのポッドトポロジスプレッドを有効にして、ポッドがゾーン間に厳密に分散されるようにすることができます。 厳密なElastic Container Instanceベースのポッドトポロジスプレッドを有効にすると、kube-schedulerはまず、ゾーンa、ゾーンB、およびゾーンCのそれぞれにポッドをスケジュールします。次の図に示すように、スケジュールされたポッドが作成されるまで、kube-schedulerは保留中のポッドをスケジュールしません。
ポッドA1が作成されても、保留中のポッドはスケジュールされません。 これは、ゾーンBまたはゾーンCのポッドの作成に失敗した場合、maxSkewパラメーターで指定された制約に違反するためです。 ポッドB1が作成された後、kube-schedulerはポッドをゾーンCにスケジュールします。緑のシェーディングを持つポッドが作成されます。
厳格なElastic Container Instanceベースのポッドトポロジスプレッドを無効にする場合は、whenUnsatisfiable
パラメーターをScheduleAnyway
に設定します。 詳細については、次をご参照ください: スプレッド制約の定義