调度大型工作负载比调度单个 Pod 更复杂、也更脆弱, 因为它通常需要把所有 Pod 作为整体来考虑,而不是逐个独立调度。 例如,在调度一个机器学习批处理任务时, 你往往需要有策略地放置每个 worker(例如放在同一个机架上), 才能让整体执行效率更高。 同时,这类工作负载中的 Pod 在调度视角下往往非常相似, 这从根本上改变了调度过程应有的形态。
虽然已经有很多定制调度器可以高效处理工作负载调度,
但考虑到工作负载调度对 Kubernetes 用户的普遍性和重要性,
尤其是在 AI 时代用例快速增长的背景下,
现在正是让工作负载成为 kube-scheduler 一等公民、并提供原生支持的时候。
Kubernetes 1.35 最近发布了首批工作负载感知调度能力改进。 这些改进属于一个更广泛的长期计划,目标是提升工作负载的调度与管理能力。 该计划将跨越多个 SIG 和多个发布周期, 逐步扩展系统能力,向其“北极星目标”推进: 在 Kubernetes 中实现无缝的工作负载调度与管理, 包括但不限于抢占和自动伸缩。
Kubernetes v1.35 引入了 Workload API,
你可以用它描述工作负载的目标形态以及面向调度的要求。
它还带来了 编组调度(Gang Scheduling) 的初始实现,
可指示 kube-scheduler 以 全有或全无(all-or-nothing) 方式调度编组 Pod。
最后,我们通过 机会式批处理(Opportunistic batching) 特性提升了相同 Pod(通常构成一个编组)的调度效率,
从而加速整个调度过程。
新的 Workload API 资源属于 scheduling.k8s.io/v1alpha1
API 组。
该资源以结构化、机器可读的形式定义多 Pod 应用的调度需求。
像 Job 这类面向用户的工作负载定义“运行什么”,
而 Workload 资源定义“一组 Pod 应如何被调度”,
以及它们在整个生命周期内的放置如何被管理。
Workload 允许你定义一组 Pod,并对其应用调度策略。
下面是一个编组调度配置示例:
你可以定义一个名为 workers 的 podGroup,并应用 gang 策略,minCount 设置为 4。
apiVersion: scheduling.k8s.io/v1alpha1
kind: Workload
metadata:
name: training-job-workload
namespace: some-ns
spec:
podGroups:
- name: workers
policy:
gang:
# 仅当 4 个 Pod 能同时运行时,该编组才可调度
minCount: 4
创建 Pod 时,你可以通过新的 workloadRef 字段把它们关联到这个 Workload:
apiVersion: v1
kind: Pod
metadata:
name: worker-0
namespace: some-ns
spec:
workloadRef:
name: training-job-workload
podGroup: workers
...
gang 策略会强制执行全有或全无放置。
没有编组调度时,一个 Job 可能只被部分调度,
占用资源却无法真正运行,从而导致资源浪费甚至潜在死锁。
当你创建属于某个编组调度 Pod 组的 Pod 时,
调度器的 GangScheduling 插件会按每个 Pod 组(或副本键)独立管理其生命周期:
当你创建 Pod(或由控制器代你创建)时, 调度器会先阻止它们被调度,直到:
minCount。当到达足够数量的 Pod 后,调度器会尝试放置它们。
但这些 Pod 不会立即绑定到节点,而是先在 Permit 门控处等待。
调度器会检查是否已为整个组(至少达到 minCount)找到有效分配。
需要说明的是,虽然这只是第一版实现, Kubernetes 项目已经明确计划在后续版本持续改进并扩展编组调度算法。 我们希望带来的收益包括: 针对整个编组的单周期调度阶段、工作负载级抢占等, 并持续向北极星目标推进。
除了显式的编组调度,v1.35 还引入了机会式批处理。 这是一个 Beta 特性,可降低相同 Pod 的调度延迟。
与编组调度不同,这个特性不要求启用 Workload API, 也不需要用户显式选择加入。 它在调度器内部以“机会式”方式工作:识别调度要求相同的 Pod (例如容器镜像、资源请求、亲和性等)。 当调度器处理一个 Pod 时, 可以复用该 Pod 的可行性计算结果给队列中后续相同 Pod, 从而显著加速调度。
只要 Pod 满足相应条件,多数用户无需额外操作就能自动受益于这项优化。
机会式批处理仅在特定条件下生效。
kube-scheduler 用于寻找放置位置的相关字段,必须在 Pod 之间保持一致。
此外,某些特性的使用会为这些 Pod 禁用批处理机制,以确保正确性。
请注意,你可能需要检查 kube-scheduler 配置,
确保它没有在你不知情的情况下为工作负载隐式禁用批处理。
关于限制条件的更多细节,请参考文档。
该项目有着广泛目标:实现工作负载感知调度。 这些新 API 与调度增强只是第一步。 在近期,工作将重点攻关:
以及更多方向。上述重点的优先级和实现顺序可能会调整,敬请关注后续更新。
要体验工作负载感知调度改进:
kube-apiserver 和 kube-scheduler 上启用
GenericWorkload
特性门控,并确保启用 scheduling.k8s.io/v1alpha1
API 组。kube-scheduler 上启用
GangScheduling
特性门控(要求 Workload API 已启用)。kube-scheduler 上通过
OpportunisticBatching
特性门控将其关闭。我们鼓励你在测试集群中试用工作负载感知调度,并分享使用体验, 帮助塑造 Kubernetes 调度的未来。 你可以通过以下方式反馈: