1、常用的預選策略
2、優選函數
3、節點親和調度
3.1、節點硬親和性
3.2、節點軟親和性
4、Pod資源親和調度
4.1、Pod硬親和度
4.2、Pod軟親和度
4.3、Pod反親和度
5、污點和容忍度
5.1、定義污點和容忍度
5.2、管理節點的污點
5.3、Pod對象的容忍度
API Server在接受客戶端提交Pod對象創建請求后,然后是通過調度器(kube-schedule)從集群中選擇一個可用的最佳節點來創建並運行Pod。
而這一個創建Pod對象,在調度的過程當中有3個階段:節點預選、節點優選、節點選定,從而篩選出最佳的節點。
節點預選:基於一系列的預選規則對每個節點進行檢查,將那些不符合條件的節點過濾,從而完成節點的預選
節點優選:對預選出的節點進行優先級排序,以便選出最合適運行Pod對象的節點
節點選定:從優先級排序結果中挑選出優先級最高的節點運行Pod,當這類節點多於1個時,則進行隨機選擇
當我們有需求要將某些Pod資源運行在特定的節點上時,我們可以通過組合節點標簽,以及Pod標簽或標簽選擇器來匹配特定的預選策略並完成調度,如MatchInterPodAfinity、MatchNodeSelector、PodToleratesNodeTaints等預選策略,這些策略常用於為用戶提供自定義Pod親和性或反親和性、節點親和性以及基於污點及容忍度的調度機制。
Pod資源調度
1、常用的預選策略
預選策略實際上就是節點過濾器,例如節點標簽必須能夠匹配到Pod資源的標簽選擇器(MatchNodeSelector實現的規則),以及Pod容器的資源請求量不能大於節點上剩余的可分配資源(PodFitsResource規則)等等。執行預選操作,調度器會逐一根據規則進行篩選,如果預選沒能選定一個合適的節點,此時Pod會一直處於Pending狀態,直到有一個可用節點完成調度。
2、優選函數
預選策略篩選出一個節點列表就會進入優選階段,在這個過程調度器會向每個通過預選的節點傳遞一系列的優選函數來計算其優先級分值,優先級分值介於0-10之間,其中0表示不適用,10表示最適合托管該Pod對象。
另外,調度器還支持給每個優選函數指定一個簡單的值,表示權重,進行節點優先級分值計算時,它首先將每個優選函數的計算得分乘以權重,然后再將所有優選函數的得分相加,從而得出節點的最終優先級分值。權重可以讓管理員定義優選函數傾向性的能力,
3、節點親和調度
節點親和性是用來確定Pod對象調度到哪一個節點的規則,這些規則基於節點上的自定義標簽和Pod對象上指定的標簽選擇器進行定義。
定義節點親和性規則有2種:硬親和性(require)和軟親和性(preferred)
硬親和性:實現的是強制性規則,是Pod調度時必須滿足的規則,否則Pod對象的狀態會一直是Pending
軟親和性:實現的是一種柔性調度限制,在Pod調度時可以盡量滿足其規則,在無法滿足規則時,可以調度到一個不匹配規則的節點之上。
定義節點親和規則的兩個要點:一是節點配置是否合乎需求的標簽,而是Pod對象定義合理的標簽選擇器,這樣才能夠基於標簽選擇出期望的目標節點。
需要注意的是preferredDuringSchedulingIgnoredDuringExecution和requiredDuringSchedulingIgnoredDuringExecution名字中后半段字符串IgnoredDuringExecution表示的是,在Pod資源基於節點親和性規則調度到某個節點之后,如果節點的標簽發生了改變,調度器不會講Pod對象從該節點上移除,因為該規則僅對新建的Pod對象有效。
4、Pod資源親和調度
在出於高效通信的需求,有時需要將一些Pod調度到相近甚至是同一區域位置(比如同一節點、機房、區域)等等,比如業務的前端Pod和后端Pod,此時這些Pod對象之間的關系可以叫做親和性。
同時出於安全性的考慮,也會把一些Pod之間進行隔離,此時這些Pod對象之間的關系叫做反親和性(anti-affinity)。
調度器把第一個Pod放到任意位置,然后和該Pod有親和或反親和關系的Pod根據該動態完成位置編排,這就是Pod親和性和反親和性調度的作用。Pod的親和性定義也存在硬親和性和軟親和性的區別,其約束的意義和節點親和性類似。
Pod的親和性調度要求各相關的Pod對象運行在同一位置,而反親和性則要求它們不能運行在同一位置。這里的位置實際上取決於節點的位置拓撲,拓撲的方式不同,Pod是否在同一位置的判定結果也會有所不同。
如果基於各個節點的kubernetes.io/hostname標簽作為評判標准,那么會根據節點的hostname去判定是否在同一位置區域。
4.1、Pod硬親和度
Pod強制約束的親和性調度也是使用requiredDuringSchedulingIgnoredDuringExecution進行定義的。Pod親和性是用來描述一個Pod對象和現有的Pod對象運行的位置存在某種依賴關系,所以如果要測試Pod親和性約束,需要存在一個被依賴的Pod對象,下面創建一個帶有app=tomcat的Deployment資源部署一個Pod對象:
基於單一節點的Pod親和性相對來說使用的情況會比較少,通常使用的是基於同一地區、區域、機架等拓撲位置約束。比如部署應用程序(myapp)和數據庫(db)服務相關的Pod時,這兩種Pod應該部署在同一區域上,可以加速通信的速度。
4.2、Pod軟親和度
同理,有硬親和度即有軟親和度,Pod也支持使用preferredDuringSchedulingIgnoredDuringExecuttion屬性進行定義Pod的軟親和性,調度器會盡力滿足親和約束的調度,在滿足不了約束條件時,也允許將該Pod調度到其他節點上運行。
4.3、Pod反親和度
podAffinity定義了Pod對象的親和約束,而Pod對象的反親和調度則是用podAntiAffinty屬性進行定義,
5、污點和容忍度
5.1、定義污點和容忍度
污點(taints)是定義在節點上的一組鍵值型屬性數據,用來讓節點拒絕將Pod調度到該節點上,除非該Pod對象具有容納節點污點的容忍度。而容忍度(tolerations)是定義在Pod對象上的鍵值型數據,用來配置讓Pod對象可以容忍節點的污點。
前面的節點選擇器和節點親和性的調度方式都是通過在Pod對象上添加標簽選擇器來完成對特定類型節點標簽的匹配,實現的是Pod選擇節點的方式。而污點和容忍度則是通過對節點添加污點信息來控制Pod對象的調度結果,讓節點擁有了控制哪種Pod對象可以調度到該節點上的 一種方式。
Kubernetes使用PodToleratesNodeTaints預選策略和TaintTolerationPriority優選函數來完成這種調度方式。
污點的定義是在節點的nodeSpec,而容忍度的定義是在Pod中的podSpec,都屬於鍵值型數據,兩種方式都支持一個effect標記,語法格式為key=value: effect,其中key和value的用戶和格式和資源注解類似,而effect是用來定義對Pod對象的排斥等級,主要包含以下3種類型:
NoSchedule:不能容忍此污點的新Pod對象不能調度到該節點上,屬於強制約束,節點現存的Pod對象不受影響。
PreferNoSchedule:NoSchedule屬於柔性約束,即不能容忍此污點的Pod對象盡量不要調度到該節點,不過無其他節點可以調度時也可以允許接受調度。
NoExecute:不能容忍該污點的新Pod對象不能調度該節點上,強制約束,節點現存的Pod對象因為節點污點變動或Pod容忍度的變動導致無法匹配規則,Pod對象就會被從該節點上去除。
在Pod對象上定義容忍度時,其支持2中操作符:Equal和Exists
Equal:等值比較,表示容忍度和污點必須在key、value、effect三者之上完全匹配。
Exists:存在性判斷,表示二者的key和effect必須完全匹配,而容忍度中的value字段使用空值。
在使用kubeadm部署的集群中,master節點上將會自動添加污點信息,阻止不能容忍該污點的Pod對象調度到該節點上,
5.2、管理節點的污點
此時,node01節點上已經存在的Pod對象不受影響,僅對新建Pod對象有影響,需要注意的是,如果是同一個鍵值數據,但是最后的標識不同,也是屬於不同的污點信息,比如再給node01上添加一個污點的標識為:PreferNoSchedule
5.3、Pod對象的容忍度
Pod對象的容忍度可以通過spec.tolerations字段進行添加,同一的也有兩種操作符:Equal和Exists方式。