这篇文章已经一年多了,较旧的文章可能包含过时的内容。请检查从发表以来,页面中的信息是否变得不正确。
Kubernetes 1.26:Pod 调度就绪态
作者: Wei Huang (Apple), Abdullah Gharaibeh (Google)
译者: XiaoYang Zhang (HuaWei)
Kubernetes 1.26 引入了一个新的 Pod 特性:调度门控。在 Kubernetes 中,调度门控是通知调度器何时可以考虑 Pod 调度的关键。
它解决了什么问题?
当 Pod 被创建时,调度器会不断尝试寻找适合它的节点。这个无限循环一直持续到调度程序为 Pod 找到节点,或者 Pod 被删除。
长时间无法被调度的 Pod(例如,被某些外部事件阻塞的 Pod)会浪费调度周期。一个调度周期可能需要约 20ms 或更长时间,这取决于 Pod 的调度约束的复杂度。因此,大量浪费的被调度周期会严重影响调度器的性能。请参阅下面 “调度器” 框中的箭头。
调度门控有助于解决这个问题。它允许声明新创建的 Pod 尚未准备好进行调度。当 Pod 上设置了调度门控时,调度程序会忽略该 Pod,从而避免不必要的调度尝试。如果你在集群中安装了 Cluster Autoscaler,这些 Pod 也将被忽略。
清除门控是外部控制器的责任,外部控制器知道何时应考虑对 Pod 进行调度(例如,配额管理器)。
它是如何工作的?
总体而言,调度门控的工作方式与 Finalizer 非常相似。具有非空 spec.schedulingGates 字段的 Pod的状态将显示为 SchedulingGated,并阻止被调度。请注意,添加多个门控是可以的,但它们都应该在创建 Pod时添加(例如,你可以将它们作为规约的一部分或者通过变更性质的 Webhook)。
NAME READY STATUS RESTARTS AGE
test-pod 0/1 SchedulingGated 0 10s
要清除这些门控,你可以通过删除 Pod 的 schedulingGates 字段中的所有条目来更新 Pod。不需要一次性移除所有门控,但是,只有当所有门控都移除后,调度器才会开始考虑对 Pod 进行调度。
在后台,调度门控以 PreEnqueue 调度器插件的方式实现,这是调度器框架的新扩展点,在每个调度周期开始时调用。
用例
此特性所支持的一个重要使用场景是动态配额管理。Kubernetes 支持资源配额,但是 API Server 会在你尝试创建 Pod 时强制执行配额。例如,如果一个新的 Pod 超过了 CPU 配额,它就会被拒绝。API Server 不会对 Pod 进行排队;因此,无论是谁创建了 Pod,都需要不断尝试重新创建它。这意味着在资源可用和 Pod 实际运行之间会有延迟,或者意味着由于不断尝试,会增加 API Server 和 Scheduler 的负载。
调度门控允许外部配额管理器解决 ResourceQuota 的上述限制。具体来说,管理员可以(使用变更性质的 Webhook)为集群中创建的所有 Pod 添加一个example.com/quota-check 调度门控。当存在用于启动 Pod 的配额时,管理器将移除此门控
接下来
要使用此特性,必须在 API Server 和调度器中启用 PodScheduleingReadiness 特性门控。非常欢迎你对其进行测试并告诉我们(SIG Scheduling)你的想法!
附加资源
- Kubernetes 文档中的 Pod 调度就绪态
- Kubernetes 增强提案