1. 程式人生 > >kubernetes Pod 資源調度

kubernetes Pod 資源調度

sum onf 托管 mos 狀況 lock tor 相加 size

1 概述

1 總述

API server 接受客戶端提交的POD對象創建請求操作過程中,需要kube-scheduler 從當前集群中選擇一個可用的最佳節點接受並運行,通常是默認調度器復制此類任務,對於每個待創建的POD來說,需要經過三個步驟。
1 預選(predicate)
節點預選: 基於一系列預選規則(podfitsresources 和 matchnode-selector等)對每個節點進行檢查,將那些不符合條件的節點過濾。
如果需要某些特殊服務,則需要通過組合節點標簽,以及POD標簽或標簽選擇器等來激活特定的預選策略以完成高級調度
2 優選 (priority)
3 選定 (select)

選定: 從優先級排序結果中挑出優先級最高的節點運行POD對象,當此類節點多於一個時,則從中隨機選擇一個。


K8S 內建了適合絕大多數場景的POD資源調度需求的默認調度器,支持同時使用算法基於原生及可定制的工具來選擇出集群中適合運行當前POD 資源的一個節點,其核心在於資源可用性POD資源公平分布與集群節點之上。

他們用於為用戶提供自定義POD親和性或反親和性,節點親和性以及基於汙點容忍度的調度機制。

2 預選策略(一票否決制)

1 概述

技術分享圖片

執行預選操作時,調度器將對每個節點基於配置使用的預選策略以特定次序逐一選擇,並根據一票否決機制進行淘汰,若預選過後不存在任何一個滿足條件的節點,則POD被置於pending狀態,直到至少有一個幾點可用為止。

目前支持的預選策略

1 checknodecondition : 檢查是否可以在節點寫入磁盤,網絡不可用或為準備好的情況下將POD對象調度與其上。


2 hostname: 若POD 對象擁有spec.hostname 屬性,則檢查節點名稱字符串與此屬性是否匹配,並不是必須這個POD運行在這個節點上,是否定義了hostname並且是否匹配
pods.spec.hostname


3 podfitsHostPorts: 若POD 定義了Ports.hostPort 屬性,則檢查其值指定的端口是否已經被節點上其他容器或服務占用


4 matchNodeselector: 若POD 對象定義了spec.nodeSelector 屬性,則檢查節點標簽是夠能匹配此屬性值


5 NoDiskConflict: 檢查POD對象請求的存儲卷在此節點是否可用,若不存在沖突則通過檢查,默認並沒有啟用


6 PODFITSresources: 檢查節點是否有足夠的資源滿足POD對象的運行需求,節點聲明可用容量,那些在註解中標記為關鍵性(critical)的POD資源不受此預選策略控制,是否有足夠的資源來滿足相關的需求,每一個節點都會聲明其節點資源的可用量

[[email protected] ~]# kubectl describe nodes node1
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits


cpu 100m (2%) 100m (2%)
memory 50Mi (5%) 50Mi (5%)


7 PODToleratesNodeTaints: 若POD對象定義了spec.tolerations 屬性,則檢查其值是否能夠接納節點定義的汙點(taints),不過,其僅關註具有NoSchedule 和 Noexecute 兩個效用標識的汙點 ,檢查pod上的汙點。其默認是沒有被啟用的。


8 PODTOleratesNodeNoExecuteTaints: 若POD 對象定義了spec.tolerations屬性,則檢查其是否能夠接納節點定義的NOexecute類型的汙點。


9 checknodelabelpresence: 僅檢查節點上指定的所有標簽的存在性,要檢查的標簽以及其可否存在於用戶的定義,當集群中部署的節點以regions/zones/racks 的拓撲方式放置且置於此類標簽對其進行位置標識時,預選策略可以根據此類標識將POD資源調度至此類節點上。不在預選策略內,沒有啟用。


10 checkserviceaffinity: 根據當前POD對象所屬的service已有的其他POD對象所運行的節點進行調度,其目的在於將相同service的POD 對象放置與同一個或同一類節點上以提高效率,此預選此類試圖將那些在其節點選擇器中帶有特定標簽的POD資源調度至擁有同樣標簽的節點上,具體的標簽則取決於用戶的定義。默認沒有啟用。


11 MAxEBsVOLUMEconunt: 檢查節點上已掛載的EBS存儲卷數量是夠超過了設置的最大值,默認為39 EBS 亞馬遜的彈性存儲卷。


12 MaxGCEPDVolumeCount: 檢查節點上已掛載的GCE PD存儲卷數量是否超過了設置的最大值,默認為16


13 MaxAzureDiskVolumeCount: 檢查節點上已掛載的Azure Disk 存儲卷數量是否超過設置的最大值,默認為16.


14 CheckVolumeBinding:檢查節點上已綁定和未綁定的PVC是否能夠滿足POD對象的存儲卷需求,對於已綁定的PVC,此預選策略將檢查給定節點是夠能夠兼容相應的PV,而對於未綁定的PVC,預選策略將搜索那些可滿足PVC申請的可用PV,並確保他可與給定的節點兼容。


15 NovolumeZoneConflict:在給定區域(zone)限制的前提下,檢查在此節點上部署POD對象是否存在存儲卷沖突,


16 CheckNodeMemoryPressure: 若給定的節點已經報告了在內存資源壓力過大的狀態,則檢查當前Pod對象是否可調度到此節點上,目前,最低優先級的BestEffort Qos類型的Pod資源也不能調度至此類節點上,因為其可能隨時內存溢出。


17 CheckNodePIDPressure:若給定的節點已經報告了POD資源壓力多大狀態,則檢查當前Pod對象是否可調度至節點之上。


18 CheckNodeDiskPressure:若給定節點已經報告了存在磁盤資源壓力過大的狀態,則檢查當前Pod對象是否可調度至此節點之上。


19 MatchinterPodAffinity:檢查給定節點是否能夠滿足Pod對象的親和性和反親和性條件,用於實現Pod親和性調度或反親和性調度。


其中第checknodelabelpresence條和MatchinterPodAffinity條可根據相關的情況而匹配,其可稱為可選配置策略,余下的均稱為靜態策略,另外 NoDiskConflict 、 PODToleratesNodeTaints、checknodelabelpresence、checkserviceaffinity 沒有包含在默認預選策略中。

3 優選策略

1 概述

技術分享圖片

調度器向每個通過預選的節點傳遞一系列的優選函數來計算其優先級分值,優先級分值介於0到10 之間,其中0表示不適用,10表示最合適托管該POD對象

調度器還支持為每個優選函數指定一個簡單的由正數值表示的權重,進行節點優先級分值的計算時,首先將每個優選函數的計算得分乘以權重,然後將所有優選函數的得分相加從而得到最終的優先級分值。

2 優選策略

1 leastrequestedpriority:由節點空間資源與節點總容量的比值進行計算的,由CPU或內存資源的總容量減去已有POD對象需求的容量總和,再減去當前要創建的POD對象的需求容量得到的結果除以總容量。CPU 和 內存具有相同的權重,資源空間比例越高的界定得分就越高,計算公式為
(cpu((capacity-sum (requested)) 10/capacity) + memory ((capacity-sum (requested))\10 /capacity))/2
乘以10的原因是其優選的最高是10分,通過此得出的結果是0-10之間的數。


2 balancedresourceallocation: 以CPU 和內存資源占用率的相近程序作為評估標準,二者月接近節點權重越高,該優選及函數不能單獨使用,他需要leastrequestedpriority組合使用來平衡優化節點資源使用狀況,已選擇那些在部署當前POD資源後系統資更為均衡的節點 。

Nodepreferavoidpodspriority 優先比例占用很高,如果其傾向於不能運行此POD,則一般都不能運行此POD,節點註解信息,沒這個註解,則得分高


3 NodePreferAvoidPodsPriority: 此優選函數權限默認為10000,其將根據節點是夠設置了註解信息"sheduler.alpha.kubernetes.io/preferAvoidPods"來計算其優先級,計算方式為: 給定節點無此註解信息,其得分乘以10以權重10000;存在此註解信息時,對於那些由replicationcontroller或replicaset控制器管控的POD對象得分為0,其他POD對象會被忽略


4 NodeAffinityPriority: 基於節點親和性調度偏好進行優先級評估,其將根據POD資源中的nodeselector 對給定節點進行匹配度檢查,成功匹配到的條目卻多得分越高.


5 TaintTolerationPriority: 基於Pod資源對節點的汙點容忍度偏好進行優先級評估,它將Pod對象的tolerations列表與節點的汙點進行匹配度檢查,成功匹配的條目越多,則節點得分越低。


6 selectorSpreadpriority: 首先查找與當前POD對象匹配的service、replicationcontroller、replicaset和statusfulset,盡量調度到多個不同的節點上。如果指定了區域,調度器則會盡量把Pod分散在不同區域的不同節點上。當一個Pod的被調度時,會先查找Pod對於的service或者replication controller,然後查找service或replication controller中已存在的Pod,運行Pod越少的節點的得分越高。

SelectorSpreadPriority舉例說明:這裏主要針對多實例的情況下使用。例如,某一個服務,可能存在5個實例,例如當前節點已經分配了2個實例了,則本節點的得分為10*((5-2)/ 5)=6分,而沒有分配實例的節點,則得分為10 * ((5-0) / 5)=10分。沒有分配實例的節點得分越高。

註:1.0版本被稱之為ServiceSpreadingPriority,1.0之後版本變更為SelectorSpreadPriority,為了向前兼容ServiceSpreadingPriority名稱仍然保留。


7 interpodaffinitypriority: 遍歷Pod對象的親和性條目,並將那些能夠匹配到給定節點的條目的權重相加,結果值越大得分越高


8 mostrequestedpriority:與優選函數leastrequestedpriority的評估節點得分方式相同,其不同的是,資源占用比例越大的節點,其得分越高。


9 NodeAffinityPriority:Kubernetes調度中的親和性機制。Node Selectors(調度時將pod限定在指定節點上),支持多種操作符(In, NotIn, Exists, DoesNotExist, Gt, Lt),而不限於對節點labels的精確匹配。另外,Kubernetes支持兩種類型的選擇器,一種是“hard(requiredDuringSchedulingIgnoredDuringExecution)”選擇器,它保證所選的主機必須滿足所有Pod對主機的規則要求。這種選擇器更像是之前的nodeselector,在nodeselector的基礎上增加了更合適的表現語法。另一種是“soft(preferresDuringSchedulingIgnoredDuringExecution)”選擇器,它作為對調度器的提示,調度器會盡量但不保證滿足NodeSelector的所有要求。
NodePreferAvoidPodsPriority(權重1W):如果 節點的 Anotation 沒有設置 key-value:scheduler. alpha.kubernetes.io/ preferAvoidPods = "...",則節點對該 policy 的得分就是10分,加上權重10000,那麽該node對該policy的得分至少10W分。如果Node的Anotation設置了,scheduler.alpha.kubernetes.io/preferAvoidPods = "..." ,如果該 pod 對應的 Controller 是 ReplicationController 或 ReplicaSet,則該 node 對該 policy 的得分就是0分。
TaintTolerationPriority : 使用 Pod 中 tolerationList 與 節點 Taint 進行匹配,配對成功的項越多,則得分越低。

另外在優選的調度規則中,有幾個未被默認使用的規則:


10 ImageLocalityPriority:根據Node上是否存在一個pod的容器運行所需鏡像大小對優先級打分,分值為0-10。遍歷全部Node,如果某個Node上pod容器所需的鏡像一個都不存在,分值為0;如果Node上存在Pod容器部分所需鏡像,則根據這些鏡像的大小來決定分值,鏡像越大,分值就越高;如果Node上存在pod所需全部鏡像,分值為10。

Kubernetes 的默認調度器以預選。優選、選定機制完成將每個新的POD資源綁定至為其選出的目標節點上,不過,其是默認調度器,使用中,用戶還可以自定義調度器插件,並在定義POD資源配置清單時通過spec.schedulerName指定即可使用。

4 選定

當有多個相同的優選選項時,則進行隨機選擇

2 節點親和度和Pod資源親和度

1 節點親和度概述

1 概述

親和性調度時用來確定Pod對象調度位置的規則,其是基於節點上自定義的標簽和Pod對象上指定的標簽選擇器進行定義的,節點親和性允許Pod對象針對一組可以調度於其上的節點設置親和性和反親和性,但無法具體到某個節點。

2 節點親和度的兩種規則:

1 硬親和:強制性規則,是Pod調度必須滿足的調遣,在不存在滿足此條件的節點存在時,其將一直處於pending狀態。

2 軟親和:其傾向於將Pod對象運行與某類特定的節點之上,而調度器也將盡量滿足需求,若無滿足條件的節點,其也將會選擇一個節點運行此Pod。

3 定義節點親和性的關鍵要素

1 為節點設置符合的標簽
2為Pod對象定義合理的標簽選擇器

4 節點親和度應用場景

若Pod調度至此節點後此節點標簽發生變化而不再符合親和性規則,則調度器不會將其Pod對象從節點移除,因為其僅對新建的Pod對象生效。

2 節點親和度

1節點硬親和度

1 概述

為POD 對象使用nodeselector屬性可以基於節點標簽匹配的方式將POD對象強制調度至某一類特定的節點上,不過他僅能基於簡單的等值關系定義標簽選擇器,而nodeaffinity中支持使用matchExpressions 屬性構建更為復雜的標簽選擇機制

2 核心字段

pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms.matchExpressions  

pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms.matchExpressions.key :鍵名稱 

pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms.matchExpressions.operator : 指定匹配規則,有包含IN ,不包含NotIn,Exists 存在 ,DoesNotExist 不存在 

pods.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms.matchExpressions.values : 指定key對應value值的列表

3 應用

查看節點標簽
技術分享圖片

配置硬親和性
實例

[[email protected] all]# cat demo.yaml 
apiVersion: v1
kind: Pod
metadata:
    name: demo2
    namespace: default
spec:
    containers:
        - name: demo2
          image: nginx:1.14
    affinity:  #定義親和性
        nodeAffinity:  #定義節點親和性
            requiredDuringSchedulingIgnoredDuringExecution:  #定義節點硬親和性
                nodeSelectorTerms:  #定義選擇器方式
                    - matchExpressions:  #定義選擇策略
                        - key: service  #定義選擇器key值
                          operator: In #定義關系為包含關系
                          values: ["web1"]  #定義values值

部署

 kubectl apply -f demo.yaml

查看
技術分享圖片
其不能被調度到任何節點上

技術分享圖片

修改節點標簽

kubectl label nodes 192.168.1.30  service=web1 --overwrite

查看節點標簽和Pod運行狀態
技術分享圖片
此時運行正常。

requiredDuringSchedulingIgnoredDuringExecution 字段的值是一個對象列表,用以定義節點硬親和性,其可由一個或多個nodeSelectorTerms 定義的對象組成,彼此之間為"邏輯或"的關系,進行匹配度檢查時,多個nodeSelectorTerms之間是或的關系,只要滿足其中之一即可,nodeselectorterm:用於定義節點選擇器的條目,其值為對象列表,其可由一個或多個matchExpressions對象定義的匹配規則組成,多個規則之前為"邏輯與"的關系,而matchexpression對象由可由多個標簽選擇器組成,多個標簽選擇器之間彼此為"邏輯與"的關系。


節點硬親和性實現的功能與節點選擇器相似,但親和性支持使用匹配表達式來挑選節點,此比節點選擇器更加靈活。

2 節點軟親和性

1 概述

節點軟親和性為節點選擇機制提供了一種柔性控制邏輯,被調度的POD對象不再是“必須”而是“應該”放置於某個特定節點之上,當條件不滿足時,他也能夠接受被編排與其他不符合調節的節點之上,另外,其還為每種傾向性提供了weight 屬性以便用戶定義其優先級,取值範圍1-100, 數字越大優先級越高。

2 核心字段

pods.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution.preference : 定義選擇策略

pods.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution.weight: 定義傾向性優先級,數字越大越優先
為節點1添加標簽

3 應用

技術分享圖片

實例

#[[email protected] all]# cat demo1.yaml 
apiVersion: v1
kind: Pod
metadata:
    name: demo3
    namespace: default
spec:
    containers:
        - name: demo3
          image: nginx:1.14
    affinity:  #定義親和性
        nodeAffinity:  #定義節點親和性
            preferredDuringSchedulingIgnoredDuringExecution:  #定義節點軟親和性
                - weight: 60  #定義傾向性
                  preference: #定義匹配規則
                    matchExpressions:
                        - {key: rule, operator: In, values: ["test"]}
                - weight: 30
                  preference:
                    matchExpressions:
                        - {key: service, operator: In, values: ["db1"]}

部署

 kubectl apply -f demo1.yaml

查看
技術分享圖片

Pod 資源模板定義了對rule和service的標簽選擇,其對應的value都不匹配,但由於rule設置了高傾向性,則選擇了具有rule標簽key值對應的節點,若有足夠多的節點,則其將被視為三類:
1 同時滿足以上兩種標簽
2 僅具有任何一種標簽
3 不具備任何標簽

同時部署多個服務

[[email protected] all]# cat demo1.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
    name: demo
    namespace: default
spec:
    selector:
        matchLabels:
            app: nginx10
    replicas: 3
    template:
        metadata:
            name: demo3
            namespace: default
            labels:
                app: nginx10
        spec:
            containers:
                - name: demo3
                  image: nginx:1.14
            affinity:  #定義親和性
                nodeAffinity:  #定義節點親和性
                    preferredDuringSchedulingIgnoredDuringExecution:  #定義節點軟親和性
                        - weight: 60  #定義優先級
                          preference: #定義匹配規則
                            matchExpressions:
                                - {key: rule, operator: In, values: ["test"]}
                        - weight: 30
                          preference:
                            matchExpressions:
                                - {key: service, operator: In, values: ["db1"]}

部署

 kubectl apply -f demo1.yaml 

查看
技術分享圖片

及結果顯示,其不止運行與192.168.1.30節點上,因為此處預選策略都已通過,但其需要優選策略進行選擇,選擇結果即為上述結果

3 Pod資源親和度

1 概述

其原理將第一個POD放置在隨意節點上,而後其他POD與其有親和或反親和關系的POD據此動態完成位置編排

POD 的親和性定義存在硬親和和軟親和,其與節點親和性定義大體相同。

kubernetes 調度器通過內建的MatchinterPodAffinity 預選策略為這種調度方式完成節點預選,並基於InterPodAffinityPriority優選函數進行各個節點的優先級評估


2 位置拓撲

POD 親和性調度需要各相關的POD對象運行在"同一位置",而反親和性則要求他們不能運行於同一位置。 如果以基於各節點的hostname標簽作為評判標準,則"同一位置"意味著同一個節點,不同節點及不同位置。如果基於標簽選擇,則可以按照設定的標簽來評判。
在定義POD對象的親和性與反親和性時,需要借助標簽選擇器來選擇被依賴的POD對象,並根據選出的POD對象所在的節點的標簽來判斷同一位置的意義。

3 POD 硬親和度

1 概述

POD 強制約束的親和性調度也使用pods.spec.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution屬性進行定義,POD親和性用於描述一個POD對象與具有某些特征的現存POD對象運行位置的依賴關系

2 應用

1 創建一個人具有特定標簽的POD對象

kubectl  run  tomcat -l app=tomcat  --image=tomcat:alpine

查看服務,其運行於192.168.1.40節點,且其label為app=tomcat

技術分享圖片

實例

[[email protected] all]# cat demo.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
    name: demo-dep
    namespace: default
spec:
    selector:
        matchLabels:
            app: nginx 
    replicas: 3
    template:
        metadata:
            namespace: default
            labels:
                app: nginx
        spec:
            containers:
                - name: nginx-demo
                  image: nginx:1.14
            affinity:
                podAffinity:  #配置節點親和性
                    requiredDuringSchedulingIgnoredDuringExecution:  #配置硬親和性
                        - labelSelector:
                            matchExpressions:  # 配置匹配親和性的標簽
                                - {key: app,operator: In,values: ["tomcat"]}
                          topologyKey: kubernetes.io/hostname #位置拓撲鍵,其是基於hostname級別的位置

部署

kubectl apply -f demo.yaml

查看
技術分享圖片

其所有POD都匹配到192.168.1.40節點上去

3 選擇過程

1 調度器首先會基於標簽選擇查詢擁有標簽"app=tomcat"的所有POD資源
2 若存在多個則會分別獲取到其所屬節點的hostname標簽值
3 接著查詢這些擁有hostname標簽值的所有節點,
4 若存在多個,則會根據優選函數進行優選處理,從而選出合適運行的節點。

kubernetes.io/hostname 標簽時kubernetes集群節點的內建標簽,其值是當前界定啊的節點主機名標識,對各個節點各有不同。

基於單節點的POD親和性只能在個別情況中用到,較為常用的是基於同一地區region,區域zone或機架rack的位置拓撲約束,其只需要修改上述 deployment.spec.template.spec.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution.topologyKey 字段的屬性值即可。

4 POD 軟親和調度

1 概述

pods.spec.affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution
調度器會盡力確保滿足親和性的調度邏輯,然而在約束條件不滿足的情況下,它允許將POD對象調度至其他節點運行。

2 應用

創建另一個應用

kubectl run tomcat1  -l  app=tomcat1 --image=tomcat:alpine

查看
技術分享圖片
技術分享圖片

實例

[[email protected] all]# cat demo.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
    name: demo-dep
    namespace: default
spec:
    selector:
        matchLabels:
            app: nginx 
    replicas: 3
    template:
        metadata:
            namespace: default
            labels:
                app: nginx
        spec:
            containers:
                - name: nginx-demo
                  image: nginx:1.14
            affinity:
                podAffinity:  #配置節點親和性
                    preferredDuringSchedulingIgnoredDuringExecution:
                        - weight: 80  #定義權重
                          podAffinityTerm:
                            labelSelector:
                                matchExpressions:  #配置匹配規則
                                    - {key: app,operator: In,values: ["tomcat"]}
                            topologyKey: service

                        - weight: 40
                          podAffinityTerm:
                            labelSelector:
                                matchExpressions:
                                    - {key: app,operator: In,values: ["tomcat1"]}
                            topologyKey: service

部署

kubectl apply -f demo.yaml 

查看
技術分享圖片

上述定義了兩組親和性判斷機制,一種是選擇值為tomcat的POD所在的節點的service標簽,並賦予了較高的權限,另一種是選擇值為tomcat1的POD所在的service標簽,其權限較低,然其權限較高的節點192.168.1.40上具有兩個POD,但另一個POD仍然運行在權限較低的192.168.1.30節點上,這既是軟親和性。

4 POD 反親和調度

1 概述

pods.spec.affinity.podAntiAffinity
反親和度一般用於分散同一類應用的POD對象,也包括將不同安全級別的POD對象調度至不同的區域,機架或節點。

2 反親和度硬親和

刪除之前配置

kubectl delete -f demo.yaml
kubectl delete deployment tomcat1

查看當前服務情況
技術分享圖片
配置服務的反親和性硬親和性
實例

[[email protected] all]# cat demo.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
    name: demo-dep
    namespace: default
spec:
    selector:
        matchLabels:
            app: nginx 
    replicas: 3
    template:
        metadata:
            namespace: default
            labels:
                app: nginx
        spec:
            containers:
                - name: nginx-demo
                  image: nginx:1.14
            affinity:
                podAntiAffinity:
                    requiredDuringSchedulingIgnoredDuringExecution:  #定義反親和性的硬親和度
                        - labelSelector:
                            matchExpressions:
                                - {key: app,operator: In,values: ["tomcat"]}
                          topologyKey: kubernetes.io/hostname  #以節點為區域進行劃分

部署

kubectl apply -f demo.yaml 

查看
技術分享圖片

3 反親和度軟親和

POD反親和性調度也支持使用柔性調度約束機制,在調度時,它將盡量滿足將不同位置相斥的Pod對象調度在同一位置,但是,當約束關系無法滿足時,也可以違反約束而調度,其實例與上述POD的柔性調度類似,此處便不一一舉例了。

3 汙點和容忍度

1 概述

汙點 taints 是定義在節點之上的鍵值屬性數據,用於拒絕將POD調度運行於其節點上,除非該POD對象具有接納汙點的容忍度,而容忍度是定義在POD對象上的鍵值性屬性數據,用於配置節點可容忍的節點汙點,而且調度器僅能將POD對象調度至其能容忍該節點汙點的節點之上。

汙點容忍度是通過向節點添加汙點信息來控制POD對象的調度結果,從而賦予了節點控制何種POD對象能夠調度特定節點上

kubernetes 使用podtoleratesnodetaints預選策略和 tainttolerationpriority優選函數來完成此種類型的高級調度機制。

2 定義汙點和容忍度

1 汙點

1 核心字段

nodes.spec.taintsd 核心字段
nodes.spec.taints.effect :用於定義POD對象的排斥等級,主要包含三種類型:
  1 NoSchedule: 不能容忍此汙點的新POD對象不可調度至當前節點,屬於強制約束關系,節點上現存的POD對象不受影響
  2 PreferNoSchedule:noschedule的柔性約束版本,即不能容忍此汙點的新POD對象盡量不要調度至當前節點,不過無其他節點可提供調度時才允許接收相應的POD對象,節點現存的POD對象不受影響 
  3 NoExecute:不能容忍此汙點的新POD對象不可調度至當前節點,屬於強制型約束關系,而且節點上現存的POD對象因節點汙點變動或POD容忍度變動而不再滿足匹配規則時,該POD對象將會被驅逐,即影響調度過程,也影響現存的節點,不能容忍的POD將會被直接驅逐。

nodes.spec.taints.key:定義匹配的key值 
nodes.spec.taints.value: 定義匹配的value值 

2 容忍度

1 核心字段

pods.spec.tolerations.operator : 定義容忍度匹配方式
    POD 對象定義容忍度時,支持兩種操作符: 
    1 等值比較(Equal): 表示容忍度與汙點必須在key、value和effect三者之上完全匹配
    2 存在性判斷(Exists): 表示兩者的key值和effect必須完全匹配,而容忍度中的value字段要使用空值。
pods.spec.tolerations.key :定義匹配的KEY 
pods.spec.tolerations.effect:定義與汙點匹配的排斥等級,此處為空切operator為Exists是表示可容忍所有級別的汙點,但其他還需和key匹配決定。
pods.spec.tolerations.tolerationSeconds: 定義被驅逐的時長,僅當effect 為 NoExecute 時使用 
pods.spec.tolerations.value:匹配的value值

一個節點可以配置使用多個汙點,一個POD對象也可以有多個容忍度,但必須遵循以下邏輯:
1 首先處理每個有著與之匹配的容忍度的汙點

2 不能匹配到的汙點上,如果存在了一個汙點使用了Noschedule 效用標識,則拒絕調度POD對象至此節點,各個汙點之間是與的關系,及一個不滿足,則全部不會被調度到此節點上。

3 不能匹配到的汙點上,若沒有任何一個使用了noschedule 效用標識,但至少有一個使用了preferNoshedule,則應盡量避免將POD對象調度至此節點

4 如果至少有一個不匹配的汙點使用了NoExecute 效用標識,則節點將立即驅除POD對象,或不予以調度至給定節點,另外,即便容忍度可以匹配到使用了Noexcute效用標識的汙點,若在定義容忍度時還同時使用了tolerationseconds屬性定義了容忍時限,則超出時間後其也將被節點驅逐。


kubernetes中視同kuebadm部署集群時,其master節點自動添加了汙點信息以組織不能容忍此汙點的POD對象調度至此節點,若是單節點,則需註意此處,但在kubernetes中,kube-proxy 和kube-flannel等,都在資源創建時就已經添加了容忍度來確保其能夠調度至master節點。

技術分享圖片

3 管理節點汙點

1 汙點定義規則

任何符合其鍵值規範要求的字符串均可用以定義汙點信息:僅可使用字母,數字,連接符,點號和下劃線,且僅能以字母或數字開頭,其中鍵名的長度上限為253個字符,值最長為63個字符。

2 汙點操作

添加汙點
其使用kubectl taint 命令即可向節點添加汙點,命令語法如下

kubectl taint NODE NAME KEY_1=VAL_1:TAINT_EFFECT_1 ...
KEY_N=VAL_N:TAINT_EFFECT_N [options]

為192.168.1.30節點定義汙點,使其不能容忍此汙點的POD不能調度至此節點上,其key為node-type,value為web

kubectl taint nodes 192.168.1.30 node-type=web:NoSchedule

查看汙點信息

 kubectl get  nodes 192.168.1.30   -o go-template={{.spec.taints}}

技術分享圖片

刪除汙點
語法

 kubectl get  nodes 192.168.1.30   -o go-template={{.spec.taints}}
kubectl taint nodes 192.168.1.30 node-type:NoSchedule-

查看
技術分享圖片
刪除節點上所有汙點

kubectl patch nodes  192.168.1.30 -p ‘{"spec": {"taints": []}}‘

3 配置容忍度

1 添加節點汙點

kubectl taint  nodes 192.168.1.30 app=web:NoSchedule 
kubectl taint  nodes 192.168.1.40 app=db:NoSchedule

查看
技術分享圖片

2 實例

kubectl run nginx --image=nginx:1.14  --replicas=2

查看
技術分享圖片
其不能被調度至任何節點

配置有容忍度的POD資源

[[email protected] all]# cat demo1.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
    name: my-deployment
    namespace: default
spec:
    replicas: 3
    selector:
        matchLabels:
            app: myapp
            release: canary
    template:
        metadata:        
            labels:
                app: myapp
                release: canary
        spec:
            containers:
                - name: myapp
                  image: ikubernetes/myapp:v2
                  ports:
                    - name: http
                      containerPort: 80
            tolerations: 
                - key: "app"  #定義key值
                  effect: "NoSchedule"  #定義容忍度類別
                  operator: "Equal"  #定義匹配方式為等值匹配
                  value: "web"  #定義匹配值

部署

kubectl apply -f demo1.yaml 

查看
技術分享圖片

可以部署到指定節點和其相關匹配的標簽所在的節點上

3 部署存在性判斷

[[email protected] all]# cat demo2.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
    name: my-deployment1
    namespace: default
spec:
    replicas: 3
    selector:
        matchLabels:
            app: myapp1
            release: canary
    template:
        metadata:        
            labels:
                app: myapp1
                release: canary
        spec:
            containers:
                - name: myapp1
                  image: ikubernetes/myapp:v2
                  ports:
                    - name: http
                      containerPort: 80
            tolerations: 
                - key: "app"  #定義key值
                  effect: "NoSchedule"  #定義容忍度類別,若此處為空,則表示容忍所有級別的汙點
                  operator: "Exists"  #定義匹配方式為存在性判斷,只要鍵和容忍級別和鍵相同,即可調度至該節點上
                  value: ""  #定義匹配值,若是存在性判斷,則此處可以為空

刪除之前部署並重新部署

kubectl  delete  deployment demo-dep
kubectl apply -f demo2.yaml 

查看結果
技術分享圖片

4 配置 NoExecute
刪除之前192.168.1.40配置,並重新定義汙點

kubectl taint nodes 192.168.1.40 app:NoSchedule-
kubectl taint  nodes 192.168.1.40 app=db:NoExecute

查看服務
技術分享圖片

這些服務因為不匹配而導致其處於為未成功調度狀態。

4 擴展

內建的汙點:
1  node.kubernetes.io/not-ready: 節點進入"NotReady"狀態時被自動添加的汙點
2 node.alpha.kubernetes.io/unreadchable: 節點進入"NotReachable"狀態時被自動添加的汙點
3 node.kubernetes.io/out-of-disk: 節點進入"outOfDisk"狀態時被自動添加的汙點
4 node.kubernetes.io/memory-pressure: 節點磁盤資源面臨壓力
5 node.kubernetes.io/network-unavailable: 節點網絡不可用
6 node.cloudprovider.kubernetes.io/uninitialized:kubelet由外部的雲環境程序啟動時,將自動為節點添加此汙點,待到雲控制器管理器中的控制器初始化此節點時再將其刪除。

kubernetes Pod 資源調度