高可用性と高パフォーマンスは、分散ジョブにとって不可欠です。ACK マネージド Pro クラスタでは、Kubernetes ネイティブのスケジューリングセマンティクスを使用して、高可用性のためにゾーン全体に分散ジョブを分散できます。また、Kubernetes ネイティブのスケジューリングセマンティクスを使用して、高可用性と高パフォーマンスのためにアフィニティ設定に基づいて特定のゾーンに Elastic Container Instance ベースのポッドをデプロイすることもできます。
前提条件
ACK Serverless Pro クラスタが作成されており、クラスタが次の要件を満たしていること。
クラスタは Kubernetes バージョン 1.22 以降で実行されている。
クラスタ内のACK 仮想ノードコンポーネントのバージョンが 2.10.0 以降である。
クラスタ内のkube-schedulerコンポーネントのバージョンが 5.9 以降であり、クラスタで仮想ノードベースのポッドスケジューリング機能が有効になっている。詳細については、「ACK クラスタの仮想ノードベースのポッドスケジューリングポリシーを有効にする」をご参照ください。
ポッドを複数のゾーンにスケジュールできるように、eci-profile で複数のゾーン(vSwitch)が指定されている。詳細については、「eci-profile を構成する」をご参照ください。
スケジュールするポッドに対して
nodeAffinity、podAffinity、topologySpreadConstraintsパラメーターが構成されているか、ポッドが既存のリソースポリシーと一致していることを確認します。説明詳細については、「クイックスタート: PHP を使用して BLOB をアップロード、ダウンロード、一覧表示する」をご参照ください。
ARM ベースの仮想ノードにポッドをスケジュールする場合は、ポッド構成の
tolerationsパラメーターで、仮想ノードの taint を許容するように指定します。
前提条件
次の要件を満たす ACK マネージド Pro クラスタ が作成されていること。
クラスタは Kubernetes 1.22 以降で実行されている。
クラスタ内の ACK 仮想ノード コンポーネントのバージョンが 2.10.0 以降である。
クラスタ内の kube-scheduler コンポーネントのバージョンが 5.9 以降である。また、クラスタの仮想ノードベースのポッドスケジューリングポリシーが有効になっている。
Elastic Container Instance ベースのポッドを構成する際に、対応する eci-profile で複数のゾーン(vSwitch)が指定されている。
nodeAffinity、podAffinity、topologySpreadConstraintsフィールドがポッド構成で指定されている。または、ポッドに ResourcePolicy が構成されている。説明ARM ベースの仮想ノードにポッドをスケジュールする場合は、ノードの taint と一致する特定の toleration をポッドに追加する必要があります。
使用上の注意
topologyKeyパラメーターをtopology.kubernetes.io/zoneに設定する必要があります。このトピックで説明されている機能は、次のシナリオでは有効になりません。
k8s.aliyun.com/eci-schedule-strategy: "VSwitchOrdered"アノテーションを使用して、指定された vSwitch の順序に従うマルチゾーンスケジューリング戦略をポッドに宣言する場合。k8s.aliyun.com/eci-fail-strategy: "fail-fast"アノテーションを使用して、ポッドのエラー処理ポリシーをfail-fastに設定する場合。
ゾーン全体に Elastic Container Instance ベースのポッドを分散し、アフィニティを構成する
次の例は、Kubernetes 1.22 を実行する ACK Pro クラスタ で、ゾーン全体に Elastic Container Instance ベースのポッドを分散し、アフィニティを構成する方法を示しています。
例 1: トポロジスプレッド制約を使用して、ゾーン全体に Elastic Container Instance ベースのポッドを分散する
ワークロードの構成にトポロジスプレッド制約を追加します。
ポッドの構成の
Specパラメーター、または Deployment や Job などのワークロードの構成のSpecパラメーターでトポロジスプレッド制約を指定するには、次の手順を実行します。topologySpreadConstraints: - maxSkew: <integer> minDomains: <integer> # このパラメーターはオプションであり、Kubernetes 1.25 以降ではベータ段階です。 topologyKey: <string> whenUnsatisfiable: <string> labelSelector: <object> matchLabelKeys: <list> # このパラメーターはオプションであり、Kubernetes 1.27 以降ではベータ段階です。 nodeAffinityPolicy: [Honor|Ignore] # このパラメーターはオプションであり、Kubernetes 1.26 以降ではベータ段階です。 nodeTaintsPolicy: [Honor|Ignore] # このパラメーターはオプションであり、Kubernetes 1.26 以降ではベータ段階です。この例では、ポッドが複数のゾーンに均等に分散される Deployment を作成します。次のコードブロックは、Deployment の YAML テンプレートを示しています。
パラメーター
説明
preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: type operator: NotIn values: - virtual-kubeletこの構成では、ポッドが優先的に Elastic Compute Service (ECS) ノードにスケジュールされるように指定しています。
パラメーターの詳細については、Node affinity を参照してください。
topologySpreadConstraints: - maxSkew: 1 topologyKey: topology.kubernetes.io/zone whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: app: with-pod-topology-spreadこの構成では、ポッドが複数のゾーンに均等にデプロイされるように指定しています。
パラメーターの詳細については、topologySpreadConstraints field を参照してください。
tolerations: - key: "virtual-kubelet.io/provider" operator: "Exists" effect: "NoSchedule"kube-scheduler は仮想ノードの taint を許容して、ポッドを仮想ノードにスケジュールします。
パラメーターの詳細については、Taints and Tolerations を参照してください。
説明ARM ベースの仮想ノードにポッドをスケジュールする場合は、ARM ベースの仮想ノードの taint を許容する toleration をポッドに追加する必要があります。
ワークロードを作成します。
deployment.yamlという名前のファイルを作成し、上記の YAML テンプレートをファイルにコピーします。次に、次のコマンドを実行して、クラスタに Deployment を作成します。kubectl apply -f deployment.yamlワークロードのスケジューリング結果を確認します。
次のコマンドを実行して、Deployment がポッドをデプロイするノードをクエリします。
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: ポッドアフィニティとノードアフィニティを構成して、特定のゾーンにポッドをデプロイする
ワークロードの構成にアフィニティを追加します。
この例では、ポッドが単一ゾーンにデプロイされる Deployment を作成します。次のコードブロックは、Deployment の YAML テンプレートを示しています。
パラメーター
説明
podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - with-affinity topologyKey: topology.kubernetes.io/zoneこの構成では、すべてのポッドが単一ゾーンにデプロイされるように指定しています。
パラメーターの詳細については、Node affinity を参照してください。
nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: type operator: NotIn values: - virtual-kubeletこの構成では、ポッドが優先的に ECS ノードにスケジュールされるように指定しています。
パラメーターの詳細については、Node affinity を参照してください。
tolerations: - key: "virtual-kubelet.io/provider" operator: "Exists" effect: "NoSchedule"kube-scheduler は仮想ノードの taint を許容して、ポッドを仮想ノードにスケジュールします。
パラメーターの詳細については、Taints and Tolerations を参照してください。
特定のゾーンにポッドをデプロイする場合は、
podAffinityパラメーターを削除し、nodeAffinityパラメーターに次の制約を追加します。次の構成では、ポッドを北京ゾーン A にデプロイする必要があることを指定しています。requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: topology.kubernetes.io/zone operator: In values: - cn-beijing-aワークロードを作成します。
deployment.yamlという名前のファイルを作成し、上記の YAML テンプレートをファイルにコピーします。次に、次のコマンドを実行して、クラスタに Deployment を作成します。kubectl apply -f deployment.yamlワークロードのスケジューリング結果を確認します。
次のコマンドを実行して、Deployment がポッドをデプロイするノードをクエリします。
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 Instance ベースのポッドトポロジスプレッド
デフォルトでは、システムにゾーン全体に Elastic Container Instance ベースのポッドを強制的に分散させると、kube-scheduler はワークロードのポッドをすべてのゾーンに均等にデプロイします。ただし、Elastic Container Instance ベースのポッドは、一部のゾーンで作成に失敗する可能性があります。次の図は、maxSkew パラメーターが 1 に設定されている場合のスケジューリング結果を示しています。maxSkew の詳細については、maxSkew を参照してください。
ゾーン B とゾーン C で Elastic Container Instance ベースのポッドの作成に失敗した場合、2 つの Elastic Container Instance ベースのポッドがゾーン A で実行され、ゾーン B またはゾーン C では Elastic Container Instance ベースのポッドは実行されません。これは、maxSkew パラメーターで指定された制約に違反しています。
厳密な Elastic Container Instance ベースのポッドトポロジスプレッドを有効にして、ポッドがゾーン全体に厳密に分散されるようにすることができます。厳密な Elastic Container Instance ベースのポッドトポロジスプレッドを有効にすると、kube-scheduler は最初にゾーン A、ゾーン B、ゾーン C のそれぞれにポッドをスケジュールします。kube-scheduler は、スケジュールされたポッドが作成されるまで、保留中のポッドをスケジュールしません。次の図を参照してください。
Pod A1 が作成された場合でも、保留中のポッドはスケジュールされません。これは、ゾーン B またはゾーン C でポッドの作成に失敗した場合、maxSkew パラメーターで指定された制約に違反するためです。Pod B1 が作成されると、kube-scheduler はゾーン C にポッドをスケジュールします。緑色の網掛けが付いたポッドは作成済みです。
厳密な Elastic Container Instance ベースのポッドトポロジスプレッドを無効にする場合は、whenUnsatisfiable パラメーターを ScheduleAnyway に設定します。詳細については、Spread constraint definition を参照してください。