Koordinator v0.7: 為任務排程領域注入新活力

語言: CN / TW / HK

作者:李濤(呂風)

Koordinator [ 1] 繼上次 v0.6版本​ [ 2] 釋出後,經過 Koordinator 社群的努力,我們迎來了具有重大意義的 v0.7 版本。在這個版本中著重建設了機器學習、大資料場景需要的任務排程能力,例如 Coscheduling、ElasticQuota 和精細化的 GPU 共享排程能力。並在排程問題診斷分析方面得到了增強,重排程器也極大的提升了安全性,降低了重排程的風險。

版本功能特性解讀

任務排程

Enhanced Coscheduling

Gang scheduling 是在併發系統中將多個相關聯的程序排程到不同處理器上同時執行的策略,其最主要的原則是保證所有相關聯的程序能夠同時啟動,防止部分程序的異常,導致整個關聯程序組的阻塞。例如當提交一個 Job 時會產生多個任務,這些任務期望要麼全部排程成功,要麼全部失敗。這種需求稱為 All-or-Nothing,對應的實現被稱作 Gang Scheduling(or Coscheduling) 。

Koordinator 在啟動之初,期望支援 Kubernetes 多種工作負載的混部排程,提高工作負載的執行時效率和可靠性,其中就包括了機器學習和大資料領域中廣泛存在的具備 All-or-Nothing 需求的作業負載。為了解決 All-or-Nothing 排程需求,Koordinator v0.7.0 基於社群已有的 Coscheduling 實現了 Enhanced Coscheduling。

Enhanced Coscheduling 秉承著 Koordiantor 相容社群的原則,完全相容社群 scheduler-plugins/Coscheduling 和依賴的 PodGroup CRD。已經使用 PodGroup 的使用者可以無縫升級到 Koordinator。

除此之外,Enhanced Coscheduling 還實現瞭如下增強能力:

1. 支援 Strict 和 NonStrict 兩種模式

scheduler-plugins/Coscheduling 在排程失敗時會 Reject 所有分配到資源但處於 Wait 狀態的 Pod。這種模式我們定義為 Strict 模式,也是預設模式。但這種模式對於體量較大的 Job 並不是很友好,有可能會導致這種大體量的 Job 拿不到資源。為了解決這個問題,我們允許排程失敗時不立即 Reject,並通過重試排程嘗試拿到資源滿足 MinMember。這種模式我們稱為 NonStrict。雖然這種模式對於體量大的 Job 友好,可以讓這種 Job 更快的排程完成,但同時也增加了資源死鎖的風險。後續 Koordinator 會提供 NonStrict 模式下解決死鎖的方案實現。

要使用這種模式也比較簡單,在 PodGroup 或者 Pod 中追加 annotation gang.scheduling.koordinator.sh/mode=NonStrict 開啟 NonStrict 模式。

2. 改進 PodGroup 排程失敗的處理機制,實現更高效的重試排程

社群 scheduler-plugins/Coscheduling 在排程失敗後會在一段時間不在嘗試處理該 PodGroup。這個時間一般是 20 秒。並且只支援按照外掛維度配置,不支援使用者按業務配置不同的時間。另外這種時間引數一般也難配置合適的值。

而在 Enhanced Coscheduling 中,實現了一種基於 ScheduleCycle 的重試機制。可以簡單的理解為一種熔斷機制。每個 PodGroup 會有一個單調遞增的變數,我們定義為 ScheduleCycle(PodGroup),初始值為 1。該 PodGroup 關聯的所有 Pod 也有一個 ScheduleCycle 變數,我們定義為 ScheduleCycle(Pod),初始值為 ScheduleCycle(PodGroup) - 1。每次 Pod 排程時,ScheduleCycle(Pod) 等於當前 ScheduleCycle(PodGroup)。

當一個 PodGroup 中的一個 Pod 排程失敗時,會標記當前的 ScheduleCycle(PodGroup) 無效,後續其他 Pod 都會排程失敗。當該 PodGroup 中所有 Pod ScheduleCycle(Pod) 都與當前 ScheduleCycle(PodGroup) 相等時,ScheduleCycle(PodGroup) 開始遞增,允許重新開始進行排程。這種方式可以有效規避基於過期時間的缺陷,完全取決於排程佇列的配置重試排程。

1.png

基於 ScheduleCycle 的重試機制

3. 支援多個 PodGroup 為一組完成 Gang Scheduling

一些複雜的 Job 有多種角色,每個角色管理一批任務,每個角色的任務要求支援 All-or-Nothing ,每個角色的 MinMember 要求也不一樣,並且每個角色之間也要求 All-or-Nothing。這就導致每個角色都有一個對應的 PodGroup ,並且還要求 PodGroup 即使滿足了也需要等待其他角色的 PodGroup 必須滿足。社群 Coscheduling 無法滿足這種場景需求。而 Koordinator 實現的 Enhanced Coscheduling 支援使用者在多個 PodGroup 中增加 anntation 相關關聯實現,並支援跨Namespace。例如使用者有 2 個 PodGroup ,名字分別是PodGroupA 和 PodGroupB,可以按照如下例子關聯兩個 PodGroup:

apiVersion: v1alpha1 kind: PodGroup metadata: name: podGroupA namespace: default annotations: gang.scheduling.koordinator.sh/groups: ["namespaceA/podGroupA", "namespaceB/podGroupB"] spec: ...

4. 支援輕量化 Gang 協議

如果使用者不希望建立 PodGroup,認為建立 PodGroup 太繁瑣,那麼可以考慮在一組 Pod 中填充相同的  annotation  gang.scheduling.koordinator.sh/name= 表示這一組 Pod 使用 Coscheduling 排程。如果期望設定 minMember ,可以追加  Annotation gang.scheduling.koordinator.sh/min-available=。舉個例子:

apiVersion: v1 kind: Pod metadata: annotations: gang.scheduling.koordinator.sh/name: "pod-group-a" gang.scheduling.koordinator.sh/min-available: "5" name: demo-pod namespace: default spec: ...

ElasticQuota Scheduling

一家中大型公司內有多個產品和研發團隊,共用多個比較大規模的 Kubernetes 叢集,這些叢集內含有的大量 CPU/Memory/Disk 等資源被資源運營團隊統一管理。運營團隊往往在採購資源前,通過額度預算的機制讓公司內每個團隊根據自身的需求提交額度預算。業務團隊此時一般根據業務當前和對未來的預期做好額度預算。最理想的情況是每一份額度都能夠被使用,但現實告訴我們這是不現實的。往往出現的問題是:

  1. 團隊 A 高估了業務的發展速度,申請了太多的額度用不完
  2. 團隊 B 低估了業務的發展速度,申請的額度不夠用
  3. 團隊 C 安排了一場活動,手上的額度不夠多了,但是活動只持續幾周,申請太多額度和資源也會浪費掉。
  4. 團隊 D 下面還有各個子團隊和業務,每個子團隊內也會出現類似 A B C 三個團隊的情況,而且其中有些團隊的業務臨時突發需要提交一些計算任務要交個客戶,但是沒有額度了,走額度預算審批也不夠了。
  5. ...... 

以上大家日常經常遇到的場景,在混部場景、大資料場景,臨時性突發需求又是時常出現的,這些資源的需求都給額度管理工作帶來了極大的挑戰。做好額度管理工作,一方面避免過度採購資源降低成本,又要在臨時需要額度時不採購資源或者儘量少的採購資源;另一方面不能因為額度問題限制資源使用率,額度管理不好就會導致即使有比較好的技術幫助複用資源,也無法發揮其價值。總之,額度管理工作是廣大公司或組織需長期面對且必須面對的問題。

Kubernetes ResourceQuota 可以解決額度管理的部分問題。原生 Kubernetes ResourceQuota API 用於指定每個 Namespace 的最大資源額度量,並通過 admission 機制完成准入檢查。如果 Namespace 當前資源分配總量超過 ResourceQuota 指定的配額,則拒絕建立 Pod。Kubernetes ResourceQuota 設計有一個侷限性:Quota  用量是按照 Pod Requests 聚合的。雖然這種機制可以保證實際的資源消耗永遠不會超過 ResourceQuota 的限制,但它可能會導致資源利用率低,因為一些 Pod 可能已經申請了資源但未能排程。

Kuberenetes Scheduler-Sig 後來給出了一個借鑑 Yarn Capacity Scheduling,稱作 ElasticQuota 的設計方案並給出了具體的實現。允許使用者設定 max 和 min:

  • max 表示使用者可以消費的資源上限
  • min 表示需要保障使用者實現基本功能/效能所需要的最小資源量  

通過這兩個引數可以幫助使用者實現如下的需求:

  1. 使用者設定 min < max 時,當有突發資源需求時,即使當前 ElasticQuota 的總用量超過了 min, 但只要沒有達到 max,那麼使用者可以繼續建立新的 Pod 應對新的任務請求。
  2. 當用戶需要更多資源時,使用者可以從其他 ElasticQuota 中“借用(borrow)” 還沒有被使用並且需要通保障的 min。
  3. 當一個 ElasticQuota 需要使用 min 資源時,會通過搶佔機制從其他借用方搶回來,即驅逐一些其他 ElasticQuota 超過 min 用量的 Pod。  

ElasticQuota 還有一些侷限性:沒有很好的保障公平性。假如同一個 ElasticQuota 有大量新建的 Pod,有可能會消耗所有其他可以被借用的 Quota,從而導致後來的 Pod 可能拿不到 Quota。此時只能通過搶佔機制搶回來一些 Quota。

另外 ElasticQuota 和 Kubernetes ResourceQuota 都是面向 Namespace 的,不支援多級樹形結構,對於一些本身具備複雜組織關係的企業/組織不能很好的使用 ElasticQuota/Kubenretes ResourceQuota 完成額度管理工作。

Koordinator 針對這些額度管理問題,給出了一種基於社群 ElasticQuota 實現的支援多級管理方式的彈性 Quota 管理機制(multi hierarchy quota management)。具備如下特性:

  • 相容社群的 ElasticQuota API。使用者可以無縫升級到 Koordinator
  • 支援樹形結構管理 Quota。
  • 支援按照共享權重(shared weight)保障公平性。
  • 允許使用者設定是否允許借用 Quota 給其他消費物件。 
1. Pod 關聯 ElasticQuota 方式

使用者可以非常使用的使用該能力,可以完全按照 ElasticQuota 的用法,即每個 Namespace 設定一個 ElasticQuota 物件。也可以在 Pod 中追加 Label 關聯 ElasticQuota:

apiVersion: v1 kind: Pod metadata: labels: quota.scheduling.koordinator.sh/name: "elastic-quota-a" name: demo-pod namespace: default spec: ...

2. 樹形結構管理機制和使用方法

需要使用樹形結構管理 Quota 時,需要在 ElasticQuota 中追加 Label  quota.scheduling.koordinator.sh/is-parent表示當前 ElasticQuota 是否是父節點,quota.scheduling.koordinator.sh/parent表示當前 ElasticQuota 的父節點 ElasticQuota 的名字。舉個例子:

2.png

我們建立一個 ElasticQuota parentA 作為父節點,資源總量為CPU 100C,記憶體 200Gi,以及子節點 childA1

``` apiVersion: scheduling.sigs.k8s.io/v1alpha1 kind: ElasticQuota metadata: name: parentA namespace: default labels: quota.scheduling.koordinator.sh/is-parent: "true" quota.scheduling.koordinator.sh/allow-lent-resource: "true" spec: max: cpu: 100 memory: 200Gi min: cpu: 100 memory: 200Gi


apiVersion: scheduling.sigs.k8s.io/v1alpha1 kind: ElasticQuota metadata: name: childA1 namespace: default labels: quota.scheduling.koordinator.sh/is-parent: "false" quota.scheduling.koordinator.sh/parent: "parentA" quota.scheduling.koordinator.sh/allow-lent-resource: "true" spec: max: cpu: 40 memory: 100Gi min: cpu: 20 memory: 40Gi ```

在使用樹形結構管理 ElasticQuota 時,有一些需要遵循的約束:

  1. 除了根節點,其他所有子節點的 min 之和要小於父節點的 min。 

  2. 不限制子節點 max,允許子節點的 max 大於父節點的 max。考慮以下場景,叢集中有 2 個 ElasticQuota 子樹:dev-parent 和 production-parent,每個子樹都有幾個子 ElasticQuota。當 production-parent 忙時,我們可以通過只降低 dev-parent 的 max 限制  dev-parent 整顆子樹的資源使用量,而不是降低 dev-parent 子樹的每個子 ElasticQuota 的 max 限制用量。 

  3. Pod 不能使用父節點 ElasticQuota。如果放開這個限制,會導致整個彈性 Quota 的機制變的異常複雜,暫時不考慮支援這種場景。 

  4. 只有父節點可以掛子節點,不允許子節點掛子節點。 

  5. 暫時不允許改變 ElasticQuota 的 quota.scheduling.koordinator.sh/is-parent 屬性 

我們將在下個版本中通過 webhook 機制實現這些約束。

3. 公平性保障機制

Koordinator ElasticQuota  支援按照共享權重(shared weight)保障公平性。shared-weight 表示一個 ElasticQuota 物件 的競爭力,預設等於 ElasticQuota Max。通過公平性保障機制,會給所有 min < max 的 ElasticQuota 分配實際可用的資源量,該資源量用 runtime表示,並保障 runtime 在min 與 max 之間,即 max >= runtime >= min。

當一個 ElasticQuota 物件關聯的所有 Pod 的資源請求量(我們定義為 request)大於 min 時,會借用其他 ElasticQuota 物件中 min 未分配的部分。被借出去的 Quota 需要使用時,會再次通過該公平性保障機制拿回來。

另外還有一種日常生產時會遇到的情況:即叢集內資源總量會隨著節點故障、資源運營等原因降低,導致所有 ElasticQuota 的 min 之和大於資源總量。當出現這種情況時,我們無法確保 min 的資源需求。此時我們會按照一定的比例調整各個 ElasticQuota 的 min,確保所有 min 之和小於或者等於當前實際的資源總量。

4. 搶佔機制

Koordinator ElasticQuota 機制在排程階段如果發現 Quota 不足,會進入搶佔階段,按照優先順序排序,搶佔屬於同一個ElasticQuota 內的 低優先順序 Pod。同時,我們不支援跨 ElasticQuota 搶佔其他 Pod。但是我們也提供了另外的機制支援從借用 Quota 的 ElasticQuota 搶回。

舉個例子,在叢集中,有兩個 ElasticQuota,ElasticQuota A {min = 50, max = 100}, ElasticQuota B {min = 50,  max = 100}。使用者在上午 10 點使用 ElasticQuota A 提交了一個 Job, Request = 100 ,此時因為 ElasticQuota B 無人使用,ElasticQuota A 能從 B 手裡借用 50 個 Quota,滿足了 Request = 100, 並且此時 Used = 100。在 11 點鐘時,另一個使用者開始使用 ElasticQuota B 提交 Job,Request = 100,因為 ElasticQuota B 的 min = 50,是必須保障的,通過公平性保障機制,此時 A 和 B 的 runtime 均為 50。那麼此時對於 ElasticQuota A ,Used = 100 是大於當前 runtime = 50 的,因此我們會提供一個 Controller,驅逐掉一部分 Pod ,使得當前 ElasticQuota A 的 Used 降低到 runtime 相等的水位。

精細化資源排程

Device Share Scheduling

機器學習領域裡依靠大量強大算力效能的 GPU 裝置完成模型訓練,但是 GPU 自身價格十分昂貴。如何更好地利用 GPU 裝置,發揮 GPU 的價值,降低成本,是一個亟待解決的問題。Kubernetes 社群現有的 GPU 分配機制中,GPU 是由 kubelet 分配的,並只支援分配一個或多個完整的 GPU 例項。這種方法簡單可靠,但類似於 CPU 和 Memory,GPU 並不是一直處於高利用率水位,同樣存在資源浪費的問題。因此,Koordinator 希望支援多工作負載共享使用 GPU 裝置以節省成本。此外,GPU 有其特殊性。比如下面的 NVIDIA GPU 支援的 NVLink 和超賣場景,都需要通過排程器進行中央決策,以獲得全域性最優的分配結果。

3.png

從圖中我們可以發現,雖然該節點有 8 個 GPU 例項,型號為 A100/V100,但 GPU 例項之間的資料傳輸速度是不同的。當一個 Pod 需要多個 GPU 例項時,我們可以為 Pod 分配具有最大資料傳輸速度組合關係的 GPU 例項。此外,當我們希望一組 Pod 中的 GPU 例項具有最大資料傳輸速度組合關係時,排程器應該將最佳 GPU 例項批量分配給這些 Pod,並將它們分配到同一個節點。

1. GPU 資源協議

Koordinator 相容社群已有的 nvidia.com/gpu 資源協議,並且還自定義了擴充套件資源協議,支援使用者更細粒度的分配 GPU 資源。

  • kubernetes.io/gpu-core 代表 GPU 的計算能力。與 Kuberetes MilliCPU 類似,我們將 GPU 的總算力抽象為 100,使用者可以根據需要申請相應數量的 GPU 算力。
  • kubernetes.io/gpu-memory 表示 GPU 的記憶體容量,以位元組為單位。
  • kubernetes.io/gpu-memory-ratio 代表 GPU 記憶體的百分比。  

假設一個節點有 4 個 GPU 裝置例項,每個 GPU 裝置例項有 8Gi 視訊記憶體。使用者如果期望申請一個完整的 GPU 例項,除了使用 nvidia.com/gpu 之外,還可以按照如下方式申請:

apiVersion: v1 kind: Pod metadata: name: demo-pod namespace: default spec: containers: - name: main resources: limits: kubernetes.io/gpu-core: 100 kubernetes.io/gpu-memory: "8Gi" requests: kubernetes.io/gpu-core: 100 kubernetes.io/gpu-memory: "8Gi"

如果期望只使用一個 GPU 例項一半的資源,可以按照如下方式申請:

apiVersion: v1 kind: Pod metadata: name: demo-pod namespace: default spec: containers: - name: main resources: limits: kubernetes.io/gpu-core: 50 kubernetes.io/gpu-memory: "4Gi" requests: kubernetes.io/gpu-core: 50 kubernetes.io/gpu-memory: "4Gi"

2. 裝置資訊和裝置容量上報

在 Koordinator v0.7.0 版本中,單機側 koordlet 安裝後會自動識別節點上是否含有 GPU 裝置,如果存在的話,會上報這些 GPU 裝置的 Minor ID、 UUID、算力和視訊記憶體大小到一個型別為 Device CRD 中。每個節點對應一個 Device CRD 例項。Device CRD 不僅支援描述 GPU,還支援類似於 FPGA/RDMA 等裝置型別,目前 v0.7.0 版本只支援 GPU, 暫未支援這些裝置型別。

Device CRD 會被 koord-manager 內的 NodeResource controller 和 koord-scheduler 消費。NodeResource controller 會根據 Device CRD 中描述的資訊,換算成 Koordinator 支援的資源協議 kubernetes.io/gpu-core,kubernetes.io/gpu-memory 更新到  Node.Status.Allocatable 和 Node.Status.Capacity 欄位,幫助排程器和 kubelet 完成資源排程。gpu-core 表示 GPU 裝置例項的算力,一個例項的完整算力為100。假設一個節點有 8 個 GPU 裝置例項,那麼節點的 gpu-core 容量為 8 * 100 = 800;gpu-memory 表示 GPU 裝置例項的視訊記憶體大小,單位為位元組,同樣的節點可以分配的視訊記憶體總量為 裝置數量 * 每個例項的單位容量,例如一個 GPU 裝置的視訊記憶體是 8G,節點上有 8 個 GPU 例項,總量為 8 * 8G = 64G。

apiVersion: v1 kind: Node metadata: name: node-a status: capacity: koordinator.sh/gpu-core: 800 koordinator.sh/gpu-memory: "64Gi" koordinator.sh/gpu-memory-ratio: 800 allocatable: koordinator.sh/gpu-core: 800 koordinator.sh/gpu-memory: "64Gi" koordinator.sh/gpu-memory-ratio: 800

3. 中心排程分配裝置資源

Kuberetes 社群原生提供的裝置排程機制中,排程器只負責校驗裝置容量是否滿足 Pod,對於一些簡單的裝置型別是足夠的,但是當需要更細粒度分配 GPU 時,需要中心排程器給予支援才能實現全域性最優。

Koordinator 排程器 koord-scheduler 新增了排程外掛 DeviceShare,負責精細度裝置資源排程。DeviceShare 外掛消費 Device CRD,記錄每個節點可以分配的裝置資訊。DeviceShare 在排程時,會把 Pod 的GPU資源請求轉換為 Koordinator 的資源協議,並過濾每個節點的未分配的 GPU 裝置例項。確保有資源可用後,在 Reserve 階段更新內部狀態,並在 PreBind 階段更新 Pod Annotation,記錄當前 Pod 應該使用哪些 GPU 裝置。

DeviceShare 將在後續版本支援 Binpacking  和 Spread 策略,實現更好的裝置資源排程能力。

4. 單機側精準繫結裝置資訊

Kubernetes 社群在 kubelet 中提供了 DevicePlugin 機制,支援裝置廠商在 kubelet 分配好裝置後有機會獲得裝置資訊,並填充到環境變數或者更新掛載路徑。但是不能支援 中心化的 GPU 精細化排程場景。

針對這個問題, Koordinator 擴充套件了 koord-runtime-proxy ,支援在 kubelet 建立容器時更新環境變數,注入排程器分配的 GPU 裝置資訊。

4.jpeg

排程器診斷分析

大家在使用 Kubernetes 時經常會遇到一些排程相關的問題:

  1. 我這個 Pod 為什麼不能排程?
  2. 這個 Pod 為什麼會排程到這個節點,不是應該被另一個打分外掛影響到麼?
  3. 我新開發了一個外掛,發現排程結果不符合預期,但是有不知道哪裡出了問題。 

要診斷分析這些問題,除了要掌握 Kubernetes 基本的排程機制和資源分配機制外,還需要排程器自身給予支援。但是 Kubernetes kube-scheduler 提供的診斷能力比較有限,有時候甚至沒有什麼日誌可以檢視。kube-scheduler 原生是支援通過 HTTP 更改日誌等級,可以獲得更多日誌資訊,例如執行如下命令可以更改日誌等級到 5:

$ curl -X PUT schedulerLeaderIP:10251/debug/flags/v --data '5' successfully set klog.logging.verbosity to 5

Koordinator 針對這些問題,實現了一套 Restful API ,幫助使用者提升問題診斷分析的效率

  • 分析 Score 結果

PUT /debug/flags/s  允許使用者開啟 Debug Score 開關,在打分結束後,以Markdown 格式列印 TopN 節點各個外掛的分值。例如:

$ curl -X PUT schedulerLeaderIP:10251/debug/flags/s --data '100' successfully set debugTopNScores to 100

當有新 Pod 排程時,觀察 scheduler log 可以看到如下資訊

| # | Pod | Node | Score | ImageLocality | InterPodAffinity | LoadAwareScheduling | NodeAffinity | NodeNUMAResource | NodeResourcesBalancedAllocation | NodeResourcesFit | PodTopologySpread | Reservation | TaintToleration | | --- | --- | --- | ---:| ---:| ---:| ---:| ---:| ---:| ---:| ---:| ---:| ---:| ---:| | 0 | default/curlimage-545745d8f8-rngp7 | cn-hangzhou.10.0.4.51 | 577 | 0 | 0 | 87 | 0 | 0 | 96 | 94 | 200 | 0 | 100 | | 1 | default/curlimage-545745d8f8-rngp7 | cn-hangzhou.10.0.4.50 | 574 | 0 | 0 | 85 | 0 | 0 | 96 | 93 | 200 | 0 | 100 | | 2 | default/curlimage-545745d8f8-rngp7 | cn-hangzhou.10.0.4.19 | 541 | 0 | 0 | 55 | 0 | 0 | 95 | 91 | 200 | 0 | 100 | | 3 | default/curlimage-545745d8f8-rngp7 | cn-hangzhou.10.0.4.18 | 487 | 0 | 0 | 15 | 0 | 0 | 90 | 82 | 200 | 0 | 100 |

找個 Markdown 工具,就可以轉為如下表格:

5.png

  • 排程外掛匯出內部狀態

像 koord-scheduler 內部的 NodeNUMAResource 、 DeviceShare 和 ElasticQuota 等外掛內部都有維護一些狀態幫助排程。koord-scheduler 自定義了一個新的外掛擴充套件介面(定義見下文),並會在初始化外掛後,識別該外掛是否實現了該介面並呼叫該介面,讓外掛注入需要暴露的 RestfulAPI。以 NodeNUMAResource 外掛為例,會提供/cpuTopologyOptions/:nodeName 和/availableCPUs/:nodeName 兩個 Endpoints,可以檢視外掛內部記錄的 CPU 拓撲資訊和分配結果。

type APIServiceProvider interface { RegisterEndpoints(group *gin.RouterGroup) }

使用者在使用時,按照 /apis/v1/plugins//方 式構建 URL 檢視資料,例如要檢視 /cpuTopologyOptions/:nodeName:

$ curl schedulerLeaderIP:10252/apis/v1/plugins/NodeNUMAResources/cpuTopologyOptions/node-1 {"cpuTopology":{"numCPUs":32,"numCores":16,"numNodes":1,"numSockets":1,"cpuDetails":....

  • 檢視當前支援的外掛 API

為了方便大家使用,koord-scheduler 提供了 /apis/v1/services 檢視支援的 API Endpoints

$ curl schedulerLeaderIP:10251/apis/v1/__services__ { "GET": [ "/apis/v1/__services__", "/apis/v1/nodes/:nodeName", "/apis/v1/plugins/Coscheduling/gang/:namespace/:name", "/apis/v1/plugins/DeviceShare/nodeDeviceSummaries", "/apis/v1/plugins/DeviceShare/nodeDeviceSummaries/:name", "/apis/v1/plugins/ElasticQuota/quota/:name", "/apis/v1/plugins/NodeNUMAResource/availableCPUs/:nodeName", "/apis/v1/plugins/NodeNUMAResource/cpuTopologyOptions/:nodeName" ] }

更安全的重排程

在 Koordinator v0.6 版本中我們釋出了全新的 koord-descheduler,支援外掛化實現需要的重排程策略和自定義驅逐機制,並內建了面向 PodMigrationJob 的遷移控制器,通過 Koordinator Reservation 機制預留資源,確保有資源的情況下發起驅逐。解決了 Pod 被驅逐後無資源可用影響應用的可用性問題。

Koordinator v0.7 版本中,koord-descheduler 實現了更安全的重排程

  • 支援 Evict 限流,使用者可以根據需要配置限流策略,例如允許每分鐘驅逐多少個 Pod
  • 支援配置 Namespace 灰度重排程能力,讓使用者可以更放心的灰度
  • 支援按照 Node/Namespace 配置驅逐數量,例如配置節點維度最多隻驅逐兩個,那麼即使有外掛要求驅逐該節點上的更多 Pod,會被拒絕。
  • 感知 Workload ,如果一個 Workload 正在釋出、縮容、已經有一定量的 Pod 正在被驅逐或者一些 Pod NotReady,重排程器會拒絕新的重排程請求。目前支援原生的 Deployment,StatefulSet 以及 Kruise  CloneSet,Kruise AdvancedStatefulSet。 

後續重排程器還會提升公平性,防止一直重複的重排程同一個 workload ,儘量降低重排程對應用的可用性的影響。

其他改動

  • Koordinator 進一步增強了 CPU 精細化排程能力,完全相容 kubelet ( <= v1.22) CPU Manager static 策略。排程器分配 CPU 時會避免分配被 kubelet 預留的 CPU,單機側 koordlet 完整適配了 kubelet 從 1.18 到 1.22 版本的分配策略,有效避免了 CPU 衝突。
  • 資源預留機制支援 AllocateOnce 語義,滿足單次預留場景。並改進了 Reservation 狀態語義,更加準確描述 Reservation 物件當前的狀態。
  • 改進了離線資源(Batch CPU/Memory) 的宣告方式,支援 limit 大於 request 的資源描述形式,可以方便原 burstable 型別的任務直接轉換為混部模式執行。 

你可以通過 Github release [ 3] 頁面,來檢視更多的改動以及它們的作者與提交記錄。

社群參與

非常歡迎你通過 Github/Slack/釘釘/微信 等方式加入我們來參與 Koordinator 開源社群。你是否已經有一些希望與我們社群交流的內容呢?可以通過以下渠道參與討論:

  • 加入社群 Slack channel [ 4] (English)
  • 加入社群釘釘群:搜尋群號 33383887 (Chinese) 或者掃描下方二維碼 

6.png

相關連結

[1] Koordinator

https://koordinator.sh/

[2] Koordinator 0.6 Release Note

https://mp.weixin.qq.com/s/YdoxVxz_91ZFemF8JuxRvQ

[3] Github Release

https://github.com/koordinator-sh/koordinator/releases/tag/v0.6.1

[4] Slack Channel

https://join.slack.com/t/koordinator-sh/shared_invite/zt-1756qoub4-Cn4~esfdlfAPsD7cwO2NzA

[5] Design: Gang Scheduling

https://github.com/koordinator-sh/koordinator/blob/main/docs/proposals/scheduling/20220901-gang-scheduling.md

[6] Design: Multi Hierarchy ElasticQuota Management

https://github.com/koordinator-sh/koordinator/blob/main/docs/proposals/scheduling/20220722-multi-hierarchy-elastic-quota-management.md

[7] Design: Fine-grained Device Scheduling

https://github.com/koordinator-sh/koordinator/blob/main/docs/proposals/scheduling/20220629-fine-grained-device-scheduling.md

[8] 雲原生混部系統 Koordinator 架構詳

https://mp.weixin.qq.com/s/y8k_q6rhTIubQ-lqvDp2hw

點選此處,立即瞭解 Koordinator 專案!