All Products
Search
Document Center

Container Service for Kubernetes:Enable co-scheduling with ack-co-scheduler

Last Updated:Jun 25, 2026

Compared with the native Kubernetes scheduler, ACK extends scheduling with Gang Scheduling, CPU topology-aware scheduling, ECI elastic scheduling, and more. Install the ack-co-scheduler add-on on a registered cluster to use ACK scheduling in your local cluster and improve efficiency for big data, AI, and other compute-intensive workloads.ack-co-scheduler in a registered cluster to enable Gang Scheduling, CPU topology-aware scheduling, and ECI elastic scheduling for compute-intensive workloads.

Prerequisites

Make sure you have:

  • Your self-managed Kubernetes cluster is connected to an ACK One registered cluster.

  • System components at these versions:

    Component Version
    Kubernetes 1.18.8 or later
    Helm 3.0 or later
    Docker 19.03.5
    Operating system CentOS 7.6, CentOS 7.7, Ubuntu 16.04, Ubuntu 18.04, Alibaba Cloud Linux

Usage notes

Set .template.spec.schedulerName to ack-co-scheduler in your job spec to route pods through the ACK co-scheduler instead of the default scheduler.

Install the ack-co-scheduler component

Use onectl for scripted environments. Use the console for a UI-based approach.

Install using onectl

  1. Install onectl on your machine.

  2. Install ack-co-scheduler:

    onectl addon install ack-co-scheduler

    Expected output:

    Addon ack-co-scheduler, version **** installed.

Install using the console

  1. Log on to the Container Service Management Console. In the left navigation pane, click Clusters.

  2. Click the name of your cluster. In the left navigation pane, click Add-ons.

  3. On the Add-ons page, click the Others tab. Find ack-co-scheduler and click Install.

  4. In the dialog box, click OK.

Gang scheduling

Gang scheduling enforces all-or-nothing pod placement: all pods in a group are scheduled together, or none are. This prevents resource deadlocks in distributed jobs such as MPI and AI training, where all workers must run simultaneously.

Submit a TensorFlow distributed job

This example submits a TensorFlow distributed training job with Gang Scheduling. Both PS and Worker pods use pod-group.scheduling.sigs.k8s.io labels to form a pod group.

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: "2"
        spec:
          schedulerName: ack-co-scheduler   # Route pods through the ACK co-scheduler.
          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: '10'
            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: "2"
        spec:
          schedulerName: ack-co-scheduler
          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-cpu:v20171202-bdab599-dirty-284af3
            name: tensorflow
            ports:
            - containerPort: 2222
              name: tfjob-port
            resources:
              limits:
                cpu: 10
            workingDir: /opt/tf-benchmarks/scripts/tf_cnn_benchmarks
          restartPolicy: OnFailure

Key fields:

Field Description
pod-group.scheduling.sigs.k8s.io/name Groups pods into a pod group. Pods with the same name are scheduled together.
pod-group.scheduling.sigs.k8s.io/min-available Minimum pods that must be schedulable before any pod in the group starts. In this example, at least 2 of 5 pods (1 PS + 4 Workers) must be schedulable.
schedulerName: ack-co-scheduler Routes the pod through the ACK co-scheduler. Set this on every pod template in the job.

Verify Gang scheduling

After submitting the job, verify that pods enter a pending state together:

kubectl get pods -l pod-group.scheduling.sigs.k8s.io/name=tf-smoke-gpu

Pods remain in Pending until at least min-available pods are simultaneously schedulable. This is expected. If pods stay pending, check Events for scheduling messages:

kubectl describe pod <pod-name>

See Use Gang scheduling.

CPU topology-aware scheduling

CPU topology-aware scheduling pins container CPU cores to the same Non-Uniform Memory Access (NUMA) node, reducing cross-node memory latency. This benefits CPU-intensive workloads such as real-time inference and latency-sensitive services.

Prerequisites

The resource-controller component is deployed. See Manage add-ons.

Enable CPU topology-aware scheduling

Add the cpuset-scheduler: "true" annotation to your Deployment's pod template and set schedulerName to ack-co-scheduler:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-numa
  labels:
    app: nginx-numa
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-numa
  template:
    metadata:
      annotations:
        cpuset-scheduler: "true"   # Enable CPU topology-aware scheduling.
      labels:
        app: nginx-numa
    spec:
      schedulerName: ack-co-scheduler   # Route pods through the ACK co-scheduler.
      containers:
      - name: nginx-numa
        image: nginx:1.13.3
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 4
          limits:
            cpu: 4

Key fields:

Field Description
cpuset-scheduler: "true" Pins the pod's CPU cores to a single NUMA node. Set under template.metadata.annotations.
schedulerName: ack-co-scheduler Routes the pod through the ACK co-scheduler.
resources.requests.cpu / resources.limits.cpu CPU resource requests and limits for the container.

Verify CPU topology-aware scheduling

Once running, confirm pods were scheduled with cpuset pinning:

kubectl get pods -l app=nginx-numa -o wide

To confirm NUMA pinning, log on to the node and check the container's cpuset:

cat /sys/fs/cgroup/cpuset/kubepods/pod<pod-uid>/<container-id>/cpuset.cpus

If all listed cores belong to the same NUMA node, cpuset pinning is active.

See Enable CPU topology-aware scheduling.

ECI elastic scheduling

ECI elastic scheduling controls whether pods run on Elastic Compute Service (ECS) nodes, Elastic Container Instance (ECI) resources, or burst to ECI only when ECS capacity is insufficient. Use it for workloads with spiky resource demands to avoid over-provisioning ECS nodes.

Prerequisites

The ack-virtual-node component is deployed. See Use ECI in ACK.

Enable ECI elastic scheduling

Add the alibabacloud.com/burst-resource annotation to your Deployment's pod template:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 4
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      name: nginx
      annotations:
        alibabacloud.com/burst-resource: eci   # Use ECI when ECS capacity is insufficient.
      labels:
        app: nginx
    spec:
      schedulerName: ack-co-scheduler   # Route pods through the ACK co-scheduler.
      containers:
      - name: nginx
        image: nginx
        resources:
          limits:
            cpu: 2
          requests:
            cpu: 2

Annotation values for `alibabacloud.com/burst-resource`:

Value Behavior
Not set Use only ECS nodes in the cluster.
eci Use ECS nodes first; burst to ECI when ECS capacity is insufficient.
eci_only Use only ECI resources.

Verify ECI elastic scheduling

After deploying, check which nodes the pods are running on:

kubectl get pods -l app=nginx -o wide

See Use ElasticResource to implement ECI elastic scheduling (deprecated).

Shared GPU scheduling

Shared GPU scheduling lets multiple pods share a single GPU, improving utilization for inference and workloads that do not require a full GPU.

See:

Next steps