更新时间:2025-07-18 GMT+08:00

层级队列

在多租户场景中,队列是实现公平调度、资源隔离和任务优先级控制的核心机制。而在实际应用中,不同队列往往隶属于不同部门,部门之间存在层级关系,传统平级队列的资源管理无法满足实际需要。为此,Volcano调度器引入层级队列,通过将队列按层级结构组织,实现不同层级间的资源分配、共享与抢占。通过这一功能,用户可以在层级队列的基础上实现更细粒度的资源配额管理,构建更高效的统一调度平台。

层级队列功能简介

层级队列是Volcano调度器中的一种高级队列管理机制,用于在多租户集群环境中实现资源的层次化分配和隔离。通过树形结构组织队列,支持以下功能:

  • 支持配置队列层级关系。Volcano调度器在Queue spec中新增了parent属性,在创建队列时可以通过parent参数指定该队列所属的父队列:
    type QueueSpec struct {
        ...
        // 指定队列所属的父队列
        Parent string `json:"parent,omitempty" protobuf:"bytes,8,opt,name=parent"`
        ...
    }

    Volcano Scheduler在启动后会默认创建一个root队列,作为所有队列的根队列,用户可以基于root队列进一步构建层级队列树。

  • 支持为每个维度的资源设置队列容量上限capability、资源应得量deserved(若队列已分配资源量超过设置的deserved值,则资源超出部分可能被回收)以及资源预留量guarantee(表示当前队列预留资源,无法与其他队列共享)。
  • 支持跨层级队列任务间资源共享与回收。当集群资源无法支撑Pod部署时,可以回收其他层级队列的Pod资源,层级队列间资源回收规则如下:
    • 若兄弟队列中的已分配资源量超过deserved值,则优先回收兄弟队列中的Pod资源。
    • 若兄弟队列中的资源不足以满足Pod的需求,那么就按照队列的层级结构(即祖先队列)逐层向上查找资源,直到找到足够的资源为止。

    图1,Job A和Job C先提交,且其队列已分配资源量皆超过设置的deserved值。当集群资源不够满足Job B要求,则系统会优先回收Job A资源。若回收Job A后资源仍得不到满足,则会再考虑回收Job C资源。

    图1 层级队列资源回收

前提条件

  • 已创建v1.27及以上版本的CCE Standard/Turbo集群,具体步骤请参见购买Standard/Turbo集群
  • 已安装Volcano插件,且插件版本在1.17.1及以上,具体步骤请参见Volcano调度器

约束与限制

该能力处于公测阶段,您可以体验相关特性,但稳定性暂未得到完全验证,不适用CCE服务SLA。

配置层级队列策略

配置层级队列策略后,您可以自定义队列间层级关系,实现跨层级队列的资源共享与回收,进而实现更细粒度的资源配额管理。

  1. 登录CCE控制台,单击集群名称进入集群。
  2. 在左侧导航栏中选择“配置中心”,在右侧切换至“调度配置”页签。
  3. 在Volcano调度器配置中,“层级队列”默认关闭,需进一步修改调度器配置参数以开启“层级队列”功能。

    1. “设置集群默认调度器 > 专家模式”中,单击“开始使用”
      图2 “专家模式 > 开始使用”

    2. 层级队列能力基于capacity插件构建,调度器配置需要打开capacity插件,并且将enableHierarchy设置为true,以开启层级队列能力。同时需要打开reclaim action,支持队列间的资源回收。当队列资源紧张时,将触发资源回收机制,系统将优先回收超出队列deserved值的资源,并结合队列/任务优先级选择合适的回收对象。

      capacity和proportion插件是相互冲突的,请确保使用capacity插件时已移除proportion插件配置。

      在YAML配置文件中,添加如下参数:
      ...
      default_scheduler_conf:
        actions: allocate, backfill, preempt, reclaim    # 开启reclaim action
        metrics:
          interval: 30s
          type: ''
        tiers:
          - plugins:
              - name: priority
              - enableJobStarving: false
                enablePreemptable: false
                name: gang
              - name: conformance
          - plugins:
              - enablePreemptable: false
                name: drf
              - name: predicates
              - name: capacity             # 开启capacity插件
                enableHierarchy: true     # 开启层级队列
              - name: nodeorder
              - arguments:
                  binpack.cpu: 1
                  binpack.memory: 1
                  binpack.resources: nvidia.com/gpu
                  binpack.resources.nvidia.com/gpu: 2
                  binpack.weight: 10
                name: binpack
    3. 参数填写完成后,在右下角单击“保存”

  4. 完成上述配置后,单击右下角“确认配置”。在“确认配置”弹窗中,确认修改信息,无误后单击“保存”。

层级队列使用示例

假设集群中CPU和内存资源全部可用量分别为8核、16Gi。首先,创建一个层级队列树。其次,创建2个Volcano job job-a和job-c将集群资源耗尽。最后,创建Volcano job job-b,查看层级队列中的资源回收流程。本示例的整体结构图请参见图3

图3 层级队列示例
  1. 执行以下命令,创建层级队列树的YAML文件。

    vim hierarchical_queue.yaml

    文件内容如下:

    # child-queue-a的父队列为root队列
    apiVersion: scheduling.volcano.sh/v1beta1
    kind: Queue
    metadata:
      name: child-queue-a
    spec:
      reclaimable: true
      parent: root 
      capability:
        cpu: 5
        memory: 10Gi
      deserved:
        cpu: 4
        memory: 8Gi
    ---
    # child-queue-b的父队列为root队列
    apiVersion: scheduling.volcano.sh/v1beta1
    kind: Queue
    metadata:
      name: child-queue-b
    spec:
      reclaimable: true
      parent: root 
      deserved:
        cpu: 4
        memory: 8Gi
    ---
    # subchild-queue-a1的父队列为child-queue-a队列
    apiVersion: scheduling.volcano.sh/v1beta1
    kind: Queue
    metadata:
      name: subchild-queue-a1
    spec:
      reclaimable: true
      parent: child-queue-a
      #可根据需要设置deserved,队列已分配资源若已超过deserved值,则队列中资源可能被回收
      deserved: 
        cpu: 2
        memory: 4Gi
    ---
    # subchild-queue-a2的父队列为child-queue-a队列
    apiVersion: scheduling.volcano.sh/v1beta1
    kind: Queue
    metadata:
      name: subchild-queue-a2
    spec:
      reclaimable: true
      parent: child-queue-a 
      #可根据需要设置deserved,队列已分配资源若已超过deserved值,则队列中资源可能被回收
      deserved: 
        cpu: 2
        memory: 4Gi

    child-queue-a的YAML文件为例,介绍层级队列的相关参数。更多参数信息,请参见Queue | Volcano

    表1 层级队列参数说明

    参数

    示例

    说明

    reclaimable

    true

    可选参数,用于开启资源回收策略,默认值为true。

    • true:该队列资源使用量超过其deserved时,允许其他队列回收该队列超额使用的资源。
    • false:不允许其他队列回收该队列超额使用的资源。

    parent

    root

    可选参数,用于指定该队列的父队列,使队列形成层级关系,子队列资源总量受父队列限制。若未指定parent,则父队列默认为root。

    capability

    cpu: 5

    memory: 10Gi

    可选参数,用于指定该队列的资源上限,具体数值不能超过父队列的capability值。

    如果某个队列未设置某一维度资源的capability值,则该维度的capability将继承自其父队列的设置。如果父队列及其所有祖先队列均未设置,则最终继承自root队列的配置。root队列的capability默认设置为集群中该维度资源的全部可用量。

    deserved

    cpu: 4

    memory: 8Gi

    用于指定该队列的资源应得量,子队列的deserved总和不能超过父队列配置的deserved值,且队列的deserved值需小于等于capability。root队列的deserved默认与其capability一致。

    若当前队列中已分配的资源量超过自身的deserved值,则该队列不可再回收其他队列中的资源。

  2. 执行以下命令,创建层级队列树。

    kubectl apply -f hierarchical_queue.yaml

    回显结果如下:

    queue.scheduling.volcano.sh/child-queue-a created
    queue.scheduling.volcano.sh/child-queue-b created
    queue.scheduling.volcano.sh/subchild-queue-a1 created
    queue.scheduling.volcano.sh/subchild-queue-a2 created

  3. 执行以下命令,创建Volcano job job-a和job-b的YAML文件,job-a和job-b分别属于subchild-queue-a1和child-queue-b层级队列。

    vim vcjob.yaml

    文件内容如下:

    # 提交job-a到叶子队列subchild-queue-a1中
    apiVersion: batch.volcano.sh/v1alpha1
    kind: Job
    metadata:
      name: job-a
    spec:
      queue: subchild-queue-a1
      schedulerName: volcano
      minAvailable: 1
      tasks:
        - replicas: 3
          name: test
          template:
            spec:
              containers:
                - image: alpine
                  command: ["/bin/sh", "-c", "sleep 1000"]
                  imagePullPolicy: IfNotPresent
                  name: alpine
                  resources:
                    requests:
                      cpu: "1"
                      memory: 2Gi
    ---
    # 提交job-c到叶子队列child-queue-b中
    apiVersion: batch.volcano.sh/v1alpha1
    kind: Job
    metadata:
      name: job-c
    spec:
      queue: child-queue-b
      schedulerName: volcano
      minAvailable: 1
      tasks:
        - replicas: 5
          name: test
          template:
            spec:
              containers:
                - image: alpine
                  command: ["/bin/sh", "-c", "sleep 1000"]
                  imagePullPolicy: IfNotPresent
                  name: alpine
                  resources:
                    requests:
                      cpu: "1"
                      memory: 2Gi

  4. 执行以下命令,创建job-a和job-c。

    kubectl apply -f vcjob.yaml

    回显结果如下:

    job.batch.volcano.sh/job-a created
    job.batch.volcano.sh/job-c created

  5. 执行以下命令,查看Pod的运行情况。

    kubectl get pod

    回显结果如下,所有Pod的STATUS皆为Running,此时集群CPU和内存资源皆已耗尽

    NAME           READY        STATUS        RESTARTS       AGE
    job-a-test-0   1/1          Running       0              3h21m
    job-a-test-1   1/1          Running       0              3h31m
    job-a-test-2   1/1          Running       0              3h31m
    job-c-test-0   1/1          Running       0              24m
    job-c-test-1   1/1          Running       0              24m
    job-c-test-2   1/1          Running       0              24m
    job-c-test-3   1/1          Running       0              24m
    job-c-test-4   1/1          Running       0              24m

  6. 执行以下命令,创建Volcano job job-b的YAML文件。

    vim vcjob1.yaml

    文件内容如下:

    # 提交job-b到叶子队列subchild-queue-a2中
    apiVersion: batch.volcano.sh/v1alpha1
    kind: Job
    metadata:
      name: job-b
    spec:
      queue: subchild-queue-a1
      schedulerName: volcano
      minAvailable: 1
      tasks:
        - replicas: 2
          name: test
          template:
            spec:
              containers:
                - image: alpine
                  command: ["/bin/sh", "-c", "sleep 1000"]
                  imagePullPolicy: IfNotPresent
                  name: alpine
                  resources:
                    requests:
                      cpu: "1"
                      memory: 2Gi

  7. 执行以下命令,创建job-b。

    kubectl apply -f vcjob1.yaml

    回显结果如下:

    job.batch.volcano.sh/job-b created

    由于集群CPU和内存资源已耗尽,job-b将触发资源回收机制。

    • 首先检查兄弟队列中的job-a,发现其实际占用资源(3CPU/6Gi内存)已超过所属队列subchild-queue-a1的deserved值(2CPU/4Gi内存),超占部分(1CPU/2Gi内存)可被优先回收,但该回收量仍不满足job-b需求。
    • 由于兄弟队列资源不足,job-b将沿队列层级向上查找,最终定位到child-queue-b队列中的job-c进行跨队列资源回收。

  8. 执行以下命令,查看Pod运行情况,验证系统是否回收相关资源。

    kubectl get pod
    回显结果如下,则说明系统正在回收资源。
    NAME           READY        STATUS            RESTARTS       AGE
    job-a-test-0   1/1          Running           0              3h33m
    job-a-test-1   1/1          Running           0              3h33m
    job-a-test-2   1/1          Terminating       0              3h33m
    job-b-test-0   0/1          Pending           0              1m
    job-b-test-1   0/1          Pending           0              1m
    job-c-test-0   1/1          Running           0              26m
    job-c-test-1   1/1          Running           0              26m
    job-c-test-2   1/1          Running           0              26m
    job-c-test-3   1/1          Running           0              26m
    job-c-test-4   1/1          Terminating       0              26m

    稍等几分钟后,再次执行以上命令查看Pod的运行情况。回显结果如下,则说明job-b已成功运行。待job-b任务完成释放资源后,被回收的Pod将重新运行。

    NAME           READY        STATUS            RESTARTS       AGE
    job-a-test-0   1/1          Running           0              3h35m
    job-a-test-1   1/1          Running           0              3h35m
    job-a-test-2   0/1          Pending           0              3h35m
    job-b-test-0   1/1          Running           0              2m
    job-b-test-1   1/1          Running           0              2m
    job-c-test-0   1/1          Running           0              28m
    job-c-test-1   1/1          Running           0              28m
    job-c-test-2   1/1          Running           0              28m
    job-c-test-3   1/1          Running           0              28m
    job-c-test-4   0/1          Pending           0              28m

  9. 待job-b任务完成后,执行以下命令,再次查看Pod运行情况,验证job-a-test-2和job-c-test-4是否重新运行。

    kubectl get pod

    回显结果如下,则说明被回收的Pod已重新运行。

    NAME           READY        STATUS            RESTARTS       AGE
    job-a-test-0   1/1          Running           0              3h48m
    job-a-test-1   1/1          Running           0              3h48m
    job-a-test-2   1/1          Running           1              3h48m
    job-b-test-0   0/1          Completed         0              15m
    job-b-test-1   0/1          Completed         0              15m
    job-c-test-0   1/1          Running           0              40m
    job-c-test-1   1/1          Running           0              30m
    job-c-test-2   1/1          Running           0              40m
    job-c-test-3   1/1          Running           0              40m
    job-c-test-4   1/1          Running           1              40m

相关文档