DRA 拓扑感知调度:从 ResourceSlice 到 NUMA/PCIe 对齐

DRA(Dynamic Resource Allocation)已经原生支持拓扑感知调度,而且这是它的核心设计目标之一——通过 ResourceSlice 暴露设备拓扑信息,配合 ResourceClaim 中的约束(constraint)让调度器在 Pod 绑定前就完成 NUMA / PCIe 级别的拓扑对齐。本文从实现机制、版本演进、使用示例和当前局限几个维度展开说明。

本文是 深入解析 K8s GPU 复用:从通用方案到 HAMi 异构架构全解 的深入篇——那篇讲 HAMi 怎么用 DRA 做异构 GPU 分配,这篇专讲 DRA 本身的拓扑感知能力。


一、实现机制:拓扑如何参与调度决策

DRA 的拓扑感知能力建立在 KEP-4381(DRA Structured Parameters) 引入的结构化参数模型之上,核心链路分三层:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
              ┌──────────────────────────────────────────┐
驱动层 │ DRA Driver(DaemonSet,每节点) │
│ 发现硬件拓扑 → 写入 ResourceSlice │
│ GPU: pciBusID / numaNode / pcieRoot │
│ NIC: dra.net/numaNode / dra.net/... │
└─────────────────────┬────────────────────┘
│ 发布结构化属性

┌──────────────────────────────────────────┐
用户层 │ ResourceClaim(声明式约束) │
│ requests: 要几块 GPU、几块 NIC │
│ constraints[].matchAttribute: │
│ 要求 gpu 和 nic 的 numaNode 相同 │
│ (CEL selector 也可做设备过滤) │
└─────────────────────┬────────────────────┘
│ 约束传给调度器

┌──────────────────────────────────────────┐
调度层 │ kube-scheduler 内置 DRA 插件 │
│ Filter/Score 阶段直接计算: │
│ 枚举设备组合 → 校验 matchAttribute │
│ → 拓扑对齐通过才选该节点 │
│ (Pod 绑定前完成,不等 kubelet 后处理) │
└──────────────────────────────────────────┘

1. 驱动层:ResourceSlice 发布拓扑属性

DRA 驱动(DaemonSet 形式运行在每个节点)负责发现硬件拓扑,并把每个设备的拓扑信息作为结构化属性写入 ResourceSlice。例如 NVIDIA GPU DRA 驱动会发布 pciBusIDnumaNodepcieRoot 等字段;DRANET 网络驱动同样为每个 RDMA NIC 发布 dra.net/numaNodedra.net/pciAddress 等属性。

2. 用户层:ResourceClaim 表达拓扑约束

用户在 ResourceClaimTemplate 中,除了通过 CEL 选择器做设备过滤,更关键的是使用 constraints[].matchAttribute 来声明跨请求的拓扑对齐要求。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: resource.k8s.io/v1
kind: ResourceClaim
metadata:
name: gpu-numa-alignment-claim
spec:
devices:
requests:
- name: gpu
exactly:
deviceClassName: gpu.nvidia.com
count: 8
- name: nic
exactly:
deviceClassName: dranet
count: 1
constraints:
# 关键:要求 gpu 和 nic 两个请求命中的设备,其 numaNode 属性值必须相同
- matchAttribute: "numaNode"
requests: [gpu, nic]

这条 matchAttribute 约束会让调度器只考虑那些 GPU 与 NIC 的 NUMA 编号一致的组合。

3. 调度层:Scheduler 内置 DRA 插件直接计算

与传统 DRA(依赖 kubelet 中的 DRA Driver 处理器)不同,结构化参数版本让 kube-scheduler 内置的 DynamicResourceAllocation 插件直接在 Filter/Score 阶段完成设备分配和拓扑对齐计算,无需等到 Pod 落到节点后才发现冲突。这解决了老式 Device Plugin + Topology Manager 最大的痛点——拓扑信息只在 kubelet 本地可见,调度器只能盲目选节点。


二、版本演进时间线

DRA 的拓扑感知能力随版本迭代逐步增强,关键节点:

版本 特性 拓扑能力状态
v1.26 DRA 初版(alpha,经典模式) 仅依赖驱动和 kubelet 后处理,调度器无感知
v1.32 DRA Structured Parameters(alpha) 调度器可直接解析结构化属性,支持 GPU/NIC PCIe 根对齐
v1.34 DRA 主线推进(beta) 多驱动协同、NUMA 对齐能力成熟;GA 推进中
v1.35 DRA stable(GA) ResourceClaim/ResourceSlice API 进入 resource.k8s.io/v1
v1.36 优先级备选列表(Prioritized List,stable)+ 派生属性 KEP-6080 推进 支持在多个拓扑对齐方案间按优先级选择;派生属性可桥接不同驱动的命名差异

三、典型场景:GPU + NIC 的 NUMA 对齐

Azure AKS 团队发布的 DRANET 实测很好地展示了 DRA 拓扑感知的价值。在 Azure ND GB300-v6 节点上(4 GPU + 4 ConnectX-8 NIC 分布在两个 NUMA 域),通过 ResourceClaimTemplate 中的 CEL 选择器可以显式约束 GPU 与 NIC 必须落在同一 NUMA:

1
2
3
4
5
6
7
8
9
- name: nic
exactly:
deviceClassName: dranet
count: 2
selectors:
- cel:
expression: |
device.attributes["dra.net"]["rdma"] == true &&
device.attributes["dra.net"]["numaNode"] == 0

实测结果差异显著:

配对方式 RDMA 吞吐 相对
跨 NUMA(GPU 在 NUMA0、NIC 在 NUMA1,PCIe 关系 SYS) ~25 GB/s
同 NUMA(GPU 与 NIC 同一 NUMA) ~56 GB/s 2.2×
同 NUMA 双 NIC 配对 ~112 GB/s 4.5×

差距达 4.5 倍。原因在于跨 NUMA 时 GPUDirect RDMA 被禁用、数据要跨 QPI/UPI 互联、NCCL 通道数也会减少。

此外,kubernetes-sigs/dra-driver-cpu 还把 CPU 也纳入了 DRA 管理,它会读取 sysfs 暴露完整的 socket/NUMA/core/LLC(末级缓存)拓扑,让独占 CPU 能与 GPU、NIC 做 NUMA 级别的联合对齐——这相当于把 kubelet 的 CPUManager/TopologyManager 能力上移到调度层


四、当前局限与注意事项

尽管能力已相当完整,实际使用中仍需注意几点:

1. 与 kubelet TopologyManager 不联动

这是目前最容易踩的坑,官方在 2026 年 6 月专门开了 issue 要求文档明确此边界。DRA 管理的设备不参与 kubelet TopologyManager 的准入决策——TopologyManager 协调的是 CPUManager、MemoryManager、DeviceManager 这些 kubelet 本地管理器,而 DRA 资源是在 Pod 启动流程更靠后的阶段才准备的。结果是:如果你同时申请了 DRA 管理的 GPU 和 kubelet 本地管理的独占 CPU/大页内存,系统不保证它们落在同一 NUMA 节点。官方推荐的通用做法是:把需要对齐的资源都通过 DRA 建模,用 ResourceClaim 中的 constraints[].matchAttribute 基于共享拓扑属性做联合约束。

2. 依赖驱动的属性命名一致性

matchAttribute 要求跨请求的属性名和值都精确匹配。如果 GPU 驱动发布 numa 而 NIC 驱动发布 numaNode,直接匹配会失败。KEP-6080(Derived Attributes) 正在解决这个问题,允许用户用 CEL 表达式把不同驱动的字段映射到统一的虚拟属性名上。社区同时也在推进属性标准化(如 PR #6073 统一 numaNode)。

3. 与 TAS(Topology-Aware Scheduling)的关系

v1.36 引入的独立特性 TAS 解决的是另一个维度的问题——跨节点的机架/Block 级拓扑共置(保证一个 PodGroup 的所有 Pod 落在同一网络拓扑域内以降低 East-West 带宽延迟),它通过 TopologyPlacement 和扩展的 NodeResourcesFit 插件实现。DRA 关注的是节点内的 NUMA/PCIe 拓扑对齐,两者互补而非替代。对 AI/ML 训练这种既要求 Pod 共置同机架又要求 GPU-NIC 同 NUMA 的场景,需要 TAS + DRA 配合使用:

1
2
3
4
5
6
节点内对齐 (NUMA/PCIe)        跨节点共置 (机架/交换机域)
┌─────────────────┐ ┌─────────────────────────┐
│ DRA │ │ TAS │
│ matchAttribute │ ◄──互补──► │ TopologyPlacement │
│ GPU-NIC 同 NUMA │ │ PodGroup 同机架/同Block │
└─────────────────┘ └─────────────────────────┘

4. 生态成熟度

DRA 核心 API 在 v1.35 稳定,但周边生态仍在建设中。NVIDIA 的 GPU DRA driver 已在 KubeCon Europe 2026 捐给 CNCF,DRANET、dra-driver-cpu 等 SIG 项目可用,但 KubeVirt、大部分 CSI 网络插件等尚未深度集成,多数托管 Kubernetes 服务(包括 AKS)的托管版 DRA 方案也仍在开发中,需要用户自行安装驱动。


五、总结

总体而言,如果场景是 GPU/NIC/FPGA 等加速器的节点内拓扑对齐,DRA 是当前最正规、声明式的方案;但需要注意与 kubelet 本地管理资源的边界,以及驱动属性标准化的现状。

一句话:DRA 用 ResourceSlice 把设备拓扑信息暴露给调度器、用 ResourceClaim 的 matchAttribute 表达对齐约束、用 kube-scheduler 内置插件在绑定前算好——把原来只在 kubelet 本地可见的 NUMA/PCIe 拓扑,提升成了调度期就能决策的全局信息。

它跟跨节点的 TAS 互补:DRA 管"节点内对齐",TAS 管"跨节点共置",AI 训练两者都要。这跟 Sky-Scheduler 的 RDMA Zone(跨节点交换机域共置)是不同维度的拓扑——DRA 是 NUMA 级、Sky-Scheduler 是 leaf 交换机级,两者解决训练通信优化的不同切面。


参考

  • KEP-4381: DRA Structured Parameters
  • KEP-6080: Derived Attributes
  • Azure AKS DRANET 实测
  • kubernetes-sigs/dra-driver-cpu、DRANET