Kubernetes的Pod調度算法
在本文檔中,解釋了如何為Pod選擇節點的算法。在選擇Pod的目標節點之前有兩個步驟。第一步是過濾所有節點(預選),第二步是對剩余節點進行排名(優選),以找到最適合Pod的節點。
預選
預選的目的是過濾掉不滿足Pod某些要求的節點。例如,如果節點上的空閑資源(通過容量減去已經在節點上運行的所有Pod的資源請求的總和來測量)小于Pod的所需資源,則不應在優選階段考慮該節點打分排名,就被過濾掉了。目前,有幾個“預選策略”實現了不同的過濾策略
-
NoDiskConflict
檢查pod請求的卷以及已掛載的卷存在沖突。如果這個主機已經掛載了卷,其它同樣使用這個卷的Pod不能調度到這個主機上。目前支持的卷包括:AWS EBS,GCE PD,ISCSI和Ceph RBD。僅檢查這些受支持類型的持久卷聲明。直接添加到pod的持久卷不會被評估,也不受此策略的約束。 -
NoVolumeZoneConflict
檢查給定的zone限制前提下,檢查如果在此主機上部署Pod是否存在卷沖突。 -
PodFitsResources
檢查可用資源(CPU和內存)是否滿足Pod的要求。測量空閑資源是通過節點容量減去節點上所有Pod的請求總和。要了解有關Kubernetes中資源QoS的更多信息,請查看QoS提議。 -
PodFitsHostPorts
檢查Pod所需的任何HostPort是否已在節點上占用 -
HostName
篩選出除PodSpec
的``NodeName字段中指定的節點之外的所有節點 簡單來說就是檢查主機名稱是不是Pod指定的
HostName` -
MatchNodeSelector
檢查節點的標簽是否與Pod的nodeSelector
字段中指定的標簽匹配,并且從Kubernetes v1.2開始,也匹配nodeAffinity
if present。有關兩者的詳細信息,請參見此處。 -
MaxEBSVolumeCount
確保掛載的ElasticBlockStore卷的數量不超過最大值(默認情況下為39,因為Amazon建議最多40個,其中40個為根卷保留其中一個 - 請參閱Amazon的文檔)。可以通過設置KUBE_MAX_PD_VOLS
環境變量來控制最大值。 -
MaxGCEPDVolumeCount
確保掛載的GCE PersistentDisk卷的數量不超過最大值(默認情況下,16,這是GCE允許的最大值 - 請參閱GCE的文檔)??梢酝ㄟ^設置KUBE_MAX_PD_VOLS
環境變量來控制最大值。 -
CheckNodeMemoryPressure
檢查是否可以在提示memory pressure
的節點上安排pod。目前,BestEffort
這種Qos等級的pod不能被調度到memory pressure
的節點上,因為它會被kubelet自動驅逐。 -
CheckNodeDiskPressure
檢查是否可以在提示disk pressure
節點上安排Pod。目前,Pod不會被調度在disk pressure`節點上,因為它會被kubelet自動驅逐。
上述預選的詳細信息可以在pkg / scheduler / algorithm / predicates / predicates.go中找到。上面提到的所有策略可以組合使用以執行復雜的過濾策略。默認情況下,Kubernetes使用這些謂詞中的一些,但不是全部。您可以在pkg / scheduler / algorithmprovider / defaults / defaults.go中查看默認使用的。
優選
預選節點被認為適合托管Pod,并且通常存在多個節點。Kubernetes優先考慮這些節點,以找到Pod的“最佳”節點。優先級由一組優先級函數執行。對于每一個節點,優先級函數給出從0-10開始的分數,其中10代表“最優選”,0代表“最不優選”。每個優先級函數由正數加權,每個節點的最終得分通過將所有加權得分相加來計算。例如,假設有兩個優先級的功能,priorityFunc1
和priorityFunc2
與加權系數weight1
和weight2
分別一些NodeA上的最后得分是:
finalScoreNodeA = (weight1 * priorityFunc1) + (weight2 * priorityFunc2)
在計算所有節點的分數之后,選擇具有最高分數的節點作為Pod的主機。如果存在多個具有相同最高分數的節點,則選擇其中的隨機節點。
目前,Kubernetes調度程序提供了一些實用的優先級功能,包括:
-
LeastRequestedPriority
:如果新的pod要分配給一個節點,這個節點的優先級就由節點空閑的那部分與總容量的比值(即(總容量-節點上pod的容量總和-新pod的容量)/總容量)來決定。CPU和內存的權重相等,比值最大的節點的得分最高。需要注意的是,這個優先級函數起到了按照資源消耗來跨節點分配pods的作用。計算公式如下:
score = cpu((capacity – sum(requested)) * 10 / capacity) + memory((capacity – sum(requested)) * 10 / capacity) / 2
-
BalancedResourceAllocation
:盡量選擇在部署Pod后各項資源更均衡的機器,計算公式如下:
score = 10 – abs(cpuFraction-memoryFraction)*10
-
SelectorSpreadPriority
:對于屬于同一個service、replication controller的Pod,盡量分散在不同的主機上。如果指定了區域,則會盡量把Pod分散在不同區域的不同主機上 -
CalculateAntiAffinityPriority
:對于屬于同一個service的Pod,盡量分散在不同的具有指定標簽的主機上 -
ImageLocalityPriority
:根據主機上是否已具備Pod運行的環境來打分。ImageLocalityPriority
會判斷主機上是否已存在Pod運行所需的鏡像,根據已有鏡像的大小返回一個0-10的打分。如果主機上不存在Pod所需的鏡像,返回0;如果主機上存在部分所需鏡像,則根據這些鏡像的大小來決定分值,鏡像越大,打分就越高。 -
NodeAffinityPriority
:(Kubernetes v1.2)Kubernetes調度中的親和性機制。Node Selectors(調度時將pod限定在指定節點上),支持多種操作符(In, NotIn, Exists, DoesNotExist, Gt, Lt),而不限于對節點labels的精確匹配。
另外,Kubernetes支持兩種類型的選擇器:
一種是“hard(requiredDuringSchedulingIgnoredDuringExecution)”選擇器,它保證所選的主機必須滿足所有Pod對主機的規則要求。這種選擇器更像是之前的nodeselector,在nodeselector的基礎上增加了更合適的表現語法。
另一種是“soft(preferresDuringSchedulingIgnoredDuringExecution)”選擇器,它作為對調度器的提示,調度器會盡量但不保證滿足NodeSelector的所有要求。
Kubernetes調度中的親和性機制請看這里了解更多詳情。