本文已超過一年。較舊的文章可能包含過時的內容。請檢查頁面中的資訊自發佈以來是否已變得不正確。

Kubernetes 1.26:Pod 排程就緒

Kubernetes 1.26 引入了一項新的 Pod 功能:排程閘道。在 Kubernetes 中,排程閘道是一些金鑰,可告知排程器何時可以將 Pod 視為可排程。

它解決了什麼問題?

當建立 Pod 時,排程器將持續嘗試尋找適合它的節點。此無限迴圈會持續到排程器找到 Pod 的節點,或 Pod 被刪除為止。

長時間保持無法排程的 Pod (例如,那些受某些外部事件阻礙的 Pod) 會浪費排程週期。排程週期可能需要 ≅20 毫秒或更長時間,具體取決於 Pod 排程約束的複雜性。因此,大規模而言,這些浪費的週期會顯著影響排程器的效能。請參閱下方「排程器」方塊中的箭頭。

graph LR; pod((新 Pod))-->queue subgraph 排程器 queue(排程器佇列) sched_cycle[/排程週期/] schedulable{可排程?} queue==>|彈出|sched_cycle sched_cycle==>schedulable schedulable==>|否|queue subgraph note [在持續重新排程「未就緒」Pod 上浪費的週期] end end classDef plain fill:#ddd,stroke:#fff,stroke-width:1px,color:#000; classDef k8s fill:#326ce5,stroke:#fff,stroke-width:1px,color:#fff; classDef Scheduler fill:#fff,stroke:#bbb,stroke-width:2px,color:#326ce5; classDef note fill:#edf2ae,stroke:#fff,stroke-width:1px; class queue,sched_cycle,schedulable k8s; class pod plain; class note note; class Scheduler Scheduler;

排程閘道有助於解決此問題。它允許宣告新建立的 Pod 尚未準備好進行排程。當 Pod 上存在排程閘道時,排程器會忽略 Pod,因此節省了不必要的排程嘗試。如果您在叢集中安裝了叢集自動擴展器,這些 Pod 也會被叢集自動擴展器忽略。

清除閘道是外部控制器的責任,這些控制器了解何時應將 Pod 視為可排程 (例如,配額管理器)。

graph LR; pod((新 Pod))-->queue subgraph 排程器 queue(排程器佇列) sched_cycle[/排程週期/] schedulable{可排程?} popout{彈出?} queue==>|PreEnqueue 檢查|popout popout-->|是|sched_cycle popout==>|否|queue sched_cycle-->schedulable schedulable-->|否|queue subgraph note [用於閘控 Pod 排程的旋鈕] end end classDef plain fill:#ddd,stroke:#fff,stroke-width:1px,color:#000; classDef k8s fill:#326ce5,stroke:#fff,stroke-width:1px,color:#fff; classDef Scheduler fill:#fff,stroke:#bbb,stroke-width:2px,color:#326ce5; classDef note fill:#edf2ae,stroke:#fff,stroke-width:1px; classDef popout fill:#f96,stroke:#fff,stroke-width:1px; class queue,sched_cycle,schedulable k8s; class pod plain; class note note; class popout popout; class Scheduler Scheduler;

它是如何運作的?

一般而言,排程閘道的工作方式與 Finalizers 非常相似。具有非空 spec.schedulingGates 欄位的 Pod 將顯示為狀態 SchedulingGated,並被阻止排程。請注意,可以新增多個閘道,但它們都應在 Pod 建立時新增 (例如,您可以將它們新增為規格的一部分或透過 mutating webhook)。

NAME       READY   STATUS            RESTARTS   AGE
test-pod   0/1     SchedulingGated   0          10s

若要清除閘道,您可以透過從 Pod 的 schedulingGates 欄位中移除所有項目來更新 Pod。閘道不需要一次全部移除,但只有在移除所有閘道後,排程器才會開始考慮排程 Pod。

在底層,排程閘道實作為 PreEnqueue 排程器外掛程式,這是一個新的排程器框架擴充點,在每個排程週期的開始時調用。

使用案例

此功能啟用的一個重要使用案例是動態配額管理。Kubernetes 支援 ResourceQuota,但是 API Server 會在您嘗試建立 Pod 時強制執行配額。例如,如果新的 Pod 超出 CPU 配額,則會遭到拒絕。API Server 不會將 Pod 排入佇列;因此,建立 Pod 的人需要不斷嘗試再次重新建立它。這表示資源可用與 Pod 實際執行之間會延遲,或者表示 API 伺服器和排程器由於不斷嘗試而產生負載。

排程閘道允許外部配額管理器解決 ResourceQuota 的上述限制。具體而言,管理器可以將 example.com/quota-check 排程閘道新增至叢集中建立的所有 Pod (使用 mutating webhook)。然後,當有配額啟動 Pod 時,管理器將移除閘道。

下一步是什麼?

若要使用此功能,必須在 API Server 和排程器中啟用 PodSchedulingReadiness 功能閘道。非常歡迎您測試它並告訴我們 (SIG Scheduling) 您的想法!

其他資源