Source: iSlide

Kubernetes scheduler 客製化的方法

Patrick Fu
Gemini Open Cloud 雙子星雲端
13 min readAug 18, 2021

--

Kube Scheduler 的任務

K8S工作調度器(Kube Scheduler),是Kubernetes control plane的一個重要元件。它的任務其實很簡單,Kube Scheduler 就是負責監控所有使用者開啓POD的指令,然後根據管理者訂下的「決策」,並配合目前所有worker node資源使用的狀況,去找出最合適的worker node。一旦目標worker node 決定了,Kube Scheduler 就會經由API server 通知該worker node上的Kubelet讀取PodSpec,並開啟Pod 的資源給使用者使用。

這星期跟大家介紹一下管理者跟使用者如何利用上述的決策(就是 Filtering Predicates 跟 Scoring Priorities),去配置 worker node 上的資源。同時,在上次介紹 Kube scheduler使用情境文章中,也提到Kube scheduler 只對個別任務(task)需求的調配,沒有對整體工作(job)的考量,導致不能滿足AI、ML、GPU、Batch、HPC 等等工作負載特性,所以這星期也會跟大家介紹一下在Kubernetes 1.19 推出的Scheduler framework,如何滿足使用者客製化容器調度器的需求。

Kube scheduler 的 Filtering 跟 Scoring 策略

Kube Scheduler 為一個POD挑選出最適合的worker node,是經過Filtering和Scoring兩個步驟,最後把Scoring得分數高的worker node與POD做binding。

管理者可以 經由 kube-scheduler --policy-configmap <ConfigMap>這個指令,去註明一個K8S的叢集,要使用哪些 Filtering Predicates 跟 Scoring Priorities。

Filtering Predicates 包括如PodFitsHostPodFitsResourcesMatchNodeSelectorNoDiskConflict 等預選策略。

Scoring Priorities 則包括如 SpreadPriorityAffinityPriorityLeastRequestPriorityBalancedResourcePriority 等預選策略。

讀者有興趣可參考Ref#5,對各策略的描述。

Filtering 使用情境

使用者可以在PodSpec中,根據管理者定義在scheduler policy裡的predicates, 去註明他希望一個POD被schedule到worker node上的條件。Scheduler會根據這些條件,預選出一些合適的worker nodes。下面舉例說明幾個預選的使用情境:

  1. 使用者可經由Podspec中的NodeSelector directive,指定要根據worker node的標籤(label),去預選適合的worker nodes。Kubernetes by default 已經有定義一些 worker node label,常用到的 label 包括 hostname、OS、arch、region、zone、namespace、instance type 等等。
  2. 使用者也可經由Podspec中的NodeAffinity 指令, 去預選worker node候選人。NodeAffinityNodeSelector功能更為強大,因為它可以註明在scheduling或在Execution時段,考量不同的條件。例如下面這一段 PodSpec,就註明了Nginx這個Pod,一定要被派送到 us-east 機房去執行:

3. Kubernetes 的 Taint & Toleration 機制,跟worker node 標籤,有點反道而行。假如使用者的PodSpec沒有NodeSelector或NodeAffinity directive,所有的worker nodes都會被考慮成候選人,不會被過濾掉。但是,假如管理者一經由 taint 指令 kubectl taint nodes node1 gpu_accelerator=true:NoSchedule去 taint 了一個worker node,所有的Pod都不會assign 到這個worker node 上,除非Podspec裡面有指定的Toleration directive。這邊可能的應用情境是 datacenter有一批GPU worker nodes,IT希望只有做machine learning的容器才會用這些worker node,管理員就可以用上述的指令,把有GPU的worker node,都taintgpu_accelerator 的標籤。所有做AI 的容器podspec就得加進Toleration directive,去註明 gpu_accelerator=TRUE ,才會有可能被派送到這些worker nodes 上。

Scoring 使用情境

Kube scheduler scoring機制,就是針對Filtering predicates 過濾後的每一個候選人worker node,根據Scoring Priority打一個分數(1~10分)。這個分數再乘上一個權重,然後把所有priority的得分加起來,就是這個worker node 的評分。最後 scheduler 會把該POD派送到評分最高的worker node上去做Binding。

Scoring 的使用情境,通常是幫助管理者如何有效地分配worker nodes資源. 舉例來說,管理者可以把 worker nodes 分成不同的資源池,每個資源池有它不同的優先順序(priority class),使用者可以在Pod spec 內註明他比較傾向哪一個優先順序(e.g. LeastRequestedPriority)。Scheduler就會根據當下在不同資源池中可被使用的worker node,打一個分數。如上所述,Priorities 有包括 SelectorSpreadPriority(輪流分配)、InterPodAffinityPriority(親和關係分配)、LeastRequestedPriority(被要求頻率分配), BalancedResourceAllocate(平均資源分配)等。

值得一提的是 scoring 的額外開銷 (overhead)。假如worker node的數目龐大,就算經過 Predicate filtering,候選人worker node 的數量可能還是會很高。這時對每一個worker node去進行優選計分,overhead 可能會很大。所以在Kube-scheduler config file 內,還提供了 一個 percentageOfNodesToScore 的選項,去限制在候選人worker node 群組中,只需要對一部分的候選人worker nodes 去做 scoring,以減低scheduler pipeline 的overhead。

Kubernetes 1.19 新的 Scheduler Framework

上述 Kube scheduler管理員的各種配置方案,跟使用者在Podspec 內的選項,已經提供了很多調度容器客製化的功能。但由於Kube scheduler基本上不會考慮一個工作(job)內各個POD 的相關性跟整個叢集的硬體拓撲(topology),所以這幾年來也有不少Kube scheduler 客製化的方法,包括了 Scheduler Extender 跟 Multiple Scheduler。可惜的是這些客製方案都有它的缺點(請參閱上一期的文章):

所以 Kubernetes在 1.19 版中,就加了一個全新的scheduler framework,提供開發人員在scheduler 流程的每個步驟 — Queueing、Filtering、Scoring、Binding,都可以加入插件 (Plugin),直接客製化 Kube scheduler的功能。下圖是新的scheduler framework pipeline的流程圖:

Kubernetes 1.19 Scheduler Framework

以下簡單解釋各插入點跟可能的使用情境:

QueueSort

此插件可以重組待調度的客器隊列的優先處理順序。這可以幫助有多個相關等待調度的容器,可以讓scheduler 同時處理。

PreFilter

過濾前置作業。此插件可以根據容器的任務,先期決定某些worker nodes,是否適合該任務。

Filter

Kube scheduler 會對應每一個通過Filtering Predicates的worker node,呼叫這個插件。插件就可以進一步考量是否把work node 留在候選人名單上

PostFilter

過濾後續作業。假若Filter 步驟,沒有找到任何的worker node,Kube scheduler 會呼叫這個插件,去決定如何繼續調度流程。

PreScore

Scoring 前置作業。為了增加效能,前置作業插件可以 先算出當下叢集運行狀況,並緩存 (cache) 在記憶體內,增加scoring 運算速度。

Score

Kube scheduler的優選過程,對應每個候選人worker node算出一個分數。此時Scheduler就會呼叫 Scoring插件。插件可以調整此worker node 的比重或評分,影響最後binding 的決定。

Reserve/Unreserve

當Scheduler替一個POD選定了一個worker node後,就會進行binding。但binding 可能是一個需時的operation,有兩個可能原因:

  1. Binding phase還可能要等目標worker node 把資源配置出來,或者
  2. 該POD需要等另外一個POD被schedule好後一起dispatch。

因此便有一個 Reserve/Unreserve 插件。Reserve 是保留目標worker node,一會被其他scheduler考慮,避免race condition。Unreserve 是留給Binding 不成功的狀況下,再把目標worker node釋放出來。

Permit

此插件是提供在特別情況下,binding 一個POD 到一個worker node需要外部的批准流程才能把worker node 釋放給該POD使用.

Prebind

有一些POD被dispatch 到worker node 前需要一些特別的動作(例如 mount volume),此時就會呼叫prebind 插件去做這些事。

Bind

Bind 插件會被呼叫,使用者可以決定這個 worker node assign給POD之後,是否需要呼叫 post-bind 插件。

PostBind

這個插件是預備不時之需,在binding 成功後要做某一些cleanup 的事情。

如何定義 scheduler framework 插件與使用不同的scheduler profile

以上每個插入點對scheduler framework 來說都叫一個擴展點 (Extension point)。Kubernetes 1.19 scheduler framework 還加了一個新的功能叫scheduler profile,就是說使用者可以針對不同的 POD kind,定義不同 的 scheduler profile,步驟如下:

  1. 針對使用者所需修改的 extension point,編寫插件。
  2. 把新編寫的plugin 註冊到scheduler framework內。
  3. 重新啟動scheduler
  4. 使用者可以在scheduler config file 中,把plugin 加到某個extension point 內。舉例來說,下圖就把MyCustomPluginA 跟 MyCustomerPluginB 加到 default scheduler and Score extension point 內,並同時把NodeResourcesLeastAllocated plugin disable掉。

5. 使用者也可以定義一個新的profile。Profile內可以enable 或 disable 每個 extension point 的plugin。舉例來說,下圖就定義了一個新的 scheduler profile 叫 no-scoring-scheduler ,把 preScore 跟 Score extension point 的plugin 都disable 掉。

6. 假如 PodSpec內沒有註明scheduler,Kubernetes controller 會使用default-scheduler。假如使用者對某種Podkind (e.g. Job),要用 no-scoring-scheduler,則可在 job 的podspec 內加入 scheduler directive,並註明使用 .spec.no-scoring-scheduler

Reference

  1. https://alibaba-cloud.medium.com/getting-started-with-kubernetes-scheduling-process-and-scheduler-algorithms-847e660533f1
  2. https://granulate.io/a-deep-dive-into-kubernetes-scheduling/
  3. https://www.cncf.io/blog/2020/08/10/why-the-kubernetes-scheduler-is-not-enough-for-your-ai-workloads/
  4. https://www.hpcwire.com/solution_content/ibm/cross-industry/the-pros-and-cons-of-kubernetes-for-hpc/
  5. https://kubernetes.io/docs/reference/scheduling/policies/
  6. https://kubernetes.io/docs/concepts/scheduling-eviction/scheduling-framework/
  7. https://ieeexplore.ieee.org/document/8672301/authors#authors

--

--

Patrick Fu
Gemini Open Cloud 雙子星雲端

符儒嘉於美國矽谷資訊軟體業工作約30 年,曾在IBM、Amdahl、Sun、Interwoven任職,2009回國加入雲端中心之研發團隊,擔任雲端中心關鍵計畫Cloud OS 系統軟體開發之計畫主持人,將其在美國所累積的系統軟體開發知識與經驗,運用於雲端中心之計畫執行中。