すべてのプロダクト
Search
ドキュメントセンター

Container Service for Kubernetes:Elastic Container Instanceベースのポッドをゾーン間で拡散し、アフィニティを設定する

最終更新日:Nov 14, 2024

高可用性と高性能は、分散ジョブに不可欠です。 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ベースのポッドは、nodeAffinitypodAffinity、および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ベースのポッドをゾーン全体に拡散する

  1. トポロジ拡散制約をワークロードの構成に追加します。

    次の手順を実行して、ポッドの構成の [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テンプレートを示しています。

    YAMLコンテンツの表示

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: with-pod-topology-spread
      labels:
        app: with-pod-topology-spread
    spec:
      replicas: 10
      selector:
        matchLabels:
          app: with-pod-topology-spread
      template:
        metadata:
          labels:
            app: with-pod-topology-spread
        spec:
          affinity:
            nodeAffinity:
              preferredDuringSchedulingIgnoredDuringExecution:
              - weight: 1
                preference:
                  matchExpressions:
                  - key: type
                    operator: NotIn
                    values:
                    - virtual-kubelet
          topologySpreadConstraints:
            - maxSkew: 1
              topologyKey: topology.kubernetes.io/zone
              whenUnsatisfiable: DoNotSchedule
              labelSelector:
                matchLabels:
                  app: with-pod-topology-spread
          tolerations:
            - key: "virtual-kubelet.io/provider"
              operator: "Exists"
              effect: "NoSchedule"
          containers:
          - name: with-pod-topology-spread
            image: registry.k8s.io/pause:2.0
            resources:
              requests:
                cpu: "1"
                memory: "256Mi"

    パラメーター

    説明

    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ベースの仮想ノードの汚染を許容する許容範囲をポッドに追加する必要があります。

  2. ワークロードを作成します。

    deployment.yamlという名前のファイルを作成し、上記のYAMLテンプレートをファイルにコピーします。 次に、次のコマンドを実行して、クラスターにデプロイを作成します。

    kubectl apply -f deployment.yaml
  3. ワークロードのスケジューリング結果を確認します。

    • 次のコマンドを実行して、デプロイがポッドをデプロイするノードを照会します。

      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. ワークロードの構成にアフィニティを追加します。

    この例では、ポッドが1つのゾーンにデプロイされているDeploymentが作成されます。 次のコードブロックは、デプロイのYAMLテンプレートを示しています。

    YAMLコンテンツの表示

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: with-affinity
      labels:
        app: with-affinity
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: with-affinity
      template:
        metadata:
          labels:
            app: with-affinity
        spec:
          affinity:
            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
          tolerations:
            - key: "virtual-kubelet.io/provider"
              operator: "Exists"
              effect: "NoSchedule"
          containers:
          - name: with-affinity
            image: registry.k8s.io/pause:2.0

    パラメーター

    説明

    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
  2. ワークロードを作成します。

    deployment.yamlという名前のファイルを作成し、上記のYAMLテンプレートをファイルにコピーします。 次に、次のコマンドを実行して、クラスターにデプロイを作成します。

    kubectl apply -f deployment.yaml
  3. ワークロードのスケジューリング結果を確認します。

    • 次のコマンドを実行して、デプロイがポッドをデプロイするノードを照会します。

      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を使用します。

image

ゾーン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は保留中のポッドをスケジュールしません。

image

ポッドA1が作成されても、保留中のポッドはスケジュールされません。 これは、ゾーンBまたはゾーンCのポッドの作成に失敗した場合、maxSkewパラメーターで指定された制約に違反するためです。 ポッドB1が作成された後、kube-schedulerはポッドをゾーンCにスケジュールします。緑のシェーディングを持つポッドが作成されます。

image

厳格なElastic Container Instanceベースのポッドトポロジスプレッドを無効にする場合は、whenUnsatisfiableパラメーターをScheduleAnywayに設定します。 詳細については、次をご参照ください: スプレッド制約の定義