多级网络拓扑装箱调度
功能介绍
通过多级网络拓扑亲和调度和分组亲和调度能力,Volcano已有效缓解了数据中心分布式AI训练/推理作业的网络通信性能问题。然而,随着各种新工作负载的不断到来和旧工作负载的陆续结束,各HyperNode的资源碎片化问题日趋严重,即集群虽有充足的可用资源,但却分散在不同HyperNode中,导致对通信性能要求高的新作业不能被调度,或只能被分散调度,降低集群资源使用效率。传统的装箱调度算法主要考虑节点级资源占用情况,通过将任务分配到尽可能少的节点上,有效缓解节点的资源碎片化,但却不能缓解HyperNode的资源碎片化问题。
为此,Volcano进一步提出了多级网络拓扑装箱调度能力,在调度时考虑各层HyperNode的资源占用情况,并将工作负载调度至综合资源占用率较高的HyperNode,以缓解HyperNode级资源碎片化问题,提升整体资源使用效率。
具体而言,在调度具有网络拓扑约束的工作负载时,调度器会优先将其调度到当前资源占用率较高的HyperNode,以提高整体资源利用率。如下图所示,假设集群内有2个tier=1的HyperNode,其中HyperNode1已有部分资源被其他任务占用。此时下发一个Volcano Job,均分成2组,每个分组配置网络拓扑约束只能部署在1层的HyperNode内。
- 不使用装箱调度时:分组1调度至HyperNode1,分组2调度至HyperNode2。
- 使用装箱调度时:分组1和分组2都会优先调度到HyperNode1上。此时,HyperNode2可作为一个完整的空闲HyperNode供其他任务使用。

此外,针对没有网络拓扑约束的工作负载,调度器还提供了多层级HyperNode级装箱调度能力,即优先将这些工作负载调度到所在各层级HyperNode当前资源利用率较高的节点。如下图所示,假设集群内有8个节点、7个HyperNode,其中节点node0、node2和node4上的资源均被其他任务占用,而tier=1、tier=2、tier=3的HyperNode分别有4个、2个和1个。此时,下发一个由两个Pod组成、无网络拓扑约束的Volcano Job,于是:
- 若不启用该能力:这两个Pod可能被调度到node1、node3、node5、node6和node7中的任意两个节点,可能导致其它更大、有网络拓扑约束的任务无法调度。
- 若启用了该能力:这两个Pod将被优先调度到node1和node3。此时,HyperNode3、HyperNode5有更多资源,可以供其它更大、有网络拓扑约束的任务使用。

为使用此功能,需Volcano启用network-topology-aware插件,并配置如下参数。其中,fading参数需大于等于0,否则将被设置为默认值0.8。
- 当fading为0时,各层HyperNode的装箱权重均为0。
- 当fading大于0且小于1时,低层HyperNode的装箱权重大于高层HyperNode。
- 当fading为1时,各层HyperNode的装箱权重均为1。
- 当fading大于1,高层HyperNode的装箱权重大于低层HyperNode。
...
default_scheduler_conf:
tiers:
- plugins:
- name: network-topology-aware # 添加本行内容,以启用网络拓扑感知调度
arguments:
weight: 10 # 本插件整体策略权重,可不填,默认为1
hypernode.binpack.cpu: 5 # CPU资源HyperNode级装箱权重,可不填,默认为1
hypernode.binpack.memory: 5 # 内存资源HyperNode级装箱权重,可不填,默认为1
hypernode.binpack.resources: nvidia.com/gpu, huawei.com/ascend-1980 # 装箱策略需要考虑的自定义资源名,可不填,默认为无
hypernode.binpack.resources.nvidia.com/gpu: 10 # 自定义资源“nvidia.com/gpu”的HyperNode级装箱权重,可不填,默认为1
hypernode.binpack.resources.huawei.com/ascend-1980: 10 # 自定义资源“huawei.com/ascend-1980”的HyperNode级装箱权重,可不填,默认为1
hypernode.binpack.normal-pod.enable: true # 针对无网络拓扑约束Pod的多层级HyperNode装箱调度能力开关,可不填,默认为true
hypernode.binpack.normal-pod.fading: 0.8 # 无网络拓扑约束Pod在计算各层级HyperNode装箱分数时,第tier层的权重为math.Pow(fading, tier-1),可不填,默认为0.8
... 前提条件
集群中已安装Volcano调度器插件,且插件版本在1.21.1及以上。
约束与限制
- 网络拓扑感知调度暂不支持抢占。当资源紧张时,调度器不会主动抢占已分配给Pod的资源。
- 若配置了分组亲和策略,则不支持soft模式的网络拓扑约束。
- HyperJob工作负载不支持网络拓扑感知调度。即使在HyperJob的JobTemplate中配置了networkTopology或分组亲和策略,这些配置将被忽略且不会生效。
- HyperNode自动发现功能不支持多种网络拓扑结构混部的场景(例如,A2与A3拓扑类型共存于同一集群)。
- 应尽量避免在运行中变更网络拓扑配置项,因为这可能导致集群内HyperNode结构重建,进而引发Volcano调度器进程的负载波动或调度异常。
- 若在调度过程中,集群网络拓扑结构或配置项发生变更,Volcano无法保证调度结果的正确性。
使用示例
- 登录CCE控制台,单击集群名称进入集群。
- 单击左侧导航栏的“配置中心”,切换至“调度配置”页面,选择Volcano调度器找到对应的“专家模式”,单击“开始使用”。

- 进入CCE专家模式配置页面,在YAML配置文件中,修改default_controller_conf配置为如下内容,以启用HyperNode自动发现功能。其中配置参数,请根据实际需求调整。
... default_controller_conf: networkTopologyDiscovery: - source: label # HyperNode自动发现插件的名称,不可修改 enabled: true # HyperNode自动发现插件开关,true表示开启,false表示关闭(原有的HyperNode实例不会删除) config: networkTopologyTypes: testtopology: # 网络拓扑层级关系的名称,最大限制20字符;当前仅支持配置一组 - nodeLabel: test-tier-3 # 第3层网络拓扑对应的节点标签名,对应HyperNode tier=3 - nodeLabel: test-tier-2 # 第2层网络拓扑对应的节点标签名,对应HyperNode tier=2 - nodeLabel: test-tier-1 # 第1层网络拓扑对应的节点标签名,对应HyperNode tier=1 - nodeLabel: kubernetes.io/hostname # 第0层网络拓扑对应的节点标签名,即节点层级,仅支持根据Node名匹配,不支持修改 ...同时,在default_scheduler_conf配置中添加名为network-topology-aware的插件,如下所示。其配置参数,请根据实际需求调整。
... default_scheduler_conf: actions: allocate, backfill, preempt configurations: '' metrics: interval: 30s type: '' tiers: - plugins: - name: priority - enableJobStarving: false enablePreemptable: false enableReclaimable: false name: gang - name: conformance - enableHierarchy: true name: capacity - plugins: - enablePreemptable: false enableReclaimable: false name: drf - name: predicates - name: nodeorder - plugins: - name: cce-gpu-topology-predicate - name: cce-gpu-topology-priority - name: xgpu - name: network-topology-aware # 添加本行内容,以启用网络拓扑感知调度 arguments: weight: 10 # 本插件整体策略权重,默认为1 hypernode.binpack.cpu: 5 # CPU资源HyperNode级装箱权重,默认为1 hypernode.binpack.memory: 5 # 内存资源HyperNode级装箱权重,默认为1 hypernode.binpack.resources: nvidia.com/gpu, huawei.com/ascend-1980 # 装箱策略需要考虑的自定义资源名,默认为无 hypernode.binpack.resources.nvidia.com/gpu: 10 # “nvidia.com/gpu”的HyperNode级装箱权重,默认无 hypernode.binpack.resources.huawei.com/ascend-1980: 10 # “huawei.com/ascend-1980”的HyperNode级装箱权重,默认无 hypernode.binpack.normal-pod.enable: true # 针对无网络拓扑约束Pod的多层级HyperNode装箱调度能力开关,默认为true hypernode.binpack.normal-pod.fading: 0.8 # 无网络拓扑约束Pod在计算各层级HyperNode装箱分数时,第tier层的权重为math.Pow(fading, tier-1),默认为0.8 - plugins: - name: nodelocalvolume - name: nodeemptydirvolume - name: nodeCSIscheduling - name: networkresource ... - 以下图中的多级网络拓扑结构为例,创建8个节点,并执行如下命令,为它们添加如下网络拓扑标签。

本示例仅用于演示,实际创建的HyperNode应依据集群的真实拓扑。此外,对于没有网络拓扑关系的普通节点,不应添加与网络拓扑相关的节点标签,否则可能导致创建的HyperNode不符合预期。
kubectl label node 192.168.5.17 test-tier-3=HyperNode6 test-tier-2=HyperNode4 test-tier-1=HyperNode0 # node0 kubectl label node 192.168.5.224 test-tier-3=HyperNode6 test-tier-2=HyperNode4 test-tier-1=HyperNode0 # node1 kubectl label node 192.168.5.235 test-tier-3=HyperNode6 test-tier-2=HyperNode4 test-tier-1=HyperNode1 # node2 kubectl label node 192.168.5.239 test-tier-3=HyperNode6 test-tier-2=HyperNode4 test-tier-1=HyperNode1 # node3 kubectl label node 192.168.5.240 test-tier-3=HyperNode6 test-tier-2=HyperNode5 test-tier-1=HyperNode2 # node4 kubectl label node 192.168.5.251 test-tier-3=HyperNode6 test-tier-2=HyperNode5 test-tier-1=HyperNode2 # node5 kubectl label node 192.168.5.83 test-tier-3=HyperNode6 test-tier-2=HyperNode5 test-tier-1=HyperNode3 # node6 kubectl label node 192.168.5.95 test-tier-3=HyperNode6 test-tier-2=HyperNode5 test-tier-1=HyperNode3 # node7
表1 节点、IP与多级HyperNode归属映射表 节点名
IP地址
标签(Labels)
node0
192.168.5.17
test-tier-3=HyperNode6 test-tier-2=HyperNode4 test-tier-1=HyperNode0
node1
192.168.5.224
test-tier-3=HyperNode6 test-tier-2=HyperNode4 test-tier-1=HyperNode0
node2
192.168.5.235
test-tier-3=HyperNode6 test-tier-2=HyperNode4 test-tier-1=HyperNode1
node3
192.168.5.239
test-tier-3=HyperNode6 test-tier-2=HyperNode4 test-tier-1=HyperNode1
node4
192.168.5.240
test-tier-3=HyperNode6 test-tier-2=HyperNode5 test-tier-1=HyperNode2
node5
192.168.5.251
test-tier-3=HyperNode6 test-tier-2=HyperNode5 test-tier-1=HyperNode2
node6
192.168.5.83
test-tier-3=HyperNode6 test-tier-2=HyperNode5 test-tier-1=HyperNode3
node7
192.168.5.95
test-tier-3=HyperNode6 test-tier-2=HyperNode5 test-tier-1=HyperNode3
- 执行以下命令,查询Volcano自动发现的HyperNode。
kubectl get hypernodes
返回信息如下所示。
NAME TIER TIERNAME NODECOUNT AGE hypernode-testtopology-tier1-5**** 1 test-tier-1 2 9s hypernode-testtopology-tier1-7**** 1 test-tier-1 2 10s hypernode-testtopology-tier1-g**** 1 test-tier-1 2 10s hypernode-testtopology-tier1-l**** 1 test-tier-1 2 9s hypernode-testtopology-tier2-5**** 2 test-tier-2 2 9s hypernode-testtopology-tier2-t**** 2 test-tier-2 2 10s hypernode-testtopology-tier3-c**** 3 test-tier-3 2 10s
- 创建3个Pod工作负载,指定将其调度到node0、node2和node4上,并占据这些节点的所有NPU资源。示例如下。
apiVersion: v1 kind: Pod metadata: name: node-pod-1 spec: containers: - name: nginx image: nginx:latest resources: requests: huawei.com/ascend-1980: 16 limits: huawei.com/ascend-1980: 16 nodeName: 192.168.5.17 # node0 --- apiVersion: v1 kind: Pod metadata: name: node-pod-2 spec: containers: - name: nginx image: nginx:latest resources: requests: huawei.com/ascend-1980: 16 limits: huawei.com/ascend-1980: 16 nodeName: 192.168.5.235 # node2 --- apiVersion: v1 kind: Pod metadata: name: node-pod-3 spec: containers: - name: nginx image: nginx:latest resources: requests: huawei.com/ascend-1980: 16 limits: huawei.com/ascend-1980: 16 nodeName: 192.168.5.240 # node4 - 创建一个Volcano Job工作负载,包含2个Pod,每个Pod独占一个节点的NPU资源,且无网络拓扑约束。示例如下所示。
apiVersion: batch.volcano.sh/v1alpha1 kind: Job metadata: name: network-topology-job namespace: default spec: schedulerName: volcano tasks: - replicas: 2 name: t0 template: spec: containers: - name: container1 image: nginx:latest resources: requests: huawei.com/ascend-1980: 16 limits: huawei.com/ascend-1980: 16 - 查看调度结果。该示例中,节点node0、node2和node4的资源均已被占用,因此,两个Pod分别被调度到节点node1和node3。
kubectl get pod -o wide
返回信息如下所示。
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES network-topology-job-t0-0 1/1 Running 0 5s 172.19.2.132 192.168.5.224 <none> <none> network-topology-job-t0-1 1/1 Running 0 5s 172.19.3.4 192.168.5.239 <none> <none> node-pod-1 1/1 Running 0 16s 172.19.1.25 192.168.5.17 <none> <none> node-pod-2 1/1 Running 0 16s 172.19.1.143 192.168.5.235 <none> <none> node-pod-3 1/1 Running 0 16s 172.19.2.4 192.168.5.240 <none> <none>