DRA 拓扑感知调度:从 ResourceSlice 到 NUMA/PCIe 对齐
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 | ┌──────────────────────────────────────────┐ |
1. 驱动层:ResourceSlice 发布拓扑属性
DRA 驱动(DaemonSet 形式运行在每个节点)负责发现硬件拓扑,并把每个设备的拓扑信息作为结构化属性写入 ResourceSlice。例如 NVIDIA GPU DRA 驱动会发布 pciBusID、numaNode、pcieRoot 等字段;DRANET 网络驱动同样为每个 RDMA NIC 发布 dra.net/numaNode、dra.net/pciAddress 等属性。
2. 用户层:ResourceClaim 表达拓扑约束
用户在 ResourceClaimTemplate 中,除了通过 CEL 选择器做设备过滤,更关键的是使用 constraints[].matchAttribute 来声明跨请求的拓扑对齐要求。例如:
1 | apiVersion: resource.k8s.io/v1 |
这条 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 | - name: nic |
实测结果差异显著:
| 配对方式 | RDMA 吞吐 | 相对 |
|---|---|---|
| 跨 NUMA(GPU 在 NUMA0、NIC 在 NUMA1,PCIe 关系 SYS) | ~25 GB/s | 1× |
| 同 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 | 节点内对齐 (NUMA/PCIe) 跨节点共置 (机架/交换机域) |
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