WEBKT

K8s 调度 DSA 设备:如何化解 NUMA 拓扑感知与 Pod 约束的冲突?

3 0 0 0

在高性能计算(HPC)和数据密集型应用中,Intel 的 DSA(Data Streaming Accelerator)设备已成为提升内存拷贝与数据转换效率的利器。然而,在 Kubernetes (K8s) 环境中,通过 Device Plugin 调度这些硬件时,开发者往往会遇到一个棘手的“调度错位”问题:Kubelet 本地的 NUMA 亲和性检查与 kube-scheduler 的全局调度决策之间存在冲突。

1. 冲突的核心:局部最优 vs 全局决策

在 K8s 中,调度流程是分层的:

  • kube-scheduler:负责全局决策,根据节点的 CPU、内存剩余量以及 Pod 的亲和性(Affinity)约束选择节点。它默认并不感知节点内部的 NUMA 拓扑细节。
  • Kubelet Topology Manager:负责节点内部的“最后把关”。当 Pod 到达节点后,Topology Manager 会根据策略(如 single-numa-node)协调 CPU 和设备(如 DSA)的分配。

冲突场景: 调度器认为节点 A 满足 Pod 的亲和性要求并将其派发过去。但到达节点 A 后,Kubelet 发现该 Pod 请求的 DSA 设备分布在 NUMA 0,而可用的 CPU 核心却在 NUMA 1。由于违反了 single-numa-node 策略,Pod 会被报 TopologyAffinityError 而无法启动。

2. 利用 Topology Manager 的 Hints 机制

要解决此问题,首先需要确保 Device Plugin 正确上报了拓扑信息。

DSA Device Plugin 在 ListAndWatch 阶段,必须填充 Device 结构体中的 Topology 字段。通过 TopologyManagerGetTopologyHints 接口,Device Plugin 可以向 Kubelet 提供该设备的 NUMA 节点信息。

TopologyManager 配置为 restrictedsingle-numa-node 时,它会收集所有插件(CPU Manager、Device Plugin)提供的 Hint,计算出一个合并后的最优掩码。如果 Device Plugin 没有上报正确的拓扑,或者调度器强行指派了物理位置冲突的资源组合,这里的 Hint 计算就会失败。

3. 进阶方案:从调度器端解决感知能力

仅仅靠 Kubelet 的“事后拒绝”会导致调度效率低下(Pod 不断在冲突节点间尝试)。实践中通常采用以下两种路径:

A. Node Feature Discovery (NFD) + 自定义调度评分

利用 NFD 探测节点上 DSA 设备的 NUMA 位置,并将其转化为节点标签(Labels)或扩展资源(Extended Resources)。

  • 做法:在 Pod 的 nodeSelectoraffinity 中加入对特定 NUMA 布局的约束。
  • 缺点:标签管理粒度较粗,难以处理动态变化的设备分配情况。

B. 调度器框架插件(Scheduler Framework)

编写自定义的调度插件,在 FilterScore 阶段介入。

  • 逻辑:插件通过缓存或直接查询 API,获取节点上 DSA 设备的 NUMA 分布以及 CPU 的剩余分布。
  • 计算:在调度阶段就预模拟 Topology Manager 的合并逻辑。如果发现节点无法提供跨 NUMA 对齐的资源,直接在 Filter 阶段剔除该节点。

4. 终极解决之道:DRA(Dynamic Resource Allocation)

针对 Device Plugin 在拓扑感知上的结构性缺陷,Kubernetes 引入了 DRA (动态资源分配)
与传统的 Device Plugin 相比,DRA 允许资源驱动程序参与调度决策:

  1. 结构化参数:不再仅仅是简单的整数增量,而是描述复杂的拓扑需求。
  2. 延迟绑定:资源可以在调度器选定节点的同时进行绑定,确保调度器的决策与驱动程序的分配逻辑达成共识。

对于 DSA 设备,采用 DRA 架构可以彻底解决 TopologyAffinityError,因为它将“资源分配”从 Kubelet 提前到了调度决策环中。

5. 最佳实践建议

在现有的生产环境中,如果你正在处理 DSA 设备的调度冲突,建议遵循以下 Checklist:

  • 配置 Kubelet:开启 --topology-manager-policy=single-numa-node 以确保最高性能。
  • 优化 Device Plugin:确保插件支持 GetTopologyHints,并能准确识别 /sys/class/dsa 下设备的 NUMA 关联。
  • 引入调度感知:如果冲突频繁,建议部署自定义调度器扩展,优先将 Pod 调度到 CPU 和 DSA 资源在同一 NUMA 槽位空闲较多的节点。
  • 关注 CPU Manager:确保 Pod 属于 Guaranteed QoS 类别,否则 CPU 亲和性无法激活,DSA 的低延迟优势将被跨 NUMA 访问抵消。

通过在调度层引入拓扑感知,不仅能避免 Pod 启动失败,更能充分发挥 DSA 在内存重负载场景下的极致性能。

云原生拓扑匠人 KubernetesDSANUMA

评论点评