在 Kubernetes 中,排程是指將 Pod 放置到合適的 Node 上,然後對應 Node 上的 Kubelet 才能夠執行這些 Pod 。
kube-scheduler 是叢集控制平面的主要元件之一。Kubernetes 透過它來決定如何排程叢集中的 Pod。它會使用基於預選(斷言 predicate)和基於優選(優先順序 priority)的評分演算法,根據叢集中的約束以及使用者指定的約束來最佳化資源。
預選(過濾)
kube-scheduler 首先使用預選函式來制定排程策略,決定 Pod 可以在哪些節點上進行排程。它意味著一個硬性約束條件,因此函式的返回值為布林值。例如,一個 Pod 請求 10GB 的記憶體,而節點 A 的配置為 8 GB,那麼節點 A 將返回 false
並從 Pod 的候選排程節點中剔除。另一個例子是節點 B 被叢集管理員執行了 kubectl cordon node-b
,被標記節點為不可排程,它也將會被排程決策直接剔除。
排程程式會根據限制條件和複雜性依次進行以下預選檢查,檢查順序儲存在一個名為 predicatesOrdering (順序斷言)的切片中:
var predicateOrdering = []string{
CheckNodeUnschedulablePred,
GeneralPred, HostNamePred, PodFitsHostPortsPred,
MatchNodeSelectorPred, PodFitsResourcesPred, NoDiskConflictPred,
PodToleratesNodeTaintsPred, CheckNodeLabelPresencePred,
CheckServiceAffinityPred, MaxEBSVolumeCountPred, MaxGCEPDVolumeCountPred, MaxCSIVolumeCountPred,
MaxAzureDiskVolumeCountPred, MaxCinderVolumeCountPred, CheckVolumeBindingPred, NoVolumeZoneConflictPred,
EvenPodsSpreadPred, MatchInterPodAffinityPred,
}
- CheckNodeUnschedulablePred:檢查節點是否可排程;
- GeneralPred:一般性檢測,如檢測資源是否充足,Pod 的 Host、Port、Selector 是否匹配;
- HostNamePred:檢測 Pod 指定的 Node 名稱是否和 Node 名稱相同;
- PodFitsHostPortsPred:檢查 Pod 請求的埠(網路協議型別)在節點上是否可用;
- MatchNodeSelectorPred:檢測是否匹配 NodeSelector 節點選擇器的設定;
- PodFitsResourcesPred:檢查節點的空閒資源(例如,CPU 和記憶體)是否滿足 Pod 的要求;
- NoDiskConflictPred:根據 Pod 請求的卷是否在節點上已經掛載,評估 Pod 和節點是否匹配;
- PodToleratesNodeTaintsPred:檢查 Pod 的容忍是否能容忍節點的汙點;
- CheckNodeLabelPresencePred:檢測 NodeLabel 是否存在;
- CheckServiceAffinityPred:檢測服務的親和;
MaxEBSVolumeCountPred:已廢棄,檢測 Volume 數量是否超過雲服務商 AWS 的儲存服務的配置限制;MaxGCEPDVolumeCountPred:已廢棄,檢測 Volume 數量是否是否超過雲服務商 Google Cloud 的儲存服務的配置限制;- MaxCSIVolumeCountPred:Pod 附加 CSI 卷的數量,判斷是否超過配置的限制;
MaxAzureDiskVolumeCountPred:已廢棄,檢測 Volume 數量是否超過雲服務商 Azure 的儲存服務的配置限制;MaxCinderVolumeCountPred:已廢棄,檢測 Volume 數量是否超過雲服務商 OpenStack 的儲存服務的配置限制;- CheckVolumeBindingPred,:基於 Pod 的卷請求,評估 Pod 是否適合節點,這裡的捲包括繫結的和未繫結的 PVC 都適用;
- NoVolumeZoneConflictPred:給定該儲存的故障區域限制, 評估 Pod 請求的卷在節點上是否可用;
- EvenPodsSpreadPred:檢測 Node 是否滿足拓撲傳播限制;
- MatchInterPodAffinityPred:檢測是否匹配 Pod 的親和與反親和的設定;
可以看出,Kubernetes 正在逐步移除某個具體雲服務商的服務的相關程式碼,而使用介面(Interface)來擴充套件功能。
優選(打分)
預選透過返回 true 或者 false 來表示節點是否參與排程,而優選則是根據優先順序的相對值對所有可排程節點進行排名,以下是為節點評分的優先順序列表:
- EqualPriority:給予所有節點相等的權重;
- MostRequestedPriority:支援最多請求資源的節點。 該策略將 Pod 排程到整體工作負載所需的最少的一組節點上;
- RequestedToCapacityRatioPriority:使用預設的打分方法模型,建立基於 ResourceAllocationPriority 的 requestedToCapacity;
- SelectorSpreadPriority:屬於同一 Service、 StatefulSet 或 ReplicaSet 的 Pod,儘可能地跨 Node 部署(雞蛋不要只放在一個籃子裡,分散風險,提高可用性);
- ServiceSpreadingPriority:對於給定的 Service,此策略旨在確保該 Service 關聯的 Pod 在不同的節點上執行。 它偏向把 Pod 排程到沒有該服務的節點。 整體來看,Service 對於單個節點故障變得更具彈性;
- InterPodAffinityPriority:實現了 Pod 間親和性與反親和性的優先順序;
- LeastRequestedPriority:偏向最少請求資源的節點。 換句話說,節點上的 Pod 越多,使用的資源就越多,此策略給出的排名就越低;
- BalancedResourceAllocation:偏向平衡資源使用的節點;
- NodePreferAvoidPodsPriority:根據節點的註解 scheduler.alpha.kubernetes.io/preferAvoidPods 對節點進行優先順序排序。 你可以使用它來暗示兩個不同的 Pod 不應在同一節點上執行;
- NodeAffinityPriority:根據節點親和中 PreferredDuringSchedulingIgnoredDuringExecution 欄位對節點進行優先順序排序;
- TaintTolerationPriority:根據節點上無法忍受的汙點數量,給所有節點進行優先順序排序。 此策略會根據排序結果調整節點的等級;
- ImageLocalityPriority:偏向已在本地快取 Pod 所需容器映象的節點;
- EvenPodsSpreadPriority:實現了 Pod 拓撲擴充套件約束的優先順序排序;
這些分值將會累計為節點的總分,用來表明其優先順序。例如,如果一個 Pod 需要 1 個 cpu 核心的資源,而有兩個候選節點滿足這一要求,其中節點 A 有 2 個 CPU 核心可供分配,節點 B 有 4 個核心可供分配,則節點 B 將具有更高的優先順序。 如果多個節點返回相同的優先順序,排程程式將會使用輪循的方式來選擇節點。
最優解
kube-scheduler 使用基於預選和基於優選的評分演算法,理論上需要遍歷所有 Node(實際上有快取邏輯),而當叢集中的 Node 數量超過一定數量後,排程演算法的開銷將變得很大。所以 kube-scheduler 為了解決效能問題,引入了”全域性最優解”和”區域性最優解”兩種最優解。
- 全域性最優解:遍歷叢集中的所有節點,找出全域性最優的節點;
- 區域性最優解:只遍歷叢集中的部分節點,找出區域性最有的節點;
在小型叢集中(例如 100 個節點),使用全域性最優解。而在超大型叢集中(例如 5000 個節點)使用區域性最優解。
搶佔機制
Pod 可以設定優先順序(PriorityClass,注意:此處的 Pod 優先順序與優選演算法的優先順序評分不是一個概念)。 Pod 優先順序表示一個 Pod 相對於其他 Pod 的重要性。 如果一個 Pod 無法被排程,排程程式會嘗試搶佔(驅逐)較低優先順序的 Pod。
要使用優先順序和搶佔,需要:
- 新增 PriorityClass 物件,並設定 value 值;
- 將 Pod 的 Spec.priorityClassName 設定為上述新增的 PriorityClass;
上述設定了高優先順序的 Pod(暫稱為 pod-h
) ,如果 kube-scheduler 沒有找到滿足其指定要求的節點,則觸發搶佔邏輯。搶佔邏輯試圖找到某個節點,在該節點中刪除/驅逐一個或多個優先順序低於 pod-h
的 Pod。被驅逐的 Pod 消失後,pod-h
可以被排程到該節點上。
更多
更多經典示例請參考:github.com/jxlwqq/kubernetes-examp...
本作品採用《CC 協議》,轉載必須註明作者和本文連結