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

Container Service for Kubernetes:ゾーン全体に Elastic Container Instance ベースのポッドを分散し、アフィニティを構成する

最終更新日:Apr 26, 2025

高可用性と高パフォーマンスは、分散ジョブにとって不可欠です。ACK マネージド Pro クラスタでは、Kubernetes ネイティブのスケジューリングセマンティクスを使用して、高可用性のためにゾーン全体に分散ジョブを分散できます。また、Kubernetes ネイティブのスケジューリングセマンティクスを使用して、高可用性と高パフォーマンスのためにアフィニティ設定に基づいて特定のゾーンに Elastic Container Instance ベースのポッドをデプロイすることもできます。

前提条件

  • ACK Serverless Pro クラスタが作成されており、クラスタが次の要件を満たしていること。

  • ポッドを複数のゾーンにスケジュールできるように、eci-profile で複数のゾーン(vSwitch)が指定されている。詳細については、「eci-profile を構成する」をご参照ください。

  • スケジュールするポッドに対して nodeAffinitypodAffinitytopologySpreadConstraints パラメーターが構成されているか、ポッドが既存のリソースポリシーと一致していることを確認します。

    説明

    詳細については、「クイックスタート: PHP を使用して BLOB をアップロード、ダウンロード、一覧表示する」をご参照ください。

    ARM ベースの仮想ノードにポッドをスケジュールする場合は、ポッド構成の tolerations パラメーターで、仮想ノードの taint を許容するように指定します。

前提条件

  • 次の要件を満たす ACK マネージド Pro クラスタ が作成されていること。

  • Elastic Container Instance ベースのポッドを構成する際に、対応する eci-profile で複数のゾーン(vSwitch)が指定されている。

  • nodeAffinitypodAffinitytopologySpreadConstraints フィールドがポッド構成で指定されている。または、ポッドに 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 ベースのポッドを分散する

  1. ワークロードの構成にトポロジスプレッド制約を追加します。

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

    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

    この構成では、ポッドが優先的に 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 をポッドに追加する必要があります。

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

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

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

    • 次のコマンドを実行して、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: ポッドアフィニティとノードアフィニティを構成して、特定のゾーンにポッドをデプロイする

  1. ワークロードの構成にアフィニティを追加します。

    この例では、ポッドが単一ゾーンにデプロイされる Deployment を作成します。次のコードブロックは、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

    この構成では、すべてのポッドが単一ゾーンにデプロイされるように指定しています。

    パラメーターの詳細については、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
  2. ワークロードを作成します。

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

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

    • 次のコマンドを実行して、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 を参照してください。