Kubernetes 1.35 原生 Gang Scheduling:调度生态的“大一统”前夜
Kubernetes 1.35 引入的原生 Workload API 和 Gang Scheduling 支持,被业界视为云原生 AI 基础设施的一次“内核级重构”。要真正理解这次升级的分量,我们不仅要看它带来了什么,更要看它试图取代(或融合)什么。
在 v1.35 之前,面对 AI 训练任务的“资源死锁”痛点,社区实际上已经演化出了一个庞杂的“第三方调度器动物园”。本文将从原生原语出发,盘点现有生态选择,并揭示生产环境中的架构演进方向。
1. 缘起与冲突:原子化调度在 AI 时代的“水土不服”
在 Kubernetes 的经典设计中,Pod 是最小的原子调度单元。调度器采用“贪婪算法”,依次处理队列中的 Pod,只要当前节点满足需求就立即绑定。这种机制在微服务时代运转完美,但在 AI 分布式训练场景下却遭遇了语义冲突:
- 微服务假设:Pod 是独立的,部分启动也能提供部分服务。
- AI 假设:训练任务(如 PyTorch DDP)是强耦合的拓扑结构,All-or-Nothing(全有或全无)。
这种“原子化”与“整体化”的冲突,直接导致了资源死锁:通过贪婪算法占有的资源(部分 Pod)在等待剩余资源,而剩余资源被其他部分占用的 Pod 锁死。
2. 生态群雄逐鹿:在 v1.35 之前我们如何自救?
在原生功能缺位的漫长岁月里,为了让 K8s 能跑 AI 任务,业界发展出了三类主流的替代方案。理解它们,才能明白 v1.35 的切入点。
2.1 重型替代者:Volcano 与 YuniKorn
这是最彻底的方案——直接替换或旁路默认调度器。
- Volcano:CNCF 项目,源自华为。它完全抛弃了 K8s 默认调度逻辑,引入了
PodGroup、Queue、Command等概念。它不仅支持 Gang Scheduling,还支持复杂的多租户队列管理(如“部门 A 借用部门 B 的配额”)。 - Apache YuniKorn:源自 Cloudera,带有浓厚的 Hadoop YARN 基因。它的杀手锏是层级队列(Hierarchical Queues),非常适合需要精细化预算管理的大数据/AI 混合场景。
- 痛点:运维成本极高。你需要维护两个调度器(Default for Web, Volcano for AI),且容易出现资源视图冲突(Race Condition)。
2.2 轻量级插件:Scheduler Plugins (Coscheduling)
这是基于 Kubernetes Scheduling Framework 的插件化扩展。
- 机制:通过安装
Coscheduling插件,拦截默认调度器的 Filter/Permit 阶段,实现简单的“人齐了再走”逻辑。 - 痛点:功能单一。它只解决了“成组”问题,但缺乏队列管理、优先级抢占等企业级特性。
2.3 这里的“新贵”:Kueue (Kubernetes Native Job Queuing)
Kueue 不是调度器,而是一个作业队列控制器。
- 机制:它工作在调度器之上。它拦截 Job,只有当集群配额满足时,才放行(unsuspend)Pod 进入调度器。
- 痛点:在 v1.35 之前,Kueue 虽然能控制配额,但一旦放行,底层的默认调度器依然可能因为碎片化导致死锁。因此 Kueue 往往需要配合 Coscheduling 插件使用。
3. 内核级重构:v1.35 Workload API 的“降维打击”
Kubernetes 1.35 的出现,实际上是吸取了上述方案的经验,将核心能力下沉。
3.1 调度视角的升维
新的 scheduling.k8s.io/v1alpha1 API 将调度视角从单个 Pod 提升到了 Workload(作业组)。这相当于告诉调度器:“不要只看这棵树(Pod),要看这片林(Workload)” 。
3.2 状态机的根本改变
在启用 GangScheduling 后,调度循环引入了关键的 WaitOnPermit 阶段。这本质上是一个两阶段提交协议:
- Pre-check:在队列阶段就拦截不满足最小数量(minCount)的任务组。
- Transactional Binding:在内存中尝试放置所有 Pod,只有当整个组都有位置时,才进行实际的节点绑定(Bind)。
这标志着:Coscheduling 插件的历史使命即将结束,因为它的逻辑已经被吸收到 K8s 内核中了。
4. 生产环境的现实评估:主流架构将走向何方?
如果说 v1.35 解决了“能不能跑”的问题,那么生产环境关注的是“跑得好不好”。目前的生产实践正在经历从“重型调度器”向“原生组合模式”的转变。
4.1 当前生产环境的痛点(Why not just Volcano?)
虽然 Volcano 功能强大,但在大规模生产环境中,运维团队越来越排斥“多调度器架构”:
- 升级困难:K8s 升级时,Volcano 往往需要滞后适配。
- 资源割裂:很难在同一个节点池混合跑 Web 服务和 AI 训练(Volcano 甚至有自己的节点隔离机制)。
4.2 未来的主流架构:Native + Kueue
随着 v1.35 原生 Gang Scheduling 的成熟,一个清晰的分层架构正在形成:
| 层级 | 组件 | 职责 | 演进趋势 |
|---|---|---|---|
| 决策层 (Policy) | Kueue | 决定“谁可以跑”。管理部门配额、借用逻辑、作业优先级。 | 成为 AI 任务的统一入口,接管 Volcano 的队列功能。 |
| 执行层 (Mechanism) | Kube-Scheduler (v1.35+) | 决定“跑在哪里”。利用原生 Gang Scheduling 防止死锁,执行具体的节点绑定。 | 内核功能增强,替代 Coscheduling 插件,无需第三方调度器。 |
4.3 为什么现在还不能扔掉 Volcano?
我们必须清醒地认识到,v1.35 目前处于 Alpha 阶段,且存在明显的“裸奔”特征:
- 配置僵化:硬编码的 5 分钟超时逻辑,无法适应加载超大模型(LLM)时的慢启动需求。
- 缺乏碎片整理:原生调度器缺乏重调度(Re-scheduling)能力,无法主动腾挪小任务以空出大块资源给 Gang 任务。
结论: 对于已经深度依赖 Volcano/YuniKorn 高级特性(如拓扑感知、重调度、复杂的借贷策略)的团队,目前迁移的 ROI 不高。 但对于大多数新构建的 AI 平台,“Kueue + Kubernetes 原生调度器(v1.35+)” 将是未来两年的黄金标准——既享受了原生 K8s 的稳定性,又获得了必要的队列管理能力。
结语
Kubernetes 1.35 的原生 Gang Scheduling 不是要消灭所有第三方调度器,而是要收复失地。它将“成组调度”这一通用需求收归内核,迫使 Volcano、YuniKorn 等项目向更高端的“特种调度”(如精细化 GPU 拓扑、跨集群联邦调度)转型。
对于平台工程师而言,这意味着未来的架构将更加简洁:少维护一个组件,多一份原生保障。
参考资料: