主题
Kubernetes v1.37:Workload-Aware Scheduling 进入生产就绪新阶段
一句话摘要:v1.37 不是“又一个调度增强”,而是 Kubernetes 调度范式从 Pod-centric 向 Workload-centric 的实质性跃迁——
Workload/PodGroupAPI、Workload-Aware Preemption(WAP)、CompositePodGroup和workloadbuilder库集体升为 Beta,标志着 AI/ML 与复杂批处理工作负载终于拥有了原生、可组合、可中断、可拓扑感知的调度语义,而不再依赖 KubeBatch 等第三方调度器“打补丁”。
背景动机:为什么 Pod 级调度已成瓶颈?
过去五年,Kubernetes 调度器在吞吐、公平性、资源碎片率等维度持续进化,但其底层抽象始终锚定在单个 Pod 上。这种设计对 Web 服务、无状态 API 等传统负载足够健壮,却在面对以下三类现代工作负载时频频失灵:
- AI/ML 训练作业:vLLM 推理集群需 GPU 显存拓扑对齐(如 NVLink 互联的 A100×4),PyTorch DDP 训练要求所有 Worker Pod 同时启动且网络连通,否则
torch.distributed.init_process_group()直接超时失败; - 科学计算批处理:MPI 作业中 Master + N 个 Rank 必须同机部署或低延迟跨机部署,且任意 Rank 失败即整组失效;
- 异构编排框架:JobSet(多 Job 协同)、LeaderWorkerSet(LWS)等上层抽象,长期受限于“无法向调度器表达组级语义”,只能靠 controller 轮询 + 重试 + 自定义 annotation “模拟” gang 行为,导致调度延迟高、抢占逻辑混乱、故障恢复不可控。
Kubernetes 社区早在 v1.27 就启动了 Workload-Aware Scheduling(WAS)路线图,v1.32 引入 Alpha 版 Workload 和 PodGroup,v1.35 实现基础 gang scheduling。而 v1.37 是分水岭版本:它不再满足于“能跑”,而是提供生产级稳定性、可扩展架构和控制器友好集成——这才是企业级 AI 平台真正需要的底座能力。
核心技术:从 Beta API 到可编程调度原语
1. Workload / PodGroup API 正式 Beta:gang scheduling 原生化
Workload(CRD)和 PodGroup(内置资源)是 WAS 的基石。v1.37 中二者均升为 v1beta1,意味着:
- API 字段冻结(仅允许向后兼容变更);
- kube-scheduler 内置插件
PodGroupScheduling默认启用(无需--feature-gates=WorkloadAwareScheduling=true); - 支持
status.phase(Pending/Admitted/Running/Failed)和标准条件(Admission、Scheduled)。
yaml
# 示例:vLLM 推理服务组(4 Pod,需同节点 + 共享 GPU 显存池)
apiVersion: scheduling.k8s.io/v1beta1
kind: PodGroup
metadata:
name: vllm-inference-group
namespace: ai-prod
spec:
minMember: 4
scheduleTimeoutSeconds: 300
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: vllm-inference
---
apiVersion: v1
kind: Pod
metadata:
name: vllm-worker-0
labels:
app: vllm-inference
annotations:
# 关键:绑定到 PodGroup
scheduling.k8s.io/pod-group-name: vllm-inference-group
spec:
containers:
- name: vllm-server
image: ghcr.io/vllm-project/vllm-cpu:latest
resources:
limits:
nvidia.com/gpu: 1✅ 运维提示:Beta 意味着你可以在生产环境启用
PodGroupScheduling插件,但需禁用旧版GenericScheduler(默认已弃用)。检查方式:kubectl get pods -n kube-system | grep scheduler,确认镜像含v1.37+且启动参数无--use-legacy-scheduler。
2. CompositePodGroup:首次支持多层级拓扑约束
这是 v1.37 最具突破性的设计。传统 PodGroup 是扁平结构,而 CompositePodGroup 允许定义嵌套层级,例如:
- Level 1:
LeaderWorkerSet—— 1 个 Leader + 3 个 Worker - Level 2:每个 Worker 内部含 2 个 Sidecar(metrics-collector + log-forwarder)
- 约束:Leader 与 Worker 必须同 zone;Worker 内部的 2 个 Pod 必须同 node;所有 Pod 共享同一块 NVMe SSD(通过 DRA ResourceClaim)
yaml
apiVersion: scheduling.k8s.io/v1beta1
kind: CompositePodGroup
metadata:
name: lws-train-group
spec:
children:
- name: leader
podGroupRef:
name: lws-leader-pg
namespace: ml-training
- name: workers
podGroupRef:
name: lws-workers-pg
namespace: ml-training
topologyPolicies:
- level: "leader"
constraint: "SameZone"
- level: "workers"
constraint: "SameNode"
- crossLevel:
from: "leader"
to: "workers"
constraint: "LowLatencyNetwork" # 自定义拓扑键,需 CNI 插件支持🔍 技术判断:
CompositePodGroup并非“大而全”的万能方案,而是为 JobSet/LWS 等上层控制器提供可组合的原语。它不替代控制器逻辑,而是将“组间关系”下沉至调度层,让 JobSet controller 只需关注 Job 生命周期,无需再 hack annotation 实现跨 Job 亲和性。
3. Workload-Aware Preemption(WAP):智能抢占,而非暴力驱逐
传统抢占(Preemption)基于 Pod 优先级,常导致:高优 Pod 抢占低优 Pod 后,因资源碎片仍无法调度,反而引发雪崩。WAP 则以 Workload 为单位决策:
- 若
PodGroupA(minMember=4)被抢占,则调度器会评估:是否可通过驱逐 一组 低优 Pod(如 2 个独立的 Debug Pod)释放连续资源,而非随机驱逐 4 个零散 Pod; - 支持
preemptionPolicy: Conservative(默认)与Aggressive,后者允许跨PodGroup抢占(需显式授权 RBAC)。
yaml
# 在 PodGroup 中启用保守抢占
spec:
minMember: 4
preemptionPolicy: Conservative # 或 Aggressive
priorityClassName: high-priority-ml💡 关键洞察:WAP 的价值不在“更快抢占”,而在降低抢占副作用。实测显示,在 GPU 集群中,开启 WAP 后训练作业平均调度延迟下降 62%,因抢占导致的
Pending状态抖动减少 89%(数据来源:Kubeflow SIG 测试报告)。
4. workloadbuilder 库:控制器开发者的“调度 SDK”
过去,自研控制器(如 Spark Operator)若想支持 gang scheduling,需手动解析 PodGroup status、轮询 admission、实现抢占回滚逻辑——代码量超 2000 行且极易出错。v1.37 提供的 workloadbuilder Go 库封装了全部 WAS 交互模式:
go
// 示例:Spark Operator 中创建 PodGroup 的标准化方式
pg := workloadbuilder.NewPodGroup("spark-app-123").
WithMinMember(3).
WithTopologySpread(topology.Zone, topology.DoNotSchedule).
WithPreemptionPolicy(workloadbuilder.Conservative)
if err := pg.Create(ctx, client); err != nil {
// 自动处理 admission timeout / conflict retry
}更关键的是,原生 Job Controller 已完成重构:batch/v1.Job 现在直接使用 Workload API,支持:
job.spec.scheduling字段配置topologySpreadConstraints和preemptionPolicy;job.spec.disruptionBudget控制最大并发中断数(防 vLLM 批量推理服务雪崩);job.status.admittedAt字段暴露 admission 时间戳,用于 SLA 监控。
运维建议:如何平稳升级与落地?
渐进式启用路径:
✅ 第一阶段:启用PodGroupScheduling插件,仅对新命名空间(如ai-prod)开启PodGroupBeta;
✅ 第二阶段:将 KubeBatch 用户迁移至原生PodGroup(注意:PodGroup的minMember语义与 KubeBatch 的minAvailable完全一致,迁移成本极低);
❌ 避免:直接在核心命名空间(如kube-system)启用CompositePodGroup,该 API 尚未 GA。监控必加指标:
promql# 检测 gang scheduling 失败根因 sum(rate(scheduler_podgroup_admission_failures_total{reason=~"Insufficient|Topology|Preemption"}[1h])) by (reason) # WAP 抢占成功率(目标 >95%) scheduler_workload_preemption_attempts_total - scheduler_workload_preemption_failures_totalRBAC 权限更新:
PodGroup和CompositePodGroup需独立 RBAC,勿复用pods权限:yaml- apiGroups: ["scheduling.k8s.io"] resources: ["podgroups", "compositepodgroups"] verbs: ["create", "get", "list", "watch", "delete"]GPU 场景特别提醒:
若使用 NVIDIA Device Plugin,请确保已升级至 v0.14+,并启用--device-list-strategy=volume-mounts模式,否则PodGroup的共享 GPU 资源分配可能失败。
延伸阅读
- 📘 Kubernetes WAS 设计文档(含
CompositePodGroup状态机图) - 🧪 Kubeflow 社区 WAS 实战指南(含 vLLM + Ray on K8s 拓扑优化案例)
- 📊 CNCF 2026 年 AI 工作负载调度基准报告(对比 KubeBatch vs 原生 WAS 在 1000+ GPU 集群表现)
- ⚙️
workloadbuilder官方库:https://pkg.go.dev/k8s.io/kubernetes/pkg/scheduler/framework/plugins/workloadbuilder
结语:Kubernetes v1.37 不是终点,而是起点。当
CompositePodGroup与 DRA(Dynamic Resource Allocation)深度协同,当Workload成为 Service Mesh、Serverless Runtime 的统一调度入口,K8s 将真正成为“任何工作负载的通用操作系统”。作为 SRE,你现在要做的不是观望,而是——在下一个 CI/CD 流水线中,把PodGroupYAML 加进去,然后看它如何安静地、可靠地,把你的 vLLM 推理服务,一次调度成功。