更新时间:2026-05-21 GMT+08:00
分享

多级网络拓扑调度

功能介绍

目前,分布式AI训练/推理任务正逐渐成为算力基础设施的核心工作负载,但由于高度依赖各子任务间的数据交换,面临着网络传输性能的瓶颈,导致计算效率难以显著提升。这一问题的主要原因在于数据中心网络拓扑的复杂性,通常由多层交换机构成的层级架构组成,且类型多样,包括IB、RoCE、NVSwitch等。跨层级交换机的通信路径越长,延迟越高,吞吐量越低,效率随之下降;反之,通信性能更优。因此,将高度相关的工作负载调度至同一高性能域,可以有效减少跨交换机的通信成本,加快节点间的数据交换,从而显著提高分布式训练/推理任务的整体效率。

为此,Volcano首先定义了一种新的CRD,即HyperNode,用于统一描述集群的多层级网络拓扑结构,屏蔽网络类型差异。如下图所示,每个HyperNode代表一个网络拓扑性能域,通常可以映射到一个交换机或ToR;多个HyperNode可以通过层级连接,形成多级树状结构,从而精准表达真实数据中心的复杂网络拓扑结构。

在这种结构中,节点间的通信效率取决于它们之间的HyperNode层级跨度。例如:

  • node0和node1属于HyperNode0(tier 1),通信效率最高。
  • node0和node2属于HyperNode4(tier 2),通信效率较低。
  • node0和node4属于HyperNode6(tier 3),通信效率最差。

与传统的通过节点标签(label)表示网络拓扑的方式相比,HyperNode具有以下优势:

  • 语义统一:通过标准化的结构化定义,消除了手动标签方式中可能存在的语义不一致问题。
  • 层级结构:支持树状层级结构,能够精确映射物理网络拓扑关系,适应多层交换结构。
  • 易于管理:支持手动创建或通过自动拓扑发现机制动态维护,实现资源状态的自动化同步与管理。

为了进一步减轻网络拓扑信息的管理负担,Volcano提供了HyperNode自动发现功能。该功能能够自动检测集群内部的网络拓扑结构,并根据检测结果自动创建、更新或删除相应的HyperNode自定义资源(CRs),从而减少网络拓扑信息的管理负担。自动发现功能具备以下核心优势:

  • 自动化管理:自动从节点网络拓扑信息标签(labels)中发现和维护HyperNode信息,无需手动操作。
  • 实时同步:实时同步网络拓扑的变化(如节点网络拓扑信息标签的更改),确保HyperNode信息与实际网络状态的一致性。

通过这一自动化发现机制,您可以专注于作业调度的配置,无需担忧HyperNode的创建和维护复杂性,显著简化了网络拓扑感知调度的部署和管理。

网络拓扑约束配置

在Volcano Job中,可通过配置networkTopology字段描述Job部署时的网络拓扑约束,确保Job实例被调度至满足条件的最优性能域内,显著提升计算效率与通信性能。具体约束配置如下。

字段

说明

mode

支持hard和soft两种模式:

  • hard:硬约束,Job内所有实例必须部署在同一个HyperNode内。
  • soft:软约束,尽可能将Job内所有实例部署在同一个HyperNode内,但允许在资源不足时妥协。

highestTierAllowed

与hard模式配合使用,表示Job最高允许部署到哪一层HyperNode(即最大tier值)。soft模式下无需配置此字段。

例如,配置参数值为2,则Job只能部署在tier ≤ 2的HyperNode内(如tier=1或tier=2),禁止跨tier=3或更高层级的HyperNode。

spec:
  networkTopology:
    mode: hard
    highestTierAllowed: 2

前提条件

集群中已安装Volcano调度器插件,且插件版本在1.21.1及以上。

约束与限制

  • 网络拓扑感知调度暂不支持抢占。当资源紧张时,调度器不会主动抢占已分配给Pod的资源。
  • 若配置了分组亲和策略,则不支持soft模式的网络拓扑约束。
  • HyperJob工作负载不支持网络拓扑感知调度。即使在HyperJob的JobTemplate中配置了networkTopology或分组亲和策略,这些配置将被忽略且不会生效。
  • HyperNode自动发现功能不支持多种网络拓扑结构混部的场景(例如,A2与A3拓扑类型共存于同一集群)。
  • 应尽量避免在运行中变更网络拓扑配置项,因为这可能导致集群内HyperNode结构重建,进而引发Volcano调度器进程的负载波动或调度异常。
  • 若在调度过程中,集群网络拓扑结构或配置项发生变更,Volcano无法保证调度结果的正确性。

使用示例

  1. 登录CCE控制台,单击集群名称进入集群。
  2. 单击左侧导航栏的“配置中心”,切换至“调度配置”页面,选择Volcano调度器找到对应的“专家模式”,单击“开始使用”。

  3. 进入CCE专家模式配置页面,在YAML配置文件中,修改default_controller_conf配置为如下内容,以启用HyperNode自动发现功能。其中配置参数,请根据实际需求调整。

    ...
    default_controller_conf:
      networkTopologyDiscovery:
        - source: label # HyperNode 自动发现插件名称,不可修改
          enabled: true # 开关: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级装箱权重,可不填,默认为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
        - plugins:
            - name: nodelocalvolume
            - name: nodeemptydirvolume
            - name: nodeCSIscheduling
            - name: networkresource
    ...

  4. 以下图中的多级网络拓扑结构为例,创建8个节点,并执行如下命令,为它们添加如下网络拓扑标签。

    表1 节点、IP与多级HyperNode归属映射表

    节点名

    IP地址

    标签(Labels)

    node0

    192.168.5.17

    test-tier-2=HyperNode2, test-tier-1=HyperNode0

    node1

    192.168.5.224

    test-tier-2=HyperNode2, test-tier-1=HyperNode0

    node2

    192.168.5.235

    test-tier-2=HyperNode2, test-tier-1=HyperNode0

    node3

    192.168.5.239

    test-tier-2=HyperNode2, test-tier-1=HyperNode0

    node4

    192.168.5.240

    test-tier-2=HyperNode2, test-tier-1=HyperNode1

    node5

    192.168.5.251

    test-tier-2=HyperNode2, test-tier-1=HyperNode1

    node6

    192.168.5.83

    test-tier-2=HyperNode2, test-tier-1=HyperNode1

    node7

    192.168.5.95

    test-tier-2=HyperNode2, test-tier-1=HyperNode1

    本示例仅用于演示,实际创建的HyperNode应依据集群的真实拓扑。此外,对于没有网络拓扑关系的普通节点,不应添加与网络拓扑相关的节点标签,否则可能导致创建的HyperNode不符合预期。

    kubectl label node 192.168.5.17  test-tier-2=HyperNode2 test-tier-1=HyperNode0 # node0
    kubectl label node 192.168.5.224 test-tier-2=HyperNode2 test-tier-1=HyperNode0 # node1
    kubectl label node 192.168.5.235 test-tier-2=HyperNode2 test-tier-1=HyperNode0 # node2
    kubectl label node 192.168.5.239 test-tier-2=HyperNode2 test-tier-1=HyperNode0 # node3
    kubectl label node 192.168.5.240 test-tier-2=HyperNode2 test-tier-1=HyperNode1 # node4
    kubectl label node 192.168.5.251 test-tier-2=HyperNode2 test-tier-1=HyperNode1 # node5
    kubectl label node 192.168.5.83  test-tier-2=HyperNode2 test-tier-1=HyperNode1 # node6
    kubectl label node 192.168.5.95  test-tier-2=HyperNode2 test-tier-1=HyperNode1 # node7

  5. 执行以下命令,查询Volcano自动发现的HyperNode。

    kubectl get hypernodes

    返回信息如下所示。

    NAME                                      TIER   TIERNAME      NODECOUNT   AGE
    hypernode-testtopology-tier1-8****   1      test-tier-1   4           6s
    hypernode-testtopology-tier1-l****   1      test-tier-1   4           6s
    hypernode-testtopology-tier2-v****   2      test-tier-2   2           6s

  6. 创建一个Volcano Job工作负载,包含8个Pod,每个Pod独占一个节点的NPU资源,要求至少调度4个Pod,并且这些Pod必须位于同一个一层HyperNode下。示例如下所示。

    apiVersion: batch.volcano.sh/v1alpha1
    kind: Job
    metadata:
      name: network-topology-job
      namespace: default
    spec:
      schedulerName: volcano
      minAvailable: 4         # Gang调度条件,需要满足至少4个Pod可调度成功
      networkTopology:        # 配置网络拓扑约束
        mode: hard
        highestTierAllowed: 1 # 最高亲和到tier=1的HyperNode
      tasks:
        - replicas: 8 # 一共8个实例
          name: t0
          template:
            spec:
              containers:
                - name: container1
                  image: nginx:latest
                  resources:
                    requests:
                      huawei.com/ascend-1980: 16 # 每个实例独占一个节点的NPU资源
                    limits:
                      huawei.com/ascend-1980: 16

  7. 检查调度结果。在本例中,4个Pod被调度至HyperNode1上,状态为Running;另外4个Pod因无法找到满足网络拓扑约束的节点,状态为Pending。

    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          6s    172.19.3.3     192.168.5.239   <none>           <none>
    network-topology-job-t0-1   1/1     Running   0          6s    172.19.2.131   192.168.5.224   <none>           <none>
    network-topology-job-t0-2   1/1     Running   0          6s    172.19.1.142   192.168.5.235   <none>           <none>
    network-topology-job-t0-3   1/1     Running   0          6s    172.19.1.24    192.168.5.17    <none>           <none>
    network-topology-job-t0-4   0/1     Pending   0          6s    <none>         <none>          <none>           <none>
    network-topology-job-t0-5   0/1     Pending   0          6s    <none>         <none>          <none>           <none>
    network-topology-job-t0-6   0/1     Pending   0          6s    <none>         <none>          <none>           <none>
    network-topology-job-t0-7   0/1     Pending   0          6s    <none>         <none>          <none>           <none>

相关文档