Kubernetes 是 Google 開源的容器集羣管理系統(谷歌內部:Borg),而今天要介紹的 kube-scheduler 是 k8s 系統的核心組件之一,其主要職責就是經過自身的調度算法,爲新建立的 Pod 尋找一個最合適的 Node。
主要包含以下幾個步驟:node
spec.nodeName
字段。官方流程圖以下:git
For given pod: +---------------------------------------------+ | Schedulable nodes: | | | | +--------+ +--------+ +--------+ | | | node 1 | | node 2 | | node 3 | | | +--------+ +--------+ +--------+ | | | +-------------------+-------------------------+ | | v +-------------------+-------------------------+ Pred. filters: node 3 doesn't have enough resource +-------------------+-------------------------+ | | v +-------------------+-------------------------+ | remaining nodes: | | +--------+ +--------+ | | | node 1 | | node 2 | | | +--------+ +--------+ | | | +-------------------+-------------------------+ | | v +-------------------+-------------------------+ Priority function: node 1: p=2 node 2: p=5 +-------------------+-------------------------+ | | v select max{node priority} = node 2
scheduler 的工做看似很簡單,但其實否則。考慮的問題很是多,好比要保證每一個節點被公平調度,提升資源利用率,提升 pod 調度效率,提高調度器擴展能力等等。
可涉及的內容很是多,接下來會圍繞兩個核心步驟對 k8s 的 默認調度策略
深刻了解。github
參考 Kubernetes 版本: v1.12
Predicates 在調度過程當中的做用就是先進行過濾
,過濾掉全部不符合條件的節點後,剩下的全部節點就都是能夠運行帶調度 Pod。算法
Predicates 的能夠分爲以下四類:api
具體的 Predicates 默認策略,能夠參考: 默認調度策略
當開始調度一個 Pod 的時候,調度器會同時開啓多個協程併發的進行 Node Predicates 過濾,最後返回一個能夠運行 Pod 的節點列表。每一個協程都是按照固定的順序進行計算過濾的。緩存
接下來,咱們看下四大類具體運行的調度策略內容。併發
看字面意思就知道 GeneralPredicates 負責的是最基礎的調度策略,其包含的具體策略以下:ide
由於 GeneralPredicates 是最基礎的調度策略,因此該接口也會被別的組件直接調用,好比 kubelet、daemonSet controller。kubelet 在啓動 pod 以前,還會再執行一遍 GeneralPredicates,用於二次確認。函數
不廢話就直接列舉具體的策略了:命令行
這些規則主要考察待調度的 Pod 是否知足 Node 自己的一些條件。
具體的策略以下:
該規則主要就是 PodAffinityPredicate,用於檢查待調度 Pod 與 Node 上已有的 Pod 之間的親和性和反親和性關係。
具體的親和性相關的調度,後面會單獨拿一篇文章進行介紹。
完成了前一個階段的節點 「過濾」 以後,便須要經過 Priorities
爲這些節點打分,選擇得分最高的節點,做爲調度對象。
打分函數不少,總得分能夠參考:總分 = (權重1 * 打分函數1) + (權重2 * 打分函數2) + … + (權重n * 打分函數n)
。
每一次打分的範圍是 0 — 10 分。10 表示很是合適,0 表示很是不合適。
而且每一個打分函數均可以配置對應的權重值,下面介紹 調度器策略配置
時,也會涉及權重值的配置。默認權重值是 1,若是以爲某個打分函數特別重要,即可以加大該權重值。
具體的 Priorities 默認策略能夠參考: defaultPriorities 。
Priorities 最經常使用到的一個打分規則是 LeastRequestedPriority
, 該算法用於選出空閒資源(cpu & memory)最多的宿主機。
還有一個常見的是 BalancedResourceAllocation
,該規則主要目的是資源平衡。在全部節點裏選擇各類資源分配最均衡的節點,避免出現某些節點 CPU 被大量分配,可是 Memory 大量剩餘的狀況。
此外,還有 InterPodAffinityPriority
、NodeAffinityPriority
、TaintTolerationPriority
,與親和性與污點調度有關,後面會有單獨的文章進行介紹。這裏表示節點知足的規則越多,那得分就越高。
在 K8S v1.12 版本還引入了一個調度策略,即 ImageLocalityPriority
。該策略主要目的是優先選擇那些已經存有 Pod 所需 image 的節點,能夠避免實際運行 Pod 時,再去下載 image。
注意: pod 運行時是否會下載 image,還跟 Pod ImagePullPolicy 配置有關。
能夠看到 k8s scheduler 完成一次調度所需的信息很是之多。因此在實際的調度過程當中,大量的信息都事先已經緩存,提升了 Pod 的調度效率。
Kubernetes 調度器有默認的調度策略,具體能夠參考 default 。固然用戶也能夠修改調度策略,能夠經過命令行參數 policy-config-file
指定一個 JSON 文件來描述哪些 predicates 和 priorities 在啓動 k8s 時被使用, 經過這個參數調度就能使用管理者定義的策略了。
示例以下:
{ "kind" : "Policy", "apiVersion" : "v1", "predicates" : [ {"name" : "PodFitsHostPorts"}, {"name" : "PodFitsResources"}, {"name" : "NoDiskConflict"}, {"name" : "NoVolumeZoneConflict"}, {"name" : "MatchNodeSelector"}, {"name" : "HostName"} ], "priorities" : [ {"name" : "LeastRequestedPriority", "weight" : 1}, {"name" : "BalancedResourceAllocation", "weight" : 1}, {"name" : "ServiceSpreadingPriority", "weight" : 1}, {"name" : "EqualPriority", "weight" : 1} ], "hardPodAffinitySymmetricWeight" : 10, "alwaysCheckAllPredicates" : false }
前面提到了調度器的擴展能力,除了使用 k8s 自帶的調度器,你也能夠編寫本身的調度器。經過修改 Pod 的 spec.schedulername
參數來指定調度器的名字。