摘要:與已運行相關的過濾規則負責檢查待調度與上已有之間的親和性關系。并且每個打分函數都可以配置對應的權重值,下面介紹調度器策略配置時,也會涉及權重值的配置。默認權重值是,如果覺得某個打分函數特別重要,便可以加大該權重值。
一、概述
Kubernetes 是 Google 開源的容器集群管理系統(谷歌內部:Borg),而今天要介紹的 kube-scheduler 是 k8s 系統的核心組件之一,其主要職責就是通過自身的調度算法,為新創建的 Pod 尋找一個最合適的 Node。
主要包含如下幾個步驟:
通過一組叫做謂詞 predicates 的過濾算法,先挑出滿足條件的 Node;
通過一組叫做優先級 priorities 的打分算法,來給上一步符合條件的每個 Node 進行打分排名;
最終選擇得分最高的節點,當然如果得分一樣就隨機一個節點,填回 Pod 的 spec.nodeName 字段。
官方流程圖如下:
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 的 默認調度策略 深入了解。
參考 Kubernetes 版本: v1.12二、Predicates
Predicates 在調度過程中的作用就是先進行過濾,過濾掉所有不符合條件的節點后,剩下的所有節點就都是可以運行帶調度 Pod。
Predicates 的可以分為如下四類:
GeneralPredicates:負責最基礎的調度策略,比如 PodFitsResources 計算宿主機資源是否夠用。
與 Volume 相關的過濾規則:負責與容器持久化 Volume 相關的調度策略。
與宿主機相關的過濾規則:負責考察待調度 Pod 是否滿足 Node 本身的一些條件。
與已運行 Pod 相關的過濾規則:負責檢查待調度 Pod 與 Node 上已有 Pod 之間的親和性關系。
具體的 Predicates 默認策略,可以參考: 默認調度策略
當開始調度一個 Pod 的時候,調度器會同時開啟多個協程并發的進行 Node Predicates 過濾,最后返回一個可以運行 Pod 的節點列表。每個協程都是按照固定的順序進行計算過濾的。
接下來,我們看下四大類具體運行的調度策略內容。
1. GeneralPredicates看字面意思就知道 GeneralPredicates 負責的是最基礎的調度策略,其包含的具體策略如下:
PodFitsResources: 計算宿主機的 CPU、內存、擴展資源(如 GPU)等是否夠用。
PodFitsHost: 檢查宿主機的名字是否跟 Pod 的 spec.nodeName 匹配。
PodFitsHostPorts: 檢查 Pod 申請的宿主機端口有沒有沖突。
PodMatchNodeSelector: 檢查節點是否能匹配 Pod 的 nodeSelector 和 nodeAffinity。
因為 GeneralPredicates 是最基礎的調度策略,所以該接口也會被別的組件直接調用,比如 kubelet、daemonSet controller。kubelet 在啟動 pod 之前,還會再執行一遍 GeneralPredicates,用于二次確認。
2. 與 Volume 相關的過濾規則不廢話就直接列舉具體的策略了:
NoDiskConflict:檢查該節點上所有的 Pods 是否與待調度的 Pod 的 Volume 有沖突,比如 AWS、GCE 的 Volume 是不允許被兩個 Pod 同時使用的。
VolumeZonePredicate:檢查 Pod Volume 的 zone 標簽是否與節點的 zone 標簽匹配。如果 Node 沒有 zone 標簽則認定為匹配。
MaxPDVolumeCountPredicate:檢查節點上某種類型的 Volume 是否已經超過指定數目。
CSIMaxVolumeLimitPredicate:檢查 csi volume 相關的限制
VolumeBindingPredicate:檢查 Pod 對應的 Local PV 的 nodeAffinity 字段,是否跟某個節點的標簽相匹配。如果該 Pod PVC 還沒有綁定 PV 的話,則調度器還要負責檢查所有待綁定的 PV,且該 PV 的 nodeAffinity 是否與節點標簽匹配。
3. 與宿主機相關的過濾規則這些規則主要考察待調度的 Pod 是否滿足 Node 本身的一些條件。
具體的策略如下:
NodeConditionPredicate:檢查 Node 是否還未準備好或者處于NodeOutOfDisk、NodeNetworkUnavailable 狀態,又或者 Node spec.Unschedulable 設置為 true,那該節點都將無法被調度。
PodToleratesNodeTaints:檢查 Node 的 taint(污點)機制。只有當 Pod 的 Toleration 與 Node 的 Taint 匹配時,Pod 才能調度到該節點上。
NodeMemoryPressurePredicate:檢查當前節點的內存是否已經不夠使用。
NodeDiskPressurePredicate:檢查當前節點的磁盤是否已經不夠使用。
NodePIDPressurePredicate:檢查當前節點的 PID 是否已經不夠使用。
4. 與已運行 Pod 相關的過濾規則該規則主要就是 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 參數來指定調度器的名字。
參考資料The Kubernetes Scheduler
Scheduler Algorithm in Kubernetes
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/32908.html
摘要:換句話說,親和性選擇節點僅在調度時起作用。先創建集群反親和性打散各個副本再部署服務,需要打散并且與服務共存,配置如下注意需要進行大量處理,所以會明顯減慢大型集群的調度時間,不建議在大于幾百個節點的集群中使用該功能。 一、概述 前一篇文章 Kubernetes 調度器淺析,大致講述了調度器的工作原理及相關調度策略。這一章會繼續深入調度器,介紹下親和性調度。 Kubernetes 支持限制...
摘要:本文將主要分析原生的網絡策略。筆者認為這個問題主要是因為使用者不了解網絡策略的省缺行為。可選字段,字符串,策略規則類型,表示該網絡策略中包含哪些類型的策略,可選為或。互相間為或的關系,滿足其中一條則放行。標準,除了指定的放行外其他都禁止。 k8s中的網絡策略主要分為原生 NetworkPolicy 和第三方網絡插件提供的網絡策略。本文將主要分析原生Networkpolicy的網絡策略。...
摘要:在這種情況下,以防干擾其他集群租戶,調度器可能會考慮將作為驅逐的候選對象。其結果是負載均衡和調度之間交互作用。 每當談及Kubernetes,我們經常聽到諸如資源管理、調度和負載均衡等術語。雖然Kubernetes提供了許多功能,但更關鍵的還是要了解這些概念,只有這樣才能更好地理解如何放置、管理并恢復工作負載。在這篇文章中,我提供了每個功能的概述,并解釋了它們是如何在Kubernete...
閱讀 3170·2021-09-10 10:51
閱讀 3351·2021-08-31 09:38
閱讀 1639·2019-08-30 15:54
閱讀 3129·2019-08-29 17:22
閱讀 3214·2019-08-26 13:53
閱讀 1960·2019-08-26 11:59
閱讀 3283·2019-08-26 11:37
閱讀 3308·2019-08-26 10:47