Kubernetes調度由淺入深:初探

從CNCF基金會的成立,到Kubernetes社區蓬勃發展,歷經6載,17年異軍突起,在mesos、swarm等項目角逐中,拔得頭籌,繼而一統容器編排,其成功的關鍵緣由可歸納爲如下幾點:node

  • 項目領導者們的堅守與遠見
  • 社區的良好的運做與社區文化
  • 社區與企業落地的正反饋

雖然針對kubernetes的介紹已經比較多了,可是雲原生仍是Kubernetes項目的發展都已經邁入深水區,於是今天zouyee爲你們帶來《kuberneter調度由淺入深》,但願經過接下來的五篇文章,讓各位可以系統深刻的瞭解kubernetes調度系統,該系列對應版本爲1.20.+,今天帶來《Kubernetes調度系統由淺入深系列:初探》算法

1、調度簡介

​ 在開始前,先來看看Kubernetes的架構示意圖,其中控制平面包含如下三大組件:kube-scheduler、kube-apiserver、kube-controller-manager。kubelet及kube-proxy組件的分析咱們後續單獨成章進行講解,如今咱們能夠簡單給理解上述組件的難易程度排個序,kube-apiserver、kubelet、kube-scheduler、kube-controller-manager、kube-proxy。api

Components of Kubernetes

{%note danger%}markdown

​ 如上所述,kube-scheduler是K8S系統的核心組件之一,其主要負責Pod的調度,其監聽kube-apiserver,查詢未分配 Node的Pod(未分配、分配失敗及嘗試屢次沒法分配),根據配置的調度策略,將Pod調度到最優的工做節點上,從而高效、合理的利用集羣的資源,該特性是用戶選擇K8S系統的關鍵因素之一,幫助用戶提高效率、下降能耗。架構

{%endnote%}函數

kube-scheduler 負責將Pod 調度到集羣內的最佳節點(基於相應策略計算出的最佳值)上,它監聽 kube-apiserver,查詢還未分配節點 的 Pod,而後根據調度策略爲這些 Pod 分配節點,執行綁定節點的操做(更新Pod的nodeName字段)。性能

​ 在上述過程當中,須要考慮如下問題:spa

  • 如何確保節點分配的公平性
  • 如何確保節點資源分配的高效性
  • 如何確保Pod調度的公平性
  • 如何確保Pod調度的高效性
  • 如何擴展Pod調度策略

爲解決上述的問題,kube-scheduler經過聚集節點資源、節點地域、節點鏡像、Pod調度等信息綜合決策,確保Pod分配到最佳節點,如下爲kube-scheduler的主要目標:插件

  • 公平性:在調度Pod時須要公平的決策,每一個節點都有被分配的機會,調度器須要針對不一樣節點做出平衡決策。
  • 資源高效:最大化提高全部可調度資源的利用率,使有限的CPU、內存等資源服務儘量更多的Pod。
  • 性能:能快速的完成對大規模Pod的調度工做,在集羣規模擴增的狀況下,依然能確保調度的性能。
  • 靈活性:在實際生產中,用戶但願Pod的調度策略是可擴展的,從而能夠定製化調度算法以處理複雜的實際問題。所以平臺要容許多種調度器並行工做,並支持自定義調度器。

2、調度流程

首先咱們經過下面的總體的交互圖,來構建Pod調度的直觀感覺。命令行

上述以建立一個Pod爲例,簡要介紹調度流程:

  1. 用戶經過命令行建立Pod(選擇直接建立Pod而不是其餘workload,是爲了省略kube-controller-manager)

  2. kube-apiserver通過對象校驗、admission、quota等准入操做,寫入etcd

  3. kube-apiserver將結果返回給用戶

  4. 同時kube-scheduler一直監聽節點、Pod事件等(流程1)

  5. kube-scheduler將spec.nodeName的pod加入到調度隊列中,進行調度週期(該週期即位後續介紹內容)(流程2-3)

  6. kube-scheduler將pod與得分最高的節點進行binding操做(流程4)

  7. kube-apiserver將binding信息寫入etcd

  8. kubelet監聽分配給本身的Pod,調用CRI接口進行Pod建立(該部份內容後續出系列,進行介紹)

  9. kubelet建立Pod後,更新Pod狀態等信息,並向kube-apiserver上報

  10. kube-apiserver寫入數據

調度週期

kube-scheduler的工做任務是根據各類調度算法將Pod綁定(bind)到最合適的工做節點,整個調度流程分爲兩個階段:過濾和評分。流程示意圖以下所示。

​ 注:之前稱之爲predicate與priorities,當前統稱爲過濾與評分,實際效果一致

  • 過濾:輸入是全部節點,輸出是知足預選條件的節點。kube-scheduler根據過濾策略過濾掉不知足的節點。例如,若是某節點的資源不足或者不知足預選策略的條件如「節點的標籤必須與Pod的Selector一致」時則沒法經過過濾。

  • **評分:**輸入是經過過濾階段的節點,評分時會根據評分算法爲經過過濾的節點進行打分,選擇得分最高的節點。例如,資源越充足、負載越小的節點可能具備越高的排名。

​ 通俗點說,調度的過程就是在回答兩個問題:1. 候選節點有哪些?2. 其中最適合的是哪個?

​ 若是在過濾階段沒有節點知足條件,Pod會一直處在Pending狀態直到出現知足的節點,在此期間調度器會不斷的進行重試。若是有多個節點評分一致,那麼kube-scheduler任意選擇其一。

​ 注:Pod首先進入調度隊列,失敗後進入backoff,屢次失敗後進入unschedule,該部份內容後續介紹。

調度算法

當前支持兩種方式配置過濾、評分算法:

1. Scheduling Policies:經過文件或者configmap配置Predicate算法(過濾)和 Priorities算法(評分)的算法
2. Scheduling Profiles:當前調度系統爲插拔架構,其將調度週期分爲 `QueueSort`、`PreFilter`、`Filter`、`PreScore`、`Score`、`Reserve`、`Permit`、`PreBind`、`Bind`、`PostBind`等階段,經過定製調度週期中不一樣階段的插件行爲來實現自定義。
複製代碼

下面簡單介紹一下經過Scheduling Policies方式配置

pkg/scheduler/framework/plugins/legacy_registry.go

預選(Precates)

算法名稱 算法含義
MatchInterPodAffinity 檢查pod資源對象與其餘pod資源對象是否符合親和性規則
CheckVolumeBinding 檢查節點是否知足pod資源對象的pvc掛載需求
GeneralPredicates 檢查節點上pod資源對象數量的上線,以及CPU 內存 GPU等資源是否符合要求
HostName 檢查Pod指定的NodeName是否匹配當前節點
PodFitsHostPorts 檢查Pod容器所需的HostPort是否已被節點上其它容器或服務佔用。若是已被佔用,則禁止Pod調度到該節點
MatchNodeSelector 檢查Pod的節點選擇器是否與節點的標籤匹配
PodFitsResources 檢查節點是否有足夠空閒資源(例如CPU和內存)來知足Pod的要求
NoDiskConflict 檢查當前pod資源對象使用的卷是否與節點上其餘的pod資源對象使用的卷衝突
PodToleratesNodeTaints 若是當前節點被標記爲taints,檢查pod資源對象是否能容忍node taints
CheckNodeUnschedulable 檢查節點是否可調度
CheckNodeLabelPresence 檢查節點標籤是否存在
CheckServiceAffinity 檢查服務親和性
MaxCSIVolumeCountPred 若是設置了featuregate (attachvolumelimit)功能,檢查pod資源對象掛載的csi卷是否超出了節點上卷的最大掛載數量
NoVolumeZoneConflict 檢查pod資源對象掛載pvc是否屬於跨區域掛載,由於gce的pd存儲或aws的ebs卷都不支持跨區域掛載
EvenPodsSpreadPred 一組 Pod 在某個 TopologyKey 上的均衡打散需求

注:其中 MaxEBSVolumeCountPred、 MaxGCEPDVolumeCountPred MaxAzureDiskVolumeCountPred、MaxCinderVolumeCountPred 等雲廠商相關預選算法已經廢棄

優選(Priorities)

算法名稱 算法含義
EqualPriority 節點權重相等
MostRequestedPriority 偏向具備最多請求資源的節點。這個策略將把計劃的Pods放到整個工做負載集所需的最小節點上運行。
RequestedToCapacityRatioPriority 使用默認的資源評分函數模型建立基於ResourceAllocationPriority的requestedToCapacity。
SelectorSpreadPriority 將屬於相同service rcs rss sts 的pod儘可能調度在不一樣的節點上
ServiceSpreadingPriority 對於給定的服務,此策略旨在確保Service的Pods運行在不一樣的節點上。總的結果是,Service對單個節點故障變得更有彈性。
InterPodAffinityPriority 基於親和性(affinity)和反親和性(anti-affinity)計算分數
LeastRequestdPriority 偏向使用較少請求資源的節點。換句話說,放置在節點上的Pod越多,這些Pod使用的資源越多,此策略給出的排名就越低。
BalancedRequestdPriority 計算節點上cpu和內存的使用率,使用率最均衡的節點最優
NodePreferAvoidPodsPriority 基於節點上定義的註釋(annotaion)記分,註釋中若是定義了alpha.kubernetes.io/preferAvoidPods則會禁用ReplicationController或者將ReplicaSet的pod資源對象調度在該節點上
NodeAffinityPriority 基於節點親和性計算分數
TaintTolerationPriority 基於污點(taint)和容忍度(toleration)是否匹配計算分數
ImageLocalityPriority 基於節點上是否已經下拉了運行pod資源對象的鏡像計算分數
EvenPodsSpreadPriority 用來指定一組符合條件的 Pod 在某個拓撲結構上的打散需求

更多雲原生相關內容,請關注公衆號:DCOS。

相關文章
相關標籤/搜索