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

Container Service for Kubernetes:ギャングスケジューリングの使用

最終更新日:Jun 19, 2026

分散ジョブで必要な Pod をすべて同時に起動するか、または 1 つも起動しないようにしてデッドロックを防止します。

仕組み

ACK は、PodGroup リソースを使用してギャングスケジューリングを実装します。各ポッドは、最小ポッド数 (min-available) が指定された PodGroup に割り当てられます。スケジューラは、最小数が満たされるまでグループを保留状態に保持し、その後すべてのポッドをまとめてディスパッチします。

ACK は PodGroup を定義する 3 つの方法をサポートしています:

方法 Pod のグルーピング方法 最適な用途
ラベル kube-scheduler が PodGroup を自動作成 シンプルなジョブ。個別の PodGroup オブジェクトが不要
PodGroup CRD タイムアウト制御を備えた明示的な PodGroup リソース scheduleTimeoutSeconds が必要なジョブ
Koordinator アノテーション アノテーションベースのグルーピング Koordinator のスケジューリングスタックを使用するクラスター

すべての方法で、Pod とその PodGroup は同じ名前空間に存在する必要があります。また、PodGroup 内のすべての Pod は同じ優先度を共有する必要があります。

前提条件

開始する前に、次の要件が満たされていることを確認してください:

弾性ノードプールに十分な最大リソースキャパシティと、Pod のスケジューリングに一致するノードラベルがあることを確認してください。そうしないと、弾性ノードプールによってスケールアウトされたノードを Pod が使用できない場合があります。

ギャングスケジューリングの有効化

方法 1:ラベル (推奨)

各ポッドに 2 つのラベルを追加します。kube-scheduler は、pod-group.scheduling.sigs.k8s.io/name の値を名前とする PodGroup を自動的に作成します。

labels:
  pod-group.scheduling.sigs.k8s.io/name: tf-smoke-gpu       # PodGroup名 (有効な DNS サブドメインである必要があります)
  pod-group.scheduling.sigs.k8s.io/min-available: "3"       # ジョブの開始に必要な最小Pod数

pod-group.scheduling.sigs.k8s.io/name の値は、有効な DNS サブドメイン名 である必要があります。

方法 2:PodGroup CRD

PodGroup リソースを作成し、その後、各 Pod からラベルで参照します。

重要

ACK 1.31 以降、scheduling.x-k8s.io/v1alpha1 のみがサポートされています。scheduling.sigs.k8s.io/v1alpha1 はサポートされなくなりました。

# PodGroupリソース
apiVersion: scheduling.x-k8s.io/v1alpha1
kind: PodGroup
metadata:
  name: nginx
spec:
  scheduleTimeoutSeconds: 10   # min-availableが満たされない場合にグループを拒否するまでの待機秒数
  minMember: 3                 # ジョブの開始に必要な最小Pod数
---
# Podラベル — PodGroupの名前と名前空間に一致する必要があります
labels:
  pod-group.scheduling.sigs.k8s.io/name: nginx

方法 3:Koordinator アノテーション

各ポッドにアノテーションを追加します。この方法では、Koordinator API の total-number または mode パラメーターをサポートしていません。

annotations:
  gang.scheduling.koordinator.sh/name: "gang-example"
  gang.scheduling.koordinator.sh/min-available: "2"

高度な構成

複数ギャングのグルーピング (GangGroup)

パラメーターサーバーとワーカーを持つ PyTorch ジョブのように、ジョブによってはロールごとに異なる min-available 要件を持つものがあります。単一の PodGroup ではロールごとの最小要件を表現できず、個別の PodGroup ではロール間で連携できません。

GangGroup は複数の PodGroup をリンクします。ジョブは、すべての gang がそれぞれの min-available を満たした場合にのみ開始されます。各 pod または PodGroup に次のラベルを追加します (Koordinator メソッドの場合はアノテーションキーを使用します):

方法 リソース キー
ラベル Pod pod-group.scheduling.sigs.k8s.io/groups
PodGroup CRD PodGroup pod-group.scheduling.sigs.k8s.io/groups
Koordinator アノテーション Pod gang.scheduling.koordinator.sh/groups

値の例 (<namespace>/<gang-name> エントリの JSON 配列):

pod-group.scheduling.sigs.k8s.io/groups: "[\"default/gang-example1\", \"default/gang-example2\"]"
GangGroup には、kube-scheduler のバージョンが 1.xx.xx-aliyun-4.0 より後である、バージョン 1.22 以降の Kubernetes が必要です。

マッチポリシーの設定

デフォルトでは、PodGroup はリソースの事前割り当てが完了したポッド (only-waiting) のみをカウントします。match-policy を使用すると、たとえば前のサイクルのポッドがまだ実行中である場合などに、他の状態のポッドを最小数に含めることができます。

ラベルを各 Pod (ラベルメソッド) または PodGroup リソース (PodGroup CRD メソッド) に追加します。Koordinator アノテーションメソッドは once-satisfied のみをサポートします。

マッチポリシー min-available にカウントされる Pod 使用する場面
only-waiting リソースの事前割り当てを完了した Pod 最も厳格です。前サイクルからの持ち越しがないステートレスジョブで使用します。
waiting-and-running Running 状態の Pod + 事前割り当てを完了した Pod 前サイクルの実行中 Pod も最小数に含める必要がある場合に使用します。
waiting-running-succeed Succeeded 状態の Pod + Running + 事前割り当てを完了した Pod 部分的な再起動を許容するジョブで使用します。すでに成功した Pod もカウントされます。
once-satisfied リソースの事前割り当てを完了した Pod。満たされた時点で PodGroup は無効になります ワンショットジョブで使用します。ギャングがディスパッチされた後、PodGroup は無効化されます。

ラベル方式の例:

pod-group.scheduling.sigs.k8s.io/match-policy: "waiting-and-running"

PodGroup CRD の例 (Pod ではなく PodGroup に追加します):

pod-group.scheduling.sigs.k8s.io/match-policy: "waiting-and-running"
マッチポリシー設定には、Kubernetes 1.22 以降、およびバージョンが 1.xx.xx-aliyun-4.0 より後の kube-scheduler が必要です。

例:分散 TensorFlow ジョブ

この例では、ギャングスケジューリングを使用する場合と使用しない場合の分散 TensorFlow ジョブを比較します。クラスターには GPU が 4 つあります。ジョブには PS Pod が 1 つと worker Pod が 4 つあり、各 worker は GPU を 2 つ必要とします。min-available は 5 に設定されています。

手順 1: Arena をインストールし、TensorFlow ジョブ用にクラスターを準備します。

Arena は Kubeflow のサブプロジェクトであり、環境セットアップ、データ準備、モデル開発、トレーニング、予測など、機械学習ジョブのライフサイクルを CLI または SDK で管理します。

ステップ 2: TensorFlow ジョブを送信します。PS とワーカーの両方のテンプレートには、min-available: "5" というギャングスケジューリングラベルが含まれています。

apiVersion: "kubeflow.org/v1"
kind: "TFJob"
metadata:
  name: "tf-smoke-gpu"
spec:
  tfReplicaSpecs:
    PS:
      replicas: 1
      template:
        metadata:
          creationTimestamp: null
          labels:
            pod-group.scheduling.sigs.k8s.io/name: tf-smoke-gpu
            pod-group.scheduling.sigs.k8s.io/min-available: "5"
        spec:
          containers:
          - args:
            - python
            - tf_cnn_benchmarks.py
            - --batch_size=32
            - --model=resnet50
            - --variable_update=parameter_server
            - --flush_stdout=true
            - --num_gpus=1
            - --local_parameter_device=cpu
            - --device=cpu
            - --data_format=NHWC
            image: registry.cn-hangzhou.aliyuncs.com/kubeflow-images-public/tf-benchmarks-cpu:v20171202-bdab599-dirty-284af3
            name: tensorflow
            ports:
            - containerPort: 2222
              name: tfjob-port
            resources:
              limits:
                cpu: '1'
            workingDir: /opt/tf-benchmarks/scripts/tf_cnn_benchmarks
          restartPolicy: OnFailure
    Worker:
      replicas: 4
      template:
        metadata:
          creationTimestamp: null
          labels:
            pod-group.scheduling.sigs.k8s.io/name: tf-smoke-gpu
            pod-group.scheduling.sigs.k8s.io/min-available: "5"
        spec:
          containers:
          - args:
            - python
            - tf_cnn_benchmarks.py
            - --batch_size=32
            - --model=resnet50
            - --variable_update=parameter_server
            - --flush_stdout=true
            - --num_gpus=2
            - --local_parameter_device=cpu
            - --device=gpu
            - --data_format=NHWC
            image: registry.cn-hangzhou.aliyuncs.com/kubeflow-images-public/tf-benchmarks-gpu:v20171202-bdab599-dirty-284af3
            name: tensorflow
            ports:
            - containerPort: 2222
              name: tfjob-port
            resources:
              limits:
                nvidia.com/gpu: 2
            workingDir: /opt/tf-benchmarks/scripts/tf_cnn_benchmarks
          restartPolicy: OnFailure

ギャングスケジューリングを有効にしない場合:

Pod のステータスを確認します:

kubectl get pods

GPU が 4 つしかないため、worker が 2 つ Running になってすべての GPU を確保します。残りの 2 つは Pending のままとなり、ジョブがブロックされます:

NAME                    READY   STATUS    RESTARTS   AGE
tf-smoke-gpu-ps-0       1/1     Running   0          6m43s
tf-smoke-gpu-worker-0   1/1     Running   0          6m43s
tf-smoke-gpu-worker-1   1/1     Running   0          6m43s
tf-smoke-gpu-worker-2   0/1     Pending   0          6m43s
tf-smoke-gpu-worker-3   0/1     Pending   0          6m43s

実行中の worker のログを確認します:

kubectl logs -f tf-smoke-gpu-worker-0

worker は Pending の Pod を待って待機します。GPU は確保されたままで、トレーニングは実行されません:

INFO|2020-05-19T07:02:18|/opt/launcher.py|27| 2020-05-19 07:02:18.199696: I tensorflow/core/distributed_runtime/master.cc:221] CreateSession still waiting for response from worker: /job:worker/replica:0/task:3
INFO|2020-05-19T07:02:28|/opt/launcher.py|27| 2020-05-19 07:02:28.199798: I tensorflow/core/distributed_runtime/master.cc:221] CreateSession still waiting for response from worker: /job:worker/replica:0/task:2

ギャングスケジューリングを有効にした場合:

クラスターが min-available: 5 を満たすのに十分なリソースを確保するまで、5 つのポッドはすべて Pending 状態のままになります:

NAME                    READY   STATUS    RESTARTS   AGE
tf-smoke-gpu-ps-0       0/1     Pending   0          43s
tf-smoke-gpu-worker-0   0/1     Pending   0          43s
tf-smoke-gpu-worker-1   0/1     Pending   0          43s
tf-smoke-gpu-worker-2   0/1     Pending   0          43s
tf-smoke-gpu-worker-3   0/1     Pending   0          43s

クラスターに GPU を 4 つ追加すると、スケジューラーが 5 つの Pod を同時にディスパッチします:

kubectl get pods

想定される出力:

NAME                    READY   STATUS    RESTARTS   AGE
tf-smoke-gpu-ps-0       1/1     Running   0          3m16s
tf-smoke-gpu-worker-0   1/1     Running   0          3m16s
tf-smoke-gpu-worker-1   1/1     Running   0          3m16s
tf-smoke-gpu-worker-2   1/1     Running   0          3m16s
tf-smoke-gpu-worker-3   1/1     Running   0          3m16s

worker のログを確認し、トレーニングが開始されたことを確認します:

kubectl logs -f tf-smoke-gpu-worker-0

想定される出力:

INFO|2020-05-19T07:15:24|/opt/launcher.py|27| Running warm up
INFO|2020-05-19T07:21:04|/opt/launcher.py|27| Done warm up
INFO|2020-05-19T07:21:04|/opt/launcher.py|27| Step  Img/sec loss
INFO|2020-05-19T07:21:05|/opt/launcher.py|27| 1 images/sec: 31.6 +/- 0.0 (jitter = 0.0) 8.318
INFO|2020-05-19T07:21:15|/opt/launcher.py|27| 10  images/sec: 31.1 +/- 0.4 (jitter = 0.7) 8.343
INFO|2020-05-19T07:21:25|/opt/launcher.py|27| 20  images/sec: 31.5 +/- 0.3 (jitter = 0.7) 8.142

トラブルシューティング

エラー: "rejected by podgroup xxx"

複数の PodGroup が存在する場合、kube-scheduler のバックオフキューは、あるサイクルで事前割り当てを完了した Pod を、後続の PodGroup の処理時に拒否することがあります。

これは想定どおりの動作です。20 分以内に解消する場合は、このエラーを無視してください。解消しない場合は、チケットを送信してください。

次のステップ