本文发布时间已超过一年。较旧的文章可能包含过时内容。请检查页面中的信息自发布以来是否已不准确。
Kubernetes 1.26:Pod 调度就绪
Kubernetes 1.26 引入了一个新的 Pod 特性:调度门控 (scheduling gates)。在 Kubernetes 中,调度门控是告诉调度器何时可以考虑调度一个 Pod 的关键。
它解决了什么问题?
创建 Pod 后,调度器会不断尝试为其找到合适的节点。这个无限循环会一直持续,直到调度器为 Pod 找到节点,或者 Pod 被删除。
长期处于不可调度状态的 Pod(例如,被某些外部事件阻塞的 Pod)会浪费调度周期。一个调度周期可能需要约 20 毫秒或更长时间,具体取决于 Pod 调度约束的复杂性。因此,在大规模环境下,这些浪费的周期会显著影响调度器的性能。请参阅下方“调度器”框中的箭头。
调度门控有助于解决此问题。它允许声明新创建的 Pod 尚未准备好进行调度。当 Pod 上存在调度门控时,调度器会忽略该 Pod,从而节省不必要的调度尝试。如果你在集群中安装了 Cluster Autoscaler,这些 Pod 也将被其忽略。
清除门控是外部控制器负责的任务,这些控制器了解何时应该考虑调度该 Pod(例如,配额管理器)。
它是如何工作的?
调度门控的工作原理与 Finalizers 非常相似。spec.schedulingGates
字段非空的 Pod 将显示状态为 SchedulingGated
,并被阻止调度。请注意,可以添加多个门控,但它们都应在创建 Pod 时添加(例如,你可以将它们作为 spec 的一部分添加,或通过 mutating webhook 添加)。
NAME READY STATUS RESTARTS AGE
test-pod 0/1 SchedulingGated 0 10s
要清除门控,你需要更新 Pod,移除 Pod 的 schedulingGates
字段中的所有项。门控不需要一次性全部移除,只有当所有门控都被移除时,调度器才会开始考虑调度该 Pod。
在底层,调度门控被实现为一个 PreEnqueue 调度器插件,这是一个新的调度器框架扩展点,在每个调度周期开始时被调用。
使用场景
此特性实现的一个重要使用场景是动态配额管理。Kubernetes 支持ResourceQuota,但 API Server 会在你尝试创建 Pod 时强制执行配额。例如,如果一个新 Pod 超出了 CPU 配额,它将被拒绝。API Server 不会将该 Pod 排队;因此,创建该 Pod 的人需要不断地尝试重新创建它。这要么意味着资源可用与 Pod 实际运行之间存在延迟,要么意味着由于持续尝试而增加了 API Server 和调度器的负载。
调度门控允许外部配额管理器解决上述 ResourceQuota 的限制。具体而言,管理器可以为集群中创建的所有 Pod 添加一个 example.com/quota-check
调度门控(使用 mutating webhook)。当有配额可供启动 Pod 时,管理器就会移除该门控。
后续计划?
要使用此特性,必须在 API Server 和调度器中启用 PodSchedulingReadiness
特性门控。非常欢迎你进行测试并告诉我们(SIG Scheduling)你的想法!
更多资源
- Kubernetes 文档中的Pod Scheduling Readiness
- Kubernetes 增强提案 (KEP)