Kubernetes源碼學習-Scheduler-總覽篇

調度器總體設計

調度器源碼分段閱讀目錄

概覽

首先列出官方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.gopkg/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()中來實現自定義調度策略。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章