Source: iSlide

Kubernetes 容器調度器的使用情境

Patrick Fu
Gemini Open Cloud 雙子星雲端

--

K8S kube scheduler就是一個容器的調度器,不是一個工作的調度器

在幾星期前這一篇文章中我介紹了Kubernetes 預設的 Kube scheduler:

Kube scheduler 的功能是負責將新建立的Pod分派到最合適的worker Node上。在這個過程中,Kube scheduler 會監控所有被這個叢集管理的worker nodes,並根據使用者訂立的 Filtering 跟 Scoring policy去選擇最理想的worker node。另外我們談到Kube scheduler 目前主要是根據伺服器本身的運行狀況,去派送機器學習工作,並沒有考量到GPU加速器的使用狀況。 所以Gemini 在GPU Partitioning 的功能上,就設計了一個 sharePod 的 scheduler CRD。

Kube Scheduler 派遣容器的模式相對簡單,它只是順序地根據 Create POD request queue去派遣。Kube scheduler 並沒有考慮 POD 跟 POD 間可能有任務跟資源的相關性。但在實際的環境中,一項整體的工作(Job)往往包括多項相關的任務(Task)。這些任務如何被分派到不同的worker node上,對效能會有很大的影響。換句話來說,Kubernetes 預設的 scheduler 只有考慮個別任務根據資源狀況的調度,沒有對整體工作作出考量。

只針對個別任務作調度,沒有考量到其他相關任務缺乏資源及時派遣,都可能會影響到整體工作效能。另外一個可能發生的狀況,就是資源碎片化的問題,會導致整體資源使用率下降。但在最壞情況下,假若應用程式的 timeout recovery 做得不好,更有可能導致deadlock 的情形。

圖一就是一個簡單例子:

圖一. Kube Scheduler 可能會出現資源互鎖的狀況

Scheduler 要調度 Job A 跟 Job B。Job A有兩個Tasks,Job B有三個Tasks。假設我們兩個worker node容量只能派遣兩個Tasks。這樣 Job B 的Task B3,就會被pending,等待派遣。現在假如 Task A2 在worker 2 上要 spawn off 另一個 process,但此時 worker node 已經沒有資源,萬一Job A對這種狀況沒有處理好,那系統就沒有辦法釋出資源去派送 Job B 的Task B3, 導致系統出現deadlock的狀況。

機器學習與HPC工作負載對調度器的需求

雲原生容器架構無疑是人工智慧最流行的環境,但近年來隨著機器學習流程複雜度愈來愈高,就開始暴露了一些Kube scheduler 不足的地方。從AI模型的深度神經網路而言,愈來愈多數據科學家需要傳輸大量訓練數據並使用如Spark、MPI、 Horovoid 等分散式叢集訓練工具(見圖二),Kube scheduler 就沒有自動把這些叢集訓練容器派送到鄰近dataset的K8S worker上,增加了訓練數據傳輸的時間。

圖二. 叢集機器學習模式

另外在開發過程中,人工智慧科學家在定義訓練模型(model definition)過程中,往往要在 Jupyter IDE 上進行多次重覆的訓練。這些模型參數調整的工作雖然數據不多,但卻需要多個相關容器快速地被同時派遣。標準的Kube scheduler 也沒有對一組相關的PODs (PODGroup)有同時派送的機制。

另一個有趣的領域是 HPC。HPC 一向是IT資源的重量級使用者,近年來容器的興起,從某些角度,例如 data analysis 的鏡像工具,CI/CD 的流程,對某些HPC使用者,是非常具吸引性的。但從另一些技術跟使用情境的角度,HPC 跟 Kubernetes 的哲學卻大不相同。

Kubernetes 跟一些傳統的 HPC工作負載管理工具(如 LSF,Slurm 等)不一樣的地方,主要是Kubernetes 比較注重在部署微服務,每個容器通常不會太大,而且很模組化。相對的 HPC應用,通常都包入各式各樣的軟件函式庫,HPC 使用者也有很多需要對拓撲(topology)有敏感度的部署情境,並有需要預約資源,動態搶佔正在運行流程等功能。這一些都是 kube scheduler現成沒有的功能。

Kube Scheduler 的客製化解決方案

有鑑於上述機器學習與HPC應用情境,這幾年來在雲原生社群已有不少人提出了各種Kube Scheduler 客製化的解決方案。以下簡單介紹二種:

  1. Scheduler Extender
  2. Multiple schedulers

Scheduler Extender

雲原生社群早在 2018 年就發表了 Scheduler extender。Scheduler extender 簡單來說就是讓使用者可以 在Kube scheduler 的 Filtering phase、Scoring phase、Binding phase,去定義一些 webhook,來延伸 Kube scheduler 的功能。

在 Kubernetes 推出 Scheduler Framework 之前,Scheduler extender 算是流行的Kube scheduler客製化的方法,但Scheduler extender仍有以下的限制:

  1. 因為是用webhook 做客製化,所以在Scheduler call out時就必需經過HTTP server 的RPC 程序,影響性能。
  2. Webhook 是在 kube scheduler 原來的 filter、Scoring、Binding phase 後才call out,所以客製化是有限制性的。例如已經被 filter 掉的 worker node 就很難更改回來。

Multiple Schedulers

這種做法算是最有彈性,因為沒有任何原來 scheduler 架構的限制。Multiple scheduler 最出名的實作,包括有 Volcano 跟 Kube-Batch。巧的是,這兩個都是為了 Batch job 而設計獨立的調度器。

Multiple schedulers 的意思就是它會跟原來的 Kube scheduler 並存。通常是根據 POD kind,去決定用那一個scheduler。好處當然就是可以自由發揮。但它也有兩個缺點:

  1. 因為兩個scheduler共同管理所有的k8s worker,有可能在scheduler policy上有衝突,導致資源未被充分利用。
  2. 用戶在Kubernetes 升級時,必須做額外的測試,以確保沒有不相容或迴歸測試有狀況出現。

更有擴展性的 Scheduler Framework

Kubernetes 預設的 Kube scheduler,是根據個別任務要求 (Task request) 的順序,逐個派送到最理想的 K8S Worker node 上去部署容器跟POD。換句話說,Kube scheduler 只有對 task 調度,沒有針對整體工作 (Job) 或者效能做考量。由於不同領域的應用,例如 AI、ML、GPU、Batch Job、HPC 等有著不同的工作負載特性,使用者們對於 Kube scheduler 客製化的需求愈來愈強。

Scheduler extender 與多個共存的 Multiple scheduler 都是相當流行的調度器客製化方法,但也有它們的限制。有鑑於此,Kubernetes就提出了一組比 Extender更完整的客製化plugin方案,叫做 Scheduler Framework。

Scheduler Framework 不再利用 webhook,使用者可以用不同語言寫他們的plugin,然後把這些plugin寫在scheduler profile內,即可客製化Kube scheduler 的行為。

Scheduler Framework經過幾版的討論,在 1.18 才推出 beta 版,並在 1.19 版正式推出。

我們下次再來細談 Scheduler Framework 各個可以客製化的節點,以及利用 plugin 可以達成的使用情境。

--

--

Patrick Fu
Gemini Open Cloud 雙子星雲端

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