首页 容器计算服务 操作指南 调度 使用 Gang Scheduling

使用 Gang Scheduling

更新时间: 2024-01-16 18:13:49

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

功能介绍

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

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

使用方式

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 # 设置最小运行个数
  1. 创建一个作业,并关联 PodGroup。

    apiVersion: batch/v1
    kind: Job
    metadata: 
      name: demo-job
      namespace: default
    spec:
      parallelism: 3 # Pod数量必须大于或者等于 minMember
      template:
        metadata:
          labels:
            # 关联 PodGroup 实例 demo-job-podgroup
            pod-group.scheduling.sigs.k8s.io: demo-job-podgroup
        spec:
          containers:
          - name: pi
            image: perl:5.34.0
            command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
          restartPolicy: Never
      backoffLimit: 4
说明
  • 关联同一个 PodGroup 实例的一组 Pod 必须使用相同的优先级。

  • 确保创建的 Pod 数量一定大于或等于 PodGroup 实例配置的 minMember。

示例

本文通过模拟资源不足场景展示 Gang Scheduling 的效果。

  1. 创建一个 Namespace,用于运行该示例。

    kubectl create ns test-gang
  2. 在 Namespace 下创建 ResourceQuota,限制 Pod 的总量,模拟资源不足的情况。

    cat << EOF | kubectl apply -f -
    apiVersion: v1
    kind: ResourceQuota
    metadata:
      name: object-counts
      namespace: test-gang
    spec:
      hard:
        pods: "2"
    EOF
  3. 我们创建一个 Job,该 Job 期望创建 3 个 Pod,因为 ResourceQuota 限制只能运行 2 个 Pod,因此该 Job 只有两个 Pod 可以创建并运行。

    cat << EOF | kubectl apply -f -
    apiVersion: batch/v1
    kind: Job
    metadata: 
      name: demo-job
      namespace: test-gang
    spec:
      parallelism: 3 # Pod数量必须大于或者等于 minMember
      template:
        spec:
          containers:
          - name: pi
            image: perl:5.34.0
            command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
          restartPolicy: Never
      backoffLimit: 4
    EOF
  4. 查看 Job 的 Pod 的运行状态

    kubectl -n test-gang get pod

    系统会输出如下信息:

    NAME             READY   STATUS    RESTARTS   AGE
    demo-job-5kjvn   0/1     Running   0          81s
    demo-job-vlbkg   0/1     Running   0          80s
  5. 当使用 Gang Scheduling 时,我们期望三个 Pod 能够一起调度。如果其中一个没有创建或者没有调度成功,其他 Pod 也应该处于 Pending 状态。

    1. 在 Namespace 下创建一个 PodGroup,并设置 minMember 等于 3。

      cat << EOF | kubectl apply -f -
      apiVersion: scheduling.sigs.k8s.io/v1alpha1
      kind: PodGroup
      metadata: 
        name: demo-job-podgroup
        namespace: test-gang
      spec: 
        scheduleTimeoutSeconds: 10 
        minMember: 3 # 设置最小运行个数
      EOF
    2. 创建一个 Job 并关联这个 PodGroup。

      cat << EOF | kubectl apply -f -
      apiVersion: batch/v1
      kind: Job
      metadata: 
        name: demo-job
        namespace: test-gang
      spec:
        parallelism: 3 # Pod数量必须大于或者等于 minMember
        template:
          metadata:
            labels:
              # 关联 PodGroup 实例 demo-job-podgroup
              pod-group.scheduling.sigs.k8s.io: demo-job-podgroup
          spec:
            containers:
            - name: pi
              image: perl:5.34.0
              command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
            restartPolicy: Never
        backoffLimit: 4
      EOF
    3. 查看 Pod 的状态,因为此时还有 ResourceQuota 的限制,此时只能创建两个 Worker Pod,并且这两个 Pod 处于 Pending 状态。

      kubectl -n test get pod
      NAME             READY   STATUS    RESTARTS   AGE
      demo-job-6wdvf   0/1     Pending   0          4s
      demo-job-z4jpw   0/1     Pending   0          4s
    4. 删除 ResourceQuota,解除 ResourceQuota 的限制。

      kubectl -n test-gang delete resourcequota object-counts
    5. 查看 Pod 的状态,可以发现此时调度成功。

      kubectl -n test-gang get pod
      NAME             READY   STATUS    RESTARTS   AGE
      demo-job-6wdvf   0/1     Running   0          29s
      demo-job-x7c4c   0/1     Running   0          1s
      demo-job-z4jpw   0/1     Running   0          29s