Kubernetes 2026:AI 工作负载正在改变调度器的设计方向
一、默认调度器对 AI 工作负载的失配:从 filter/score 到拓扑感知
Kubernetes 默认调度器的核心假设是"工作负载之间没有硬件拓扑依赖"。一个 Pod 调度到哪个节点,主要看 CPU 和内存的剩余量,加上亲和性/反亲和性的软约束。这个模型对 Web 服务、微服务这类无状态负载够用,对 AI 训练和推理工作负载就是灾难。
AI 工作负载有三个 Kubernetes 原生调度器无法理解的特性。第一,GPU 拓扑亲和性——分布式训练要求参与训练的 GPU 共享同一个 NVSwitch 或 NVLink 域,跨节点甚至跨 NUMA 的 GPU 通信会导致训练吞吐下降 30%~60%。第二,显存作为一等资源——Kubernetes 的 resource request 只关注"这块 GPU 有没有被占用",不关心"占了多少显存、还剩多少、碎片率如何"。第三,工作负载的排队语义——AI 任务通常以队列方式提交(Job/JobSet),而非长期运行的服务,调度器需要理解"这个队列里前面还有多少任务、它们的资源需求是什么",做全局的负载均衡。
二、GPU 拓扑感知调度:NVLink 域的发现与绑定
GPU 拓扑感知的核心,是让调度器理解节点的物理 GPU 拓扑图,并以此约束 Pod 的放置决策。
这张拓扑图对应一个 8 卡 H200 节点。如果启动一个 4 卡分布式训练任务,最优调度是选择 GPU 0-3(共享 NVSwitch 0,在同一个 NUMA 0 域内),而不是 GPU 2-5(跨 NVSwitch,会引入跨域通信延迟)。
实现上,有几个技术路径在演进:
NRI (Node Resource Interface):Kubernetes 1.31 引入的节点资源接口,允许调度器插件通过标准 API 获取节点的硬件拓扑信息,包括 GPU、NUMA、PCIe 互联关系。相比之前的 Device Plugin 方案,NRI 提供了更丰富的拓扑元数据。
拓扑约束标注:节点通过 Node Feature Discovery 暴露 GPU 拓扑标签(如 nvidia.com/gpu.nvswitch.count),调度器在 filter 阶段按标签筛选候选节点,在 score 阶段按拓扑亲和度打分。
Gang Scheduling 协议:分布式训练要求要么所有 Worker 同时运行,要么一个都不启动(all-or-nothing)。Volcano 的 Gang Scheduling 提供了这种语义,避免部分 Worker 启动后等待资源导致的资源僵持。
三、从静态配额到弹性 GPU:MIG 与 vGPU 的调度实践
NVIDIA MIG (Multi-Instance GPU) 将一张物理 GPU 切分为多个独立实例,每个实例有专属的显存、缓存和计算单元。这解决了"AI 推理不需要整张 H200,但独占模式又浪费"的矛盾。
在实践中,MIG 调度需要处理几个细节:
切分配置的动态管理:MIG 配置一旦设定,修改需要重启 GPU。生产环境的策略通常是预定义几种切分模板(如 1g.10gb、2g.20gb、7g.80gb),根据工作负载类型分配,而不是频繁动态切换。
碎片化问题:当一个 GPU 被切分成 7 个 1g.10gb 实例后,如果要调度一个需要 7g.80gb 的训练任务,调度器需要判断是否"反向合并"——销毁所有小实例,重新配置为完整 GPU。这里的决策逻辑需要结合任务优先级和等待队列。
指标暴露:Kubernetes 的 Device Plugin 需要暴露每个 MIG 实例的显存使用率、SM 利用率和温度到 Prometheus,让 HPA/VPA 能基于这些指标做自动伸缩。
// MIG 实例的调度决策:是否应该触发反向合并
func shouldDefragMIG(device map[string]*MIGStatus, pendingJob *AITrainingJob) (bool, string) {
fragmentedGPU := ""
totalFreeMem := 0
for gpuID, migs := range device {
for _, mig := range migs {
if mig.Status == "idle" && isFragment(mig.Profile) {
fragmentedGPU = gpuID
totalFreeMem += mig.MemoryMB
}
}
}
// 碎片化的小实例累加能凑出大任务所需的显存,且任务优先级足够高
if totalFreeMem >= pendingJob.MemoryMB && pendingJob.Priority >= PriorityHigh {
return true, fragmentedGPU
}
return false, ""
}
func isFragment(profile string) bool {
// 1g.10gb 或 2g.20gb 等小切分视为碎片
return strings.HasPrefix(profile, "1g.") || strings.HasPrefix(profile, "2g.")
}
这段逻辑的关键在于 Priority 阈值。生产环境通常会设一个严格的值——仅当任务是 P0 级别的紧急训练任务时,才允许触发反向合并,因为合并操作会中断所有运行中的小实例推理服务。
四、边界分析:修改调度器不是银弹
GPU 拓扑感知调度虽然正确,但有两个现实约束需要正视。
调度延迟的增加:拓扑感知调度需要额外的约束匹配计算。在一个 200 个节点的集群中,从简单的 CPU/内存匹配到 GPU 拓扑图匹配,调度延迟可能从毫秒级增加到百毫秒级。对于批量提交的训练任务可以接受,对于需要秒级扩容的推理服务就存在风险。
供应商锁定风险:NCCL 拓扑文件和 MIG 配置都是 NVIDIA 私有生态的一部分。如果未来切换到 AMD ROCm 或 Intel Gaudi,整个拓扑感知层的代码需要重写。建议的做法是抽象一个 TopologyProvider 接口,让不同 GPU 供应商的实现解耦——虽然这会增加初期工程工作量,但基础设施工程师应该习惯这种"为解耦多写代码"的做法。
适用边界:GPU 拓扑感知调度适用于分布式训练(2 卡以上)和高显存带宽要求的推理场景(如大尺寸扩散模型)。对于单卡推理、CPU 推理和轻量训练任务,默认调度器已经足够,拓扑感知反而增加了不必要的复杂度。
不适用场景:不要试图用调度器解决所有 AI 工作负载的放置问题。对于需要全互联(all-to-all)通信的千卡级别大模型训练,调度器能提供的优化有限——真正的瓶颈在网络结构(Spine-Leaf vs. Dragonfly)和集合通信算法(Ring vs. Tree AllReduce),这不是调度器层面能处理的问题。
五、总结
Kubernetes 调度器正在经历自诞生以来最深刻的一次架构调整——从面向无状态微服务的通用调度,进化为理解 GPU 拓扑、显存管理和排队语义的 AI 工作负载调度器。
三个具体趋势值得关注。第一,NRI 生态的成熟会让调度器插件从"猜测硬件拓扑"变为"查询硬件拓扑",精度和效率都有数量级提升。第二,MIG 和 vGPU 的混合管理将成为推理集群的标配,调度器需要同时理解物理 GPU 拓扑和逻辑切分状态。第三,Gang Scheduling 将从分布式训练的刚需,逐步延伸到多模型推理管线的编排。
对于云原生工程师,现在就该在测试环境跑起 Volcano + GPU Operator + NFD 的组合,建立 GPU 拓扑感知调度的实验环境。基础设施不需要漂亮话,但需要早做准备。
资料说明
本文中的协议、版本、性能、成本和行业趋势应以可核验的一手资料为准。未标注统计口径的比例、时间表和预测仅作工程讨论,不应视为行业事实。可参考 0730 资料来源索引,并在发布前将具体来源贴到对应断言之后。




