Kubernetes 1.26 引入了 Pod 的一个新特性:scheduling gates
。在 Kubernetes 中,调度门是告诉调度程序何时准备好考虑调度 Pod 的 keys。
当一个 Pod 创建时,调度器会不断尝试寻找适合它的节点。这个无限循环一直持续到调度程序找到 Pod 的节点,或者 Pod 被删除。
长时间保持不可调度的 Pod(例如,在某些外部事件上被阻塞的 Pod)会浪费调度周期。根据 Pod 调度约束的复杂性,一个调度周期可能需要 ≅20ms 或更多。因此,在大规模情况下,这些浪费的周期会明显影响调度程序的性能。请参阅下面 调度程序
框中的箭头。
调度门有助于解决这个问题。它允许声明新创建的 Pod 尚未准备好进行调度。当 Pod 上存在调度门时,调度程序会忽略该 Pod,从而避免不必要的调度尝试。如果您在集群中安装了 Cluster Autoscaler,这些 Pod 也会被忽略。
清除门是外部控制器的责任,外部控制器知道何时应考虑对 Pod 进行调度(例如,配额管理器 quota manager)。
调度门的一般工作方式与终结器非常相似。具有非空 spec.schedulingGates
字段的 Pod 将显示为状态SchedulingGated
并被阻止调度。请注意,可以添加多个门,但它们都应该在创建 Pod 时添加(例如,您可以将它们添加为 spec
的一部分或通过 mutating webhook
)。
NAME READY STATUS RESTARTS AGE
test-pod 0/1 SchedulingGated 0 10s
要清除 gates,您可以通过从 Pod 的 schedulingGates
字段中删除所有元素来更新 Pod。不需要一次性全部移除 gate,但只有当所有 gate 都移除后,调度器才会开始考虑 Pod 进行调度。
在底层,调度门实现为一个 PreEnqueue 调度器插件,这是一个新的调度程序框架扩展点,在每个调度周期开始时调用。
此功能启用的一个重要用例是动态配额管理。Kubernetes 支持 ResourceQuota[1],但是 API Server
会在您尝试创建 Pod 时强制执行配额。例如,如果一个新的 Pod 超过了 CPU 配额,它就会被拒绝。API Server 不会对 Pod 进行排队;因此,无论是谁创建了 Pod,都需要不断尝试重新创建它。这要么意味着资源变得可用和 Pod 实际运行之间的延迟,要么意味着由于不断尝试而导致 API 服务器和调度器负载高。
调度门(Scheduling gates)允许外部配额管理器解决 ResourceQuota 的上述限制。具体来说,管理器可以为集群中创建的所有 Pods 添加一个 example.com/quota-check
调度门(使用mutating webhook
)。然后,当有配额足够启动 Pod 时,manager
将移除门。
要使用此功能,必须在 API 服务器和调度程序中启用PodSchedulingReadiness
功能门。非常欢迎您对其进行测试并告诉(SIG 调度)您的想法!另外请参考:
[1]
ResourceQuota: https://kubernetes.io/docs/concepts/policy/resource-quotas/
[2]
Pod Scheduling Readiness: https://kubernetes.io/docs/concepts/scheduling-eviction/pod-scheduling-readiness/
[3]
Kubernetes 增强提案: https://github.com/kubernetes/enhancements/blob/master/keps/sig-scheduling/3521-pod-scheduling-readiness/README.md