使用Gang Scheduling

ACS为作业调度场景提供了Gang Scheduling能力,满足作业调度场景All-or-Nothing需求。本文介绍如何使用Gang Scheduling。

前提条件

  • 已开通ACS集群。

  • 已安装kube-scheduler组件。具体信息,请参见kube-scheduler

  • Gang Scheduling仅支持GPU型计算类。具体信息,请参见计算类型定义

功能介绍

作业(Job)一般会创建多个Pod,并且这些Pod需要协调一致地启动运行。这要求在调度时一定要按照一组Pod分配资源,保障这一组Pod都可以申请到资源,或者一旦有一个Pod拿不到资源就认为整组Pod调度失败。这也就是调度器需要提供的All-or-Nothing调度语义,可以避免多个作业因为资源竞争出现资源维度的死锁现象。

ACS内置的调度器提供了Gang Scheduling能力实现了All-or-Nothing语义,保障作业顺利运行。

重要

Gang Scheduling对应的一组Pod必须属于相同的compute-class。

使用方式

ACS提供的Gang Scheduling兼容Kubernetes社区自定义资源PodGroup,对应版本podgroups.scheduling.sigs.k8s.io/v1alpha1。您在提交每一个作业前,需要先在作业所属的命名空间下创建一个PodGroup实例,并在该PodGroup实例中声明保证作业正常运行需要的最小Pod个数(minMember)。之后在创建作业的Pod时通过设置labels的形式配置Pod-group.scheduling.sigs.k8s.io关联PodGroup实例名。ACS在调度时会统一为使用相同PodGroup标签的实例Pod调度分配资源。

  1. 创建对应的PodGroup自定义资源。

    apiVersion: scheduling.sigs.k8s.io/v1alpha1
    kind: PodGroup
    metadata: 
      name: demo-job-podgroup
      namespace: default
    spec: 
      scheduleTimeoutSeconds: 10 
      minMember: 3 # 设置最小运行个数
  2. 创建一个作业,并关联PodGroup。

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: gang-job
      namespace: default
    spec:
      parallelism: 3 # Pod数量必须大于或者等于 pod group对象中的minMember
      template:
        metadata:
          labels:
            alibabacloud.com/compute-class: "gpu" # 指定compute class为gpu
            alibabacloud.com/gpu-model-series: "example-model" # gpu计算类需要指定GPU型号
            pod-group.scheduling.sigs.k8s.io: demo-job-podgroup # 关联 PodGroup 实例 demo-job-podgroup
        spec:
          containers:
          - name: demo-job
            image: registry.cn-hangzhou.aliyuncs.com/acs/stress:v1.0.4
            args:
              - 'infinity'
            command:
              - sleep
            resources:
              requests:
                cpu: "1"
                memory: "1Gi"
                nvidia.com/gpu: "1"
              limits:
                cpu: "1"
                memory: "1Gi"
                nvidia.com/gpu: "1"
          restartPolicy: Never
      backoffLimit: 4
重要

请您确保关联的Pod数量一定大于或等于PodGroup实例配置的minMember,否则无法调度成功。

操作示例

本示例依次演示作业在使用Gang Scheduling时调度失败和调度成功的效果。

  1. 执行以下命令创建test-gangNamespace。

    kubectl create ns test-gang
  2. 执行以下命令,在test-gang命名空间下创建ResourceQuota,演示资源不足情况下的Gang Scheduling效果。

    cat << EOF | kubectl apply -f -
    apiVersion: v1
    kind: ResourceQuota
    metadata:
      name: object-counts
      namespace: test-gang
    spec:
      hard:
        pods: "2"
    EOF
  3. 执行以下命令,创建PodGroup对象,其中指定了minMember为3,表示关联的Pod中至少要有3个Pod同时调度成功,如果其中一个没有创建或者没有调度成功,其他Pod也应该处于 Pending 状态。

    cat << EOF | kubectl apply -f -
    apiVersion: scheduling.sigs.k8s.io/v1alpha1
    kind: PodGroup
    metadata: 
      name: demo-job-podgroup
      namespace: test-gang
    spec: 
      minMember: 3 # 设置最小运行个数
    EOF
  4. 使用以下YAML内容,创建gang-job.yaml文件。该文件描述了一个Job对象,其中指定了4个Pod副本,并关联了PodGroup对象。

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: gang-job
      namespace: test-gang
    spec:
      parallelism: 4 # Pod数量必须大于或者等于 pod group对象中的minMember
      template:
        metadata:
          labels:
            alibabacloud.com/compute-class: "gpu" # 指定compute class为gpu,
            alibabacloud.com/gpu-model-series: "example-model" # gpu计算类需要指定GPU型号
            pod-group.scheduling.sigs.k8s.io: demo-job-podgroup # 关联 PodGroup 实例 demo-job-podgroup
        spec:
          containers:
          - name: demo-job
            image: registry.cn-hangzhou.aliyuncs.com/acs/stress:v1.0.4
            args:
              - 'infinity'
            command:
              - sleep
            resources:
              requests:
                cpu: "1"
                memory: "1Gi"
                nvidia.com/gpu: "1"
              limits:
                cpu: "1"
                memory: "1Gi"
                nvidia.com/gpu: "1"
          restartPolicy: Never
      backoffLimit: 4
  5. 执行以下命令,将gang-job部署到集群。

    kubectl apply -f gang-job.yaml
  6. 执行以下命令,查看Pod状态。

    kubectl get pod -n test-gang

    预期输出:

    NAME             READY   STATUS    RESTARTS   AGE
    gang-job-hrnc6   0/1     Pending   0          23s
    gang-job-wthnq   0/1     Pending   0          23s

    由于ResourceQuota 限制只能运行 2 个Pod,因此该 Job 只有两个Pod可以创建。这个数量小于PodGroup中指定的minMember,所以这2个Pod会处于Pending状态不调度。

  7. 执行以下命令,删除ResourceQuota,解除Pod数量的限制。

    kubectl delete resourcequota -n test-gang object-counts
  8. 执行以下命令,查看Pod状态。

    kubectl get pod -n test-gang

    预期输出:

    NAME             READY   STATUS    RESTARTS   AGE
    gang-job-24cz9   1/1     Running   0          96s
    gang-job-mmkxl   1/1     Running   0          96s
    gang-job-msr8v   1/1     Running   0          96s
    gang-job-qnclz   1/1     Running   0          96s

    可以发现Pod调度成功。