Kubernetes調度算法介紹

調度流程

調度器就是一個獨立的進程,負責不斷從apiserver拉取還沒有被調度的pod,以及可調度的node列表,通過一些列算法篩選,選出一個node並與該pod綁定,將綁定的結果寫回apiserver

調度算法

下面講解基於k8s v1.6.6的源碼

算法需要經過兩個階段,分別是過濾和打分,首先過濾掉一部分,保證剩餘的節點都是可調度的,接着在打分階段選出最高分節點,該節點就是scheduler的輸出節點。

算法流程:

過濾

過濾環節就是一條過濾器鏈,包含多個過濾器,每個相當於一個函數,接收node和待調度的pod作爲參數,返回bool來確定是否可調度。通過組合多個函數可以完成一條可擴展的過濾器鏈。目前k8s中已註冊的過濾器函數如下:

算法名稱 是否默認 詳細說明
NoVolumeZoneConflict 當主機上zone-label(地區)包含pod中PersistentVolume卷下的zone label時,可以調度。當主機沒有zone-label,表示沒有沒有zone限制,也可調度
MaxEBSVolumeCount 當主機上被掛載的AWS EBS Volume超過了默認限制39,就不調度到該主機
MaxGCEPDVolumeCount 當主機上被掛載的GCD Persistent Disk超過了默認限制16,就不調度到該機器
MaxAzureDiskVolumeCount 當主機上被掛載的Azure Disk Volume超過了默認限制16,就不調度到該機器
NoDiskConflict

當主機上所有pod使用的卷和待調度pod使用的卷存在衝突,就不調度到該主機。這項檢查只針對GCE, Amazon EBS, Ceph RBD, ISCSI,具體規則爲:

  • GCE PersistentDisk允許多次只讀掛載相同的volume
  • EBS禁止兩個pod掛載同一個id的volume
  • Ceph RBD禁止兩個pod共享一個monitor、pool、image
  • ISCSI禁止兩個pod共享同一個IQN
MatchInterPodAffinity 親和性檢查,設帶調度的pod爲X,當主機上所有正運行的pod與X不相互排斥時,則可調度
PodToleratesNodeTaints 當pod可以容忍(tolerate)主機所有的taint(污點)時,纔可被調度(容忍taint標籤的方式就是給自己也打上相應tolerations標籤)
CheckNodeMemoryPressure 當主機剩餘內存緊張時,BestEffort類型的pod無法被調度到該主機
CheckNodeDiskPressure 當主機剩餘磁盤空間緊張時,無法調度到該主機
PodFitsHostPorts 當待調度pod中所有容器所用到的HostPort與工作節點上已使用端口存在衝突,就不調度到該主機
PodFitsPorts 被PodFitsHostPorts取代
PodFitsResources 當總資源-主機中所有pod對資源的request總量 < 帶調度的pod request資源量,則不調度到該主機,現在會檢查CPU,MEM,GPU資源
HostName 如果待調度的pod指定了pod.Spec.Host,則調度到該主機上
MatchNodeSelector 當主機label與pod中nodeSelector以及annotations scheduler.alpha.kubernetes.io/affinity匹配,則可調度


打分

打分環節也是一條鏈路,包含多個打分函數,每個打分函數會接收node和待調度的pod作爲參數,返回一個範圍在0-10的分數,每個打分函數還有一個權重值。某個node算出的總分就是所有打分函數的分值*權重值的總和,獲取總分最大的node(如果有多個,隨機取一個),該node就是最終要被調度的節點

示例:假設有個節點nodeA,有兩個打分函數priorityFunc1、priorityFunc2(每個方法都能返回一個score),兩個方法分別都有權重因子weight1、weight2。則nodeA的總分爲:finalScoreNodeA = (weight1 * priorityFunc1) + (weight2 * priorityFunc2)

目前k8s中已註冊的打分函數如下:

算法名稱 是否默認 權重 詳細說明
SelectorSpreadPriority 1 相同service/rc的pods越分散,得分越高
ServiceSpreadingPriority 1 相同service的pods越分散,優得分越高,被SelectorSpreadPriority取代,保留在系統中,並不使用
InterPodAffinityPriority 1 pod與node上正運行的其他pod親和性匹配度越高,得分越高
LeastRequestedPriority 1 剩餘資源越多,得分越高。cpu((capacity - sum(requested)) * 10 / capacity) + memory((capacity - sum(requested)) * 10 / capacity) / 2
BalancedResourceAllocation 1 cpu和內存利用率越接近,得分越高。10 - abs(cpuFraction-memoryFraction)*10
NodePreferAvoidPodsPriority 10000 當node的annotation scheduler.alpha.kubernetes.io/preferAvoidPods被設置時,說明該node不希望被調度,得分低,當沒有設置時得分高。之所以權重較大是因爲一旦設置preferAvoidPods表示該node不希望被調度,該項得分爲0,其他沒有設置的node得分均爲10000*分值,相當於直接過濾掉該節點。思考:其實可以放在過濾環節處理
NodeAffinityPriority 1 pod與node的親和性匹配度越高,得分越高
TaintTolerationPriority 1 pod對node的污點(taint)的容忍(tolerate)程度越高,得分越高
EqualPriority 1 所有機器得分一樣
ImageLocalityPriority 1 待調度的pod會使用到一些鏡像,擁有這些鏡像越多的節點,得分越高
MostRequestedPriority 1 request資源越多,得分越高,與LeastRequestedPriority相反。(cpu(10 * sum(requested) / capacity) + memory(10 * sum(re
本文轉移開源中國-Kubernetes調度算法介紹
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章