今天zouyee先帶各位盤點CNCF上週的一些有趣的事情:node
Kubernetes社區GB表明選舉結束 Paris Pittman當選git
CNCF孵化項目OPA進入畢業流程github
上週helm
項目發佈v3.5.0功能性版本web
CoreDNS項目經過Docker鏡像倉庫放開拉取限制的申請算法
書接上文《Kubernetes調度系統由淺入深系列:初探》,今天zouyee爲你們帶來《kuberneter調度由淺入深:框架》,該系列對應版本爲1.20.+
.api
在《Kubernetes調度系統由淺入深系列:初探》中,給出總體的交互圖,來構建Pod調度的直觀感覺,咱們拓展了一下交互圖,以下所示。緩存
注:該交互圖非專業UML,還請諒解。安全
上述以建立一個Pod爲例,簡要介紹調度流程:markdown
用戶經過命令行建立Pod(選擇直接建立Pod而不是其餘workload,是爲了省略kube-controller-manager)網絡
kube-apiserver通過對象校驗、admission、quota等准入操做,寫入etcd
kube-apiserver將結果返回給用戶
同時kube-scheduler一直監聽節點、Pod事件等(流程1)
kube-scheduler將spec.nodeName的pod加入到調度隊列中,調度系統選擇pod,進入調度週期(本文介紹內容)(流程2-3)
kube-scheduler將pod與得分最高的節點進行binding操做(流程4)
kube-apiserver將binding信息寫入etcd
kubelet監聽分配給本身的Pod,調用CRI接口進行Pod建立(該部份內容後續出系列,進行介紹)
kubelet建立Pod後,更新Pod狀態等信息,並向kube-apiserver上報
kube-apiserver寫入數據
Kubernetes 隨着功能的增多,代碼與邏輯也日益複雜。代碼體量及複雜度的提高必然帶來維護成本的增長,隱形的增長錯誤定位和修復的難度。舊版本的Kubernetes調度程序(1.16前)提供了webhooks進行擴展。但有如下缺陷:
用戶能夠擴展的點比較有限,位置比較固定,沒法支持靈活的擴展與調配,例如只能在執行完默認的 Filter 策略後才能調用。
調用擴展接口使用 HTTP 請求,其受到網絡影響,性能遠低於本地的函數調用。同時每次調用都須要將 Pod 和 Node 的信息進行 序列化與反序列化 操做,會進一步下降性能。
Pod當前的相關信息,沒法及時傳遞(利用調度Cache)。
爲了解決上述問題,使調度系統代碼精簡、擴展性更好,社區從 Kubernetes 1.16
版本開始, 引入了一種新的調度框架- Scheduling Framework 。
Scheduling Framework 在原有調度流程的基礎之上, 定義了豐富的擴展點接口,開發者能夠經過實現擴展點所定義的接口來實現插件,將插件註冊到擴展點。Scheduling Framework 在執行調度流程時,運行到相應的擴展點時,執行用戶註冊的插件,生成當前階段的結果。經過這種方式來將用戶的調度邏輯集成到 Scheduling Framework 中。Scheduling Framework明確瞭如下目標:
Framework 的調度流程是分爲兩個階段:
在介紹Framework 的調度流程以前,先介紹上圖的調度流程,即schedulerOne的處理邏輯:
a. 調度階段
1. **過濾**操做即findNodesThatFitPod函數
- 執行PreFilterPlugins
- 執行FilterPlugins
- 執行擴展 Filter
- 若出現FitError,執行PostFilter
2. **評分**操做即prioritizeNodes函數
- 執行PreScorePlugins
- 執行ScorePlugins
- 執行擴展Prioritize
3. 挑選節點即select函數(符合條件節點,按照評分排序及採樣選擇)
4. 節點預分配即assume(只是預先分配,可收回)
5. 相關調度數據緩存即RunReservePlugins,從該節點開始,後續階段發生錯誤,須要調用UnReserve,進行回滾(相似事務)
6. 執行准入操做即RunPermitPlugins
複製代碼
b. 綁定階段
1. 執行WaitOnPermit,失敗時調用RunReservePluginsUnreserve
2. 執行預綁定即RunPreBindPlugins,失敗時調用RunReservePluginsUnreserve
3. 執行擴展bingding即extendersBinding,失敗時調用RunReservePluginsUnreserve
4. 執行綁定收尾工做即RunPostBindPlugins
複製代碼
上述涉及到的各種Plugins(圖中紫色部分),針對下圖,各位應該看了不少篇了,須要注意的是Unreserve的時機,各插件功能說明以下:
pkg/scheduler/framework/interface.go
擴展點 | 用途說明 |
---|---|
QueueSort | 用來支持自定義 Pod 的排序。若是指定 QueueSort 的排序算法,在調度隊列裏面就會按照指定的排序算法來進行排序,只能enable一個 |
Prefilter | 對 Pod 信息的預處理,好比 Pod 的緩存等 |
Filter | 對應舊式的Predicate ,過濾不知足要求的節點 |
PostFilter | 用於處理當 Pod 在 Filter 階段失敗後的操做,例如搶佔等行爲 |
PreScore | 用於在 Score 以前進行一些信息生成,也能夠在此處生成一些日誌或者監控信息 |
Score | 對應舊式的Priority,根據 擴展點定義的評分策略挑選出最優的節點(打分與歸一化處理) |
Reserver | 調度階段的最後一個插件, 防止調度成功後資源的競爭, 確保集羣的資源信息的準確性 |
Permit | 主要提供了Pod綁定的攔截功能,根據條件對pod進行allow、reject或者wait。 |
PreBind | 在真正 bind node 以前,執行一些操做 |
Bind | 一個 Pod 只會被一個 BindPlugin 處理,建立Bind對象 |
PostBind | bind 成功以後執行的邏輯 |
Unreserve | 在 Permit 到 Bind 這幾個階段只要報錯就回滾數據至初始狀態,相似事務。 |
下述爲一些關於如何使用調度框架來解決常見調度場景的示例。
聯合調度
相似kube-batch
,容許調度以必定數量的Pod爲總體的任務。其可以將一個訓練任務的多個worker當作一個總體進行調度,只有當任務全部worker的資源都知足,纔會將容器在節點上啓動。
集羣資源的動態綁定
Volume topology-aware調度能夠經過filter和prebind方式實現。
調度拓展
該框架容許自定義插件,以main函數封裝scheduler方式運行。
關於框架部分,該文就介紹到此處,接下里將進入源碼階段,後續內容爲調度配置及第三方調度集成的相關內容,敬請關注。
後續相關內容,請查看公衆號:DCOS
1. https://kubernetes.io/docs/concepts/scheduling-eviction/kube-scheduler/
2. https://kubernetes.io/docs/concepts/scheduling-eviction/scheduling-framework/
3. https://github.com/kubernetes/enhancements/blob/master/keps/sig-scheduling/624-scheduling-framework/README.md
複製代碼