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

Container Service for Kubernetes:マルチゾーン間での高速なエラスティックスケーリングの実装

最終更新日:Mar 01, 2026

高可用性アーキテクチャでは、ワークロードを複数のゾーンに均等に分散させることが重要です。本トピックでは、Container Service for Kubernetes (ACK) クラスターにおいて、ack-autoscaling-placeholder コンポーネントを使用して、ゾーンを意識した高速なエラスティックスケーリングを実現する方法について説明します。これにより、スケールアウト時にノードが適切なゾーンに同時に追加されます。

前提条件

仕組み

課題

単一のスケーリンググループ内で複数ゾーンの vSwitch を使用してノードプールを構成すると、Cluster Autoscaler はどのゾーンに新しいノードが必要かを特定できません。その結果、スケールアウトされたインスタンスが特定のゾーンに集中し、他のゾーンには分散されない可能性があります。これではマルチゾーンデプロイメントの目的が達成されません。

image

ソリューション

ACK では、ack-autoscaling-placeholder コンポーネントを使用してこの課題を解決します。このコンポーネントはリソース冗長性を利用して、マルチゾーンのエラスティックスケーリングを、複数のノードプールに対する同時指向性スケーリングに変換します。詳細については、「ack-autoscaling-placeholder を使用して Pod を数秒でスケーリングする」をご参照ください。このメカニズムは以下の 3 段階で動作します。

  1. ゾーンごとにノードプールを作成し、ゾーンラベルを設定します。 各ノードプールには、所属ゾーンを識別するラベルが割り当てられます。

  2. nodeSelector を使用してプレースホルダー Pod をデプロイします。 ack-autoscaling-placeholder コンポーネントは、ゾーンラベルに基づいて各ゾーンにプレースホルダー Pod をスケジュールします。これらのプレースホルダー Pod は、アプリケーション Pod よりも低い重みを持つ PriorityClass を使用します。

  3. アプリケーション Pod がプレースホルダー Pod をプリエンプト(横取り)します。 アプリケーション Pod が Pending 状態になると、既存ノード上の低優先度のプレースホルダー Pod を置き換えます。これにより、置き換えられたプレースホルダー Pod 自体が Pending 状態になります。プレースホルダー Pod は antiAffinity ではなく nodeSelector ベースのスケジューリングを使用しているため、Cluster Autoscaler は各 Pending プレースホルダー Pod が必要とする正確なゾーンを特定し、対応するノードプールに対して同時にスケールアウトをトリガーできます。

スケーリングフロー

次の図は、このアーキテクチャを使用して 2 つのゾーンで同時にスケーリングを行う仕組みを示しています。

image
  1. ack-autoscaling-placeholder コンポーネントが各ゾーンにプレースホルダー Pod を作成します。プレースホルダー Pod は、実際のアプリケーション Pod よりもスケジューリング優先度が低くなっています。

  2. アプリケーション Pod が Pending 状態になると、すぐにプレースホルダー Pod をプリエンプトし、各ゾーンの既存ノード上にデプロイされます。プリエンプトされたプレースホルダー Pod はその後、Pending 状態になります。

  3. プレースホルダー Pod が nodeSelector を使用してスケジュールされているため、Cluster Autoscaler は対応するゾーンに対して同時にスケールアウトを実行できます。

ステップ 1:ゾーンごとのノードプールの作成とカスタムノードラベルの設定

  1. ACK コンソールにログインします。左側のナビゲーションウィンドウで、クラスター をクリックします。

  2. クラスター ページで、管理対象のクラスターを検索し、その名前をクリックします。左側のナビゲーションウィンドウで、ノード > ノードプール を選択します。

  3. ノードプールの作成 をクリックし、画面の指示に従ってノードプールを構成します。この例では、ゾーン I でオートスケーリングを有効にした auto-zone-I という名前のノードプールを作成します。以下の表は重要なパラメーターのみを示しています。詳細については、「ノードプールの作成と管理」をご参照ください。ノードプールリストで auto-zone-I ノードプールのステータスが アクティブ と表示されたら、ノードプールの作成は完了です。

    パラメーター説明
    ノードプール名auto-zone-I
    スケーリングモード自動 を選択してオートスケーリングを有効にします。
    vSwitchゾーン I の vSwitch を選択します。
    ノードラベルキーavailable_zonei に設定します。
  4. 上記の手順を繰り返して、オートスケーリングが必要な各ゾーンに対してオートスケーリングを有効にしたノードプールを作成します。

    Node pools across multiple zones

検証:ノードプールリストで、ゾーンごとのノードプールがすべて アクティブ ステータスであり、ゾーンラベルが正しく適用されていることを確認します。

ステップ 2:ack-autoscaling-placeholder のデプロイとプレースホルダーデプロイメントの構成

コンポーネントのデプロイ

  1. ACK コンソールの左側ナビゲーションウィンドウで、マーケットプレイス > マーケットプレイス を選択します。

  2. ack-autoscaling-placeholder を検索してクリックします。ack-autoscaling-placeholder ページで、デプロイ をクリックします。

  3. クラスター ドロップダウンリストからクラスターを、名前空間 ドロップダウンリストから名前空間を選択し、次へ をクリックします。チャートバージョン ドロップダウンリストからチャートバージョンを選択し、パラメーター を構成して、OK をクリックします。コンポーネントのデプロイ後、左側ナビゲーションウィンドウで アプリケーション > Helm を選択すると、アプリケーションが デプロイ済み 状態であることを確認できます。

プレースホルダーデプロイメントを使用した Helm リリースの更新

  1. 詳細ページの左側ナビゲーションウィンドウで、アプリケーション > Helm を選択します。

  2. Helm ページで、ack-autoscaling-placeholder-default の 操作 列にある 更新 をクリックします。

  3. リリースの更新 パネルで、以下の例に基づいて YAML ファイルを更新し、OK をクリックします。ゾーンごとにプレースホルダーをデプロイし、ゾーンごとにプレースホルダーデプロイメントを定義します。この例では、ゾーン I、K、H にプレースホルダーデプロイメントを作成します。deployments リスト内の各エントリは同じ構造に従います。以下に示す最初のエントリには完全な注釈が付与されていますが、以降のエントリは name および nodeSelector の値のみが異なります。以下の表は、各ゾーンで変更が必要なフィールドをまとめたものです。更新が成功すると、各ゾーン用のプレースホルダーデプロイメントが作成されます。

    フィールドゾーン Iゾーン Kゾーン H
    nameack-place-holder-Iack-place-holder-Kack-place-holder-H
    nodeSelector{"avaliable_zone":i}{"avaliable_zone":k}{"avaliable_zone":h}
       deployments:
       # --- Zone I placeholder ---
       - affinity: {}
         annotations: {}
         containers:
         - image: registry-vpc.cn-beijing.aliyuncs.com/acs/pause:3.1
           imagePullPolicy: IfNotPresent
           name: placeholder
           resources:
             requests:
               cpu: 3500m     # CPU request for each placeholder pod.
               memory: 6      # Memory request for each placeholder pod.
         imagePullSecrets: {}
         labels: {}
         name: ack-place-holder-I             # Deployment name. Use a unique suffix per zone.
         nodeSelector: {"avaliable_zone":i}   # Must match the node label key and value from Step 1.
         replicaCount: 10                     # Number of placeholder pods per zone.
         tolerations: []
    
       # --- Zone K placeholder (same structure, different zone) ---
       - affinity: {}
         annotations: {}
         containers:
         - image: registry-vpc.cn-beijing.aliyuncs.com/acs/pause:3.1
           imagePullPolicy: IfNotPresent
           name: placeholder
           resources:
             requests:
               cpu: 3500m
               memory: 6
         imagePullSecrets: {}
         labels: {}
         name: ack-place-holder-K
         nodeSelector: {"avaliable_zone":k}
         replicaCount: 10
         tolerations: []
    
       # --- Zone H placeholder (same structure, different zone) ---
       - affinity: {}
         annotations: {}
         containers:
         - image: registry-vpc.cn-beijing.aliyuncs.com/acs/pause:3.1
           imagePullPolicy: IfNotPresent
           name: placeholder
           resources:
             requests:
               cpu: 3500m
               memory: 6
         imagePullSecrets: {}
         labels: {}
         name: ack-place-holder-H
         nodeSelector: {"avaliable_zone":h}
         replicaCount: 10
         tolerations: []
    
       fullnameOverride: ""
       nameOverride: ""
       podSecurityContext: {}
       priorityClassDefault:
         enabled: true
         name: default-priority-class
         value: -1

    Placeholder Deployments created

検証アプリケーション > Helm を選択し、ack-autoscaling-placeholder-default が更新済みの構成で デプロイ済み 状態であることを確認します。

ステップ 3:ワークロード用の PriorityClass の作成

ワークロードの PriorityClass は、プレースホルダーの PriorityClass (-1) よりも高い値を持つ必要があります。これにより、アプリケーション Pod がプレースホルダー Pod をプリエンプトできます。以下の 2 つのオプションがあります。

  • オプション A:名前付き PriorityClasspriorityClassName を介して特定のワークロードに明示的に割り当てます。

  • オプション B:グローバル PriorityClass — PriorityClass を指定しないすべての Pod に自動的に適用されます。

オプション A:名前付き PriorityClass

  1. priorityClass.yaml という名前のファイルを作成し、以下の内容をコピーします。

       apiVersion: scheduling.k8s.io/v1
       kind: PriorityClass
       metadata:
         name: high-priority
       value: 1000000              # The priority value. Must be higher than the default priority value (-1) of the placeholder pods created in Step 2.
       globalDefault: false
       description: "This priority class should be used for XYZ service pods only."

オプション B:グローバル PriorityClass

各 Pod ごとに個別の PriorityClass が必要ない場合は、グローバル PriorityClass をデフォルトとして構成できます。これが有効になると、PriorityClass を指定していない Pod は自動的にこの優先度値を採用し、プリエンプションが自動的に有効になります。

   apiVersion: scheduling.k8s.io/v1
   kind: PriorityClass
   metadata:
     name: global-high-priority
   value: 1                              # The priority value. Must be higher than the default priority value (-1) of the placeholder pods created in Step 2.
   globalDefault: true
   description: "This priority class should be used for XYZ service pods only."

PriorityClass の適用

  1. PriorityClass を作成します。期待される出力:

       kubectl apply -f priorityClass.yaml
       priorityclass.scheduling.k8s.io/high-priority created
検証kubectl get priorityclass を実行し、high-priority(または global-high-priority)が正しい優先度値とともにリストに表示されることを確認します。

ステップ 4:ワークロードの作成

この例ではゾーン I を使用します。

  1. workload.yaml という名前のファイルを作成し、以下の内容をコピーします。

       apiVersion: apps/v1
       kind: Deployment
       metadata:
         name: placeholder-test
         labels:
           app: nginx
       spec:
         replicas: 1
         selector:
           matchLabels:
             app: nginx
         template:
           metadata:
             labels:
               app: nginx
           spec:
             nodeSelector:                        # Rules used to select nodes.
               avaliable_zone: "i"
             priorityClassName: high-priority     # The PriorityClass configured in Step 3. Optional if global configuration is enabled.
             containers:
             - name: nginx
               image: nginx:1.7.9
               ports:
               - containerPort: 80
               resources:
                 requests:
                   cpu: 3                         # The resource request of the workload.
                   memory: 5
  2. ワークロードをデプロイします。期待される出力:デプロイ後、ワークロード > Pod ページで、ワークロードの PriorityClass がプレースホルダー Pod の PriorityClass よりも高いことを確認できます。プレースホルダー Pod はスケールアウトされたノード上で実行され、Cluster Autoscaler による同時スケーリングをトリガーして、次のワークロードスケーリングイベントに備えます。ノード > ノード を選択すると、ノードページでワークロード Pod が以前プレースホルダー Pod をホストしていたノード上で実行されていることを確認できます。

       kubectl apply -f workload.yaml
       deployment.apps/placeholder-test created

    Workload deployed

    Workload pod placement

検証ワークロード > Pod ページで、ワークロード Pod が Running 状態であり、置き換えられたプレースホルダー Pod が正しいゾーンでノードのスケールアウトをトリガーしたことを確認します。