調度器總體設計
調度器源碼分段閱讀目錄
概覽
首先列出官方md鏈接,講解頗爲生動:
https://github.com/kubernetes/community/blob/master/contributors/devel/sig-scheduling/scheduler.md
這裏用結合自己閱讀代碼的理解做一下翻譯。
工作模式
Kubernetes scheduler獨立運作與其他主要組件之外(例如API Server),它連接API Server,watch觀察,如果有PodSpec.NodeName爲空的Pod出現,則開始工作,通過一定得篩選算法,篩選出合適的Node之後,向API Server發起一個綁定指示,申請將Pod與篩選出的Node進行綁定。
代碼層級
迴歸到代碼本身,scheduler的設計分爲3個主要代碼層級:
cmd/kube-scheduler/scheduler.go
: 這裏的main()函數即是scheduler的入口,它會讀取指定的命令行參數,初始化調度器框架,開始工作pkg/scheduler/scheduler.go
: 調度器框架的整體代碼,框架本身所有的運行、調度邏輯全部在這裏pkg/scheduler/core/generic_scheduler.go
: 上面是框架本身的所有調度邏輯,包括算法,而這一層,是調度器實際工作時使用的算法,默認情況下,並不是所有列舉出的算法都在被實際使用,參考位於文件中的Schedule()
函數
調度算法邏輯
邏輯圖:
一個沒有指定Spec.NodeName的:
+---------------------------------------------+
| Schedulable nodes: |
| |
| +--------+ +--------+ +--------+ |
| | node 1 | | node 2 | | node 3 | |
| +--------+ +--------+ +--------+ |
| |
+-------------------+-------------------------+
|
|
v
+-------------------+-------------------------+
斷言(硬性指標)篩選: node 3 資源不足
+-------------------+-------------------------+
|
|
v
+-------------------+-------------------------+
| 剩餘可選nodes: |
| +--------+ +--------+ |
| | node 1 | | node 2 | |
| +--------+ +--------+ |
| |
+-------------------+-------------------------+
|
|
v
+-------------------+-------------------------+
優先級判斷: node 1: priority=2
node 2: priority=5
+-------------------+-------------------------+
|
|
v
選擇 max{node priority} = node 2
node2則成爲成功篩選出的與pod綁定的節點
爲了給pod挑選出合適的node,調度器做出如下嘗試步驟:
- 第一步,通過一系列的predicates(斷言)指標,排除不合適的node,例如:pod.resources.requests.memory: 16Gi, node則計算:node.capacity 減去node上現有的所有pod的pod.resources.requests.memory的總和,如果差小於16Gi,那麼則此項predicates結果爲false,排除此節點
- 第二步,對通過了上一步篩選的node,執行一系列的優先級計算函數,計算的對象是node的負載情況,負載是即是node上現有的所有pod的pod.resources.requests的資源的總和除以node.capacity,值越高則負載越高,優先級越低
- 最終,挑選出了最高優先級的node,若有多個,則隨機挑選其中一個
Predicates and priorities policies
調度算法一共由Predicates和priorities這兩部分組成,Predicates(斷言)是用來過濾node的一系列策略集合,Priorities是用來優選node的一系列策略集合。默認情況下,kubernetes提供內建predicates/priorities策略,代碼集中於pkg/scheduler/algorithm/predicates/predicates.go
和 pkg/scheduler/algorithm/priorities
內.
調度策略擴展
管理員可以選擇要應用的預定義調度策略中的哪一個,開發者也可以添加自定義的調度策略。
修改調度策略
默認調度策略是通過defaultPredicates() 和 defaultPriorities()這兩個函數定義的,源碼在 pkg/scheduler/algorithmprovider/defaults/defaults.go
,我們可以通過命令行flag --policy-config-file CONFIG_FILE 來修改默認的調度策略。除此之外,也可以在pkg/scheduler/algorithm/predicates/predicates.go
pkg/scheduler/algorithm/priorities
源碼中添加自定義的predicate和prioritie策略,然後註冊到defaultPredicates()
/defaultPriorities()
中來實現自定義調度策略。