中文内容
Kubernetes v1.35:引入工作负载感知调度
调度大型工作负载是一项比调度单个 Pod 复杂且脆弱得多的操作,因为它通常需要将所有 Pod 作为整体来考虑,而不是独立调度每一个 Pod。例如,在调度机器学习批处理作业时,通常需要有策略地放置每个 worker,例如放在同一机架上,以尽可能提高整个过程的效率。与此同时,从调度角度看,这类工作负载中的 Pod 往往是相同的,这从根本上改变了该过程应有的形态。
有许多自定义调度器经过适配,可以高效执行工作负载调度;但考虑到工作负载调度对 Kubernetes 用户而言如此常见且重要,尤其是在 AI 时代用例不断增加的背景下,现在正是让工作负载成为 kube-scheduler 一等公民并原生支持它们的时候。
Kubernetes 最近发布的 1.35 版本交付了第一批工作负载感知调度改进。这些改进是更广泛工作的一部分,目标是改进工作负载的调度和管理。该工作将跨越多个 SIG 和多个版本,并将逐步扩展系统能力,朝着其北极星目标推进:在 Kubernetes 中实现无缝的工作负载调度与管理,包括但不限于抢占和自动扩缩容。
Kubernetes v1.35 引入了 Workload API,可用于描述工作负载的期望形态以及面向调度的需求。它附带了 gang scheduling 的初始实现,指示 kube-scheduler 以“全有或全无”的方式调度 gang Pod。最后,我们改进了相同 Pod(通常构成一个 gang)的调度,通过 opportunistic batching 功能加快这一过程。
新的 Workload API 资源属于 scheduling.k8s.io/v1alpha1 API 组。该资源作为多 Pod 应用调度需求的结构化、机器可读定义。面向用户的工作负载(如 Jobs)定义要运行什么,而 Workload 资源决定一组 Pod 应如何被调度,以及其放置应如何在整个生命周期中被管理。
Workload 允许你定义一组 Pod,并对其应用调度策略。下面是一个 gang scheduling 配置的样子。你可以定义一个名为 workers 的 podGroup,并应用 minCount 为 4 的 gang 策略。
apiVersion: scheduling.k8s.io/v1alpha1
kind: Workload
metadata:
name: training-job-workload
namespace: some-ns
spec:
podGroups:
- name: workers
policy:
gang:
# The gang is schedulable only if 4 pods can run at once
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 scheduling 的工作方式
gang 策略强制执行“全有或全无”的放置方式。没有 gang scheduling 时,一个 Job 可能被部分调度,占用资源却无法运行,从而导致资源浪费和潜在死锁。
当你创建属于 gang-scheduled pod group 的 Pod 时,调度器的 GangScheduling 插件会针对每个 pod group(或副本键)独立管理其生命周期:
- 当你创建 Pod(或由控制器代你创建)时,调度器会阻止它们被调度,直到:被引用的 Workload 对象已创建;被引用的 pod group 存在于某个 Workload 中;该组中处于 pending 状态的 Pod 数量达到你的 minCount。
- 一旦有足够的 Pod 到达,调度器就会尝试放置它们。不过,Pod 不会立即绑定到节点,而是会在 Permit gate 处等待。
- 调度器会检查是否已为整个组(至少达到 minCount)找到有效分配。如果该组有足够空间,gate 会打开,所有 Pod 都会绑定到节点。如果在超时时间内(设置为 5 分钟)只有该组 Pod 的一个子集成功完成调度,调度器会拒绝该组中的所有 Pod。它们会回到队列中,释放已预留的资源供其他工作负载使用。
我们想指出,虽然这是首次实现,但 Kubernetes 项目坚定地打算在未来版本中改进并扩展 gang scheduling 算法。我们希望带来的收益包括对整个 gang 的单周期调度阶段、工作负载级抢占等,并朝着北极星目标继续推进。
正文:opportunistic batching
除显式 gang scheduling 外,v1.35 还引入了 opportunistic batching。这是一项 Beta 功能,用于改善相同 Pod 的调度延迟。
与 gang scheduling 不同,此功能不需要 Workload API,也不要求用户显式选择启用。它在调度器内部以机会式方式工作,通过识别具有相同调度需求(容器镜像、资源请求、亲和性等)的 Pod。当调度器处理某个 Pod 时,可以为队列中后续相同的 Pod 复用可行性计算结果,从而显著加快这一过程。
只要 Pod 满足以下条件,大多数用户无需采取任何特殊步骤,就会自动受益于这项优化。
限制
opportunistic batching 在特定条件下工作。kube-scheduler 用于查找放置位置的所有字段,在 Pod 之间都必须相同。此外,使用某些功能会禁用这些 Pod 的批处理机制,以确保正确性。
请注意,你可能需要检查 kube-scheduler 配置,确保它没有隐式地为你的工作负载禁用批处理。
有关限制的更多详细信息,请参阅文档。
北极星愿景
该项目有一个广泛的目标,即交付工作负载感知调度。这些新的 API 和调度增强只是第一步。在不久的将来,这项工作旨在处理:
- 引入工作负载调度阶段
- 改进对多节点 DRA 和 topology aware scheduling 的支持
- 工作负载级抢占
- 改进调度与自动扩缩容之间的集成
- 改进与外部工作负载调度器的交互
- 在工作负载的整个生命周期中管理其放置
- 多工作负载调度模拟
以及更多内容。这些重点领域的优先级和实现顺序可能会发生变化。请继续关注后续更新。
入门
要试用工作负载感知调度改进:
- Workload API:在 kube-apiserver 和 kube-scheduler 上启用 GenericWorkload feature gate,并确保 scheduling.k8s.io/v1alpha1 API 组已启用。
- gang scheduling:在 kube-scheduler 上启用 GangScheduling feature gate(需要启用 Workload API)。
- opportunistic batching:作为 Beta 功能,它在 v1.35 中默认启用。如有需要,你可以在 kube-scheduler 上使用 OpportunisticBatching feature gate 将其禁用。
我们鼓励你在测试集群中试用工作负载感知调度,并分享你的经验,以帮助塑造 Kubernetes 调度的未来。你可以通过以下方式发送反馈:
- 通过 Slack(#sig-scheduling)联系。
- 在工作负载感知调度跟踪 issue 中发表评论。
- 在 Kubernetes repository 中提交新的 issue。
了解更多
- 阅读 Workload API、gang scheduling 和 opportunistic batching 的 KEP。
- 跟踪 Workload aware scheduling issue 以获取最新更新。
- ← 上一篇
- 下一篇 →