Todos los productos
Search
Centro de documentos

Container Service for Kubernetes:Use Gang scheduling

Última actualización: Sep 21, 2026

Evite los bloqueos en los trabajos distribuidos. Para ello, asegúrese de que todos los pods obligatorios se inicien al mismo tiempo o que no se inicie ninguno.

Funcionamiento

ACK implementa gang scheduling mediante un resource PodGroup. Cada pod se asigna a un PodGroup con una cantidad mínima de pods (min-available). El programador mantiene el grupo en estado Pending hasta que se cumple este mínimo y luego despacha todos los pods juntos.

ACK admite tres métodos para definir un PodGroup:

Método

Agrupación de pods

Recomendado para

Etiquetas

kube-scheduler crea automáticamente un PodGroup

Trabajos sencillos donde no se requiere un objeto PodGroup independiente

CRD PodGroup

Resource PodGroup explícito con control de tiempo de espera

Trabajos que necesitan scheduleTimeoutSeconds

Anotaciones de Koordinator

Agrupación basada en anotaciones

Clústeres que usan la pila de programación de Koordinator

En todos los casos, los pods y su PodGroup deben residir en el mismo namespace. Además, todos los pods de un PodGroup deben compartir la misma prioridad.

Requisitos previos

Antes de empezar, asegúrese de contar con lo siguiente:

  • Un ACK managed Pro cluster que ejecute Kubernetes 1.16 o posterior. Si es necesario, Upgrade the cluster.

  • Para configuraciones avanzadas (GangGroup y match policy): un clúster que ejecute Kubernetes 1.22 o posterior, con una versión de kube-scheduler superior a 1.xx.xx-aliyun-4.0.

Asegúrese de que el node pool elástico tenga suficiente capacidad máxima de recursos y etiquetas de nodo coincidentes para la programación de pods. De lo contrario, los pods podrían no utilizar los nodos escalados horizontalmente por dicho node pool.

Habilitar gang scheduling

Método 1: etiquetas (recomendado)

Agregue dos etiquetas a cada pod. kube-scheduler crea automáticamente un PodGroup cuyo nombre corresponde al valor de pod-group.scheduling.sigs.k8s.io/name.

labels:
  pod-group.scheduling.sigs.k8s.io/name: tf-smoke-gpu       # PodGroup name (must be a valid DNS subdomain)
  pod-group.scheduling.sigs.k8s.io/min-available: "3"       # Minimum pods required to start the job

El valor de pod-group.scheduling.sigs.k8s.io/name debe ser un nombre de subdominio DNS válido.

Método 2: CRD PodGroup

Cree un resource PodGroup y luego haga referencia a él desde cada pod mediante una etiqueta.

Importante

Desde ACK 1.31, solo se admite scheduling.x-k8s.io/v1alpha1. La versión scheduling.sigs.k8s.io/v1alpha1 ya no es compatible.

# PodGroup resource
apiVersion: scheduling.x-k8s.io/v1alpha1
kind: PodGroup
metadata:
  name: nginx
spec:
  scheduleTimeoutSeconds: 10   # Seconds to wait before rejecting the group if min-available is not met
  minMember: 3                 # Minimum number of pods required to start the job
---
# Pod label — must match the PodGroup name and namespace
labels:
  pod-group.scheduling.sigs.k8s.io/name: nginx

Método 3: anotaciones de Koordinator

Agregue anotaciones a cada pod. Este método no admite los parámetros total-number ni mode de la API de Koordinator.

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

Configuraciones avanzadas

Agrupar varios gangs (GangGroup)

Algunos trabajos tienen roles con distintos requisitos de min-available. Por ejemplo, los trabajos de PyTorch con un servidor de parámetros y workers. Un solo PodGroup no permite expresar mínimos por rol, mientras que varios PodGroups independientes no pueden coordinarse entre sí.

GangGroup vincula varios PodGroups. El trabajo se inicia únicamente cuando cada gang cumple su propio min-available. Agregue la siguiente etiqueta a cada pod o PodGroup. Si utiliza el método de Koordinator, use la clave de anotación correspondiente:

Método

Resource

Clave

Etiquetas

Pod

pod-group.scheduling.sigs.k8s.io/groups

CRD PodGroup

PodGroup

pod-group.scheduling.sigs.k8s.io/groups

Anotaciones de Koordinator

Pod

gang.scheduling.koordinator.sh/groups

Ejemplo de valor (una matriz JSON con entradas <namespace>/<gang-name>):

pod-group.scheduling.sigs.k8s.io/groups: "[\"default/gang-example1\", \"default/gang-example2\"]"
GangGroup requiere Kubernetes 1.22 o posterior, con una versión de kube-scheduler superior a 1.xx.xx-aliyun-4.0 .

Configurar la match policy

De forma predeterminada, un PodGroup solo cuenta los pods que completaron la preasignación de recursos (only-waiting). Utilice match-policy para incluir pods en otros estados dentro del mínimo. Esto resulta útil, por ejemplo, cuando aún se están ejecutando pods de un ciclo anterior.

Agregue la etiqueta a cada pod (método de etiquetas) o al resource PodGroup (método de CRD PodGroup). El método de anotaciones de Koordinator solo admite once-satisfied.

Match policy

Pods contados para min-available

Cuándo usarla

only-waiting

Pods que completaron la preasignación de recursos

Es la opción más estricta. Úsela para trabajos sin estado que no heredan pods de ciclos anteriores.

waiting-and-running

Pods en estado Running y pods que completaron la preasignación

Úsela cuando los pods en ejecución de un ciclo anterior deban contar para el mínimo.

waiting-running-succeed

Pods en estado Succeeded, Running y con preasignación completada

Úsela para trabajos que toleran reinicios parciales, donde los pods ya finalizados siguen contando.

once-satisfied

Pods que completaron la preasignación de recursos; el PodGroup deja de ser válido una vez satisfecho

Úsela para trabajos de una sola ejecución. Una vez despachado el gang, el PodGroup se invalida.

Ejemplo con el método de etiquetas:

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

Ejemplo con el método de CRD PodGroup (agréguelo al PodGroup, no al pod):

pod-group.scheduling.sigs.k8s.io/match-policy: "waiting-and-running"
La configuración de match policy requiere Kubernetes 1.22 o posterior, con una versión de kube-scheduler superior a 1.xx.xx-aliyun-4.0 .

Ejemplo: trabajo distribuido de TensorFlow

Este ejemplo compara un trabajo distribuido de TensorFlow con y sin gang scheduling. El clúster tiene 4 GPU. El trabajo consta de 1 pod PS y 4 pods worker, cada uno con un requerimiento de 2 GPU y un valor de min-available establecido en 5.

Paso 1: Install Arena y prepare el clúster para los trabajos de TensorFlow.

Arena es un subproyecto de Kubeflow diseñado para gestionar el ciclo de vida de los trabajos de aprendizaje automático. Permite configurar el entorno, preparar datos, desarrollar modelos, entrenarlos y ejecutar predicciones mediante una CLI o un SDK.

Paso 2: Envíe el trabajo de TensorFlow. Las plantillas de PS y de worker incluyen las etiquetas de gang scheduling con 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=1
            - --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

Sin gang scheduling habilitado:

Compruebe el estado de los pods:

kubectl get pods

Como solo hay 4 GPU disponibles, 2 workers pasan al estado Running y consumen todas las GPU. Los 2 restantes permanecen en Pending y bloquean el trabajo:

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

Revise los registros de un worker en ejecución:

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

Los workers se detienen porque esperan a los pods en estado Pending. Las GPU quedan retenidas y el entrenamiento no avanza:

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

Con gang scheduling habilitado:

Los 5 pods permanecen en estado Pending hasta que el clúster cuenta con recursos suficientes para cumplir min-available: 5:

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

Una vez que se agregan 4 GPU al clúster, el programador despacha los 5 pods de manera simultánea:

kubectl get pods

Resultado esperado:

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

Revise el registro del worker para confirmar que el entrenamiento comenzó:

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

Resultado esperado:

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

Solución de problemas

Error: "rejected by podgroup xxx"

Cuando existen varios PodGroups, la cola de retroceso de kube-scheduler puede rechazar pods que completaron la preasignación en un ciclo si después se procesan otros PodGroups.

Este comportamiento es normal. Ignore el error si se resuelve en menos de 20 minutos. Si persiste, envíe un ticket.

Siguientes pasos