默認的scheduler的調度過程:
1.預選策略:從所有節點當中選擇基本符合選擇條件的節點。
2.優選函數:在眾多符合基本條件的節點中使用優選函數,計算節點各自的得分,通過比較進行排序。
3.從最高得分的節點中隨機選擇出一個作為Pod運行的節點。
可以通過自己的預設來影響預選、優選過程,從而實現符合我們期望的調度結果。
影響調度方式:
1.節點選擇器:NodeSelector,甚至可以設置nodename來選擇節點本身。
2.親和性調度:NodeAffinity(節點親和性)、podAffinity(Pod親和性)、PodAntiAffinity(Pod的反親和性)
3.污點和容忍度:Taint、toleration
1.節點選擇器:NodeSelector(pod.spec.nodeSelector)
如果我們期望把Pod調度到某一個特定的節點上,可以通過設定Pod.spec.nodeName給定node名稱實現。
我們可以給一部分node打上特有標簽,在pod.spec.nodeSelector中匹配這些標簽。可以極大的縮小預選范圍。
給node添加標簽:
kubectl label nodes NODE_NAME key1=value1...keyN=valueN
如:在node01上打上標簽為app=frontend,而在pod上設置NodeSelector為這個標簽,則此Pod只能運行在存在此標簽的節點上。
若沒有node存在此標簽,則Pod無法被調度,即為Pending狀態。
2.親和性調度:Affinity(pod.spec.affinity)
(1)節點親和性:NodeAffinity(pod.spec.affinity.nodeAffinity)
表示Pod更傾向被調度在與節點親和度高的節點上
pod.spec.affinity.nodeAffinity.下有兩種定義方式:
1 preferredDuringSchedulingIgnoreDuringExecution:軟親和性;不管節點上能否滿足設定條件,Pod都可以被調度,只是Pod優先被調度到符合條件多的節點上。 2 - preference:##與相應權重相關聯的節點選擇器項。 3 matchExpressions:##按節點標簽列出的節點選擇器要求列表 4 - key: ##鍵 5 operator:##表示鍵與一組值的關系。有效的運算符有:In、NotIn、Exist、DoesNotExsit。GT和LT 6 values: ##值;若operator為In或NotIn則值必須為非空;若operator為Exists或DoesNotExist則值必須為空;若operator為Gt或Lt則值必須有一個元素。 7 matchFields:##按節點字段列出的節點選擇器要求列表 8 - key: ##鍵 9 operator:##表示鍵與一組值的關系。有效的運算符有:In、NotIn、Exist、DoesNotExsit。GT和LT 10 values: ##值;若operator為In或NotIn則值必須為非空;若operator為Exists或DoesNotExist則值必須為空;若operator為Gt或Lt則值必須有一個元素。 11 weight: ##權重,0~100的數值
1 requiredDuringSchedulingIgnoreDuringExecution: 硬親和性;節點必須滿足設定條件,Pod才能被調度到這個節點。 2 nodeSelectorTerms: ##節點選擇器列表 3 - matchExpressions:##按節點標簽列出的節點選擇器要求列表 4 - key: ##鍵 5 operator:##表示鍵與一組值的關系。有效的運算符有:In、NotIn、Exist、DoesNotExsit。GT和LT 6 values: ##值;若operator為In或NotIn則值必須為非空;若operator為Exists或DoesNotExist則值必須為空;若operator為Gt或Lt則值必須有一個元素。 7 matchFields:##按節點字段列出的節點選擇器要求列表 8 - key: ##鍵 9 operator:##表示鍵與一組值的關系。有效的運算符有:In、NotIn、Exist、DoesNotExsit。GT和LT 10 values: ##值;若operator為In或NotIn則值必須為非空;若operator為Exists或DoesNotExist則值必須為空;若operator為Gt或Lt則值必須有一個元素。
例:硬親和性,pod只會被調度到存在zone=foo或zone=bar標簽的節點上,若沒有節點存在此標簽,則pod將不會被調度到任何節點上,即為Pending狀態。
自主式pod的資源清單:
1 apiVersion: v1 2 kind: Pod 3 metadata: 4 name: pod-node-affinity 5 namespace: default 6 spec: 7 containers: 8 - name: myapp 9 image: kubernetes/myapp:v1 10 affinity: 11 nodeAffinity: 12 requiredDuringSchedulingIgnoredDuringExecution: 13 nodeSelectorTerms: 14 - matchExpressions: 15 - key: zone 16 operator: In 17 values: 18 - foo 19 - bar
(2)Pod親和性:podAffinity(pod.spec.affinity.podAffinity)
表示一組pod更傾向與運行在一起,一般需要高效通信時需要將pod與pod運行在相近的位置。
第一個pod被調度到某一個節點,第二個pod會跟隨第一個pod運行在同一個位置相近的節點上。
同一個位置的節點不一定是同一個節點,這個節點可能是同一個命名空間、網段、機櫃、機房、甚至同一個區域的某一個節點上。
因為如果說,同一個節點上的資源不足時,pod被調度不到同一個節點,那么就會找與這個節點相近的某個節點上。
節點相近是指節點到節點的網絡路程較近。
當然,若資源空間充足也可以實現讓第二個Pod跟隨第一個pod運行在同一個節點上。
可以根據topologyKey設定的標簽來判定擁有哪些標簽的節點屬於同一位置
與節點親和性一樣,pod.spec.affinity.podAffinity.下也有兩種定義方式:
1 preferredDuringSchedulingIgnoreDuringExecution:軟親和性;不管節點上能否滿足設定條件,Pod都可以被調度,只是Pod優先被調度到符合條件多的節點上。 2 podAffinityTerm: ##定義一組pods(即與相對於此pod應位於(關聯)或不在同一地點(反親和力),在同一地點被定義為運行在一個節點上,其鍵<topologykey>的標簽值與一組pods運行的任何節點 3 labelSelector: ##根據標簽選定一組pod作為親和對象。 4 matchExpressions:##標簽選擇器要求列表 5 - key: ##鍵 6 operator:##表示鍵與一組值的關系。有效的運算符有:In、NotIn、Exist、DoesNotExsit。GT和LT 7 values: ##值;若operator為In或NotIn則值必須為非空;若operator為Exists或DoesNotExist則值必須為空;若operator為Gt或Lt則值必須有一個元素。 8 matchLabels:##標簽選擇器要求列表 9 namespaces: ##指明選定的pod親和對象是哪組名稱空間下的,不指定則為第一個pod所運行的命名空間下。 10 topologyKey: ##位置拓撲鍵,用來判定擁有哪些標簽的節點是同一位置。 11 weight: ##權重,0~100的數值
1 requiredDuringSchedulingIgnoreDuringExecution: 硬親和性;必須滿足設定條件。 2 - labelSelector: ##根據標簽選定一組pod作為親和對象。 3 matchExpressions:##標簽選擇器要求列表 4 - key: ##鍵 5 operator:##表示鍵與一組值的關系。有效的運算符有:In、NotIn、Exist、DoesNotExsit。GT和LT 6 values: ##值;若operator為In或NotIn則值必須為非空;若operator為Exists或DoesNotExist則值必須為空;若operator為Gt或Lt則值必須有一個元素。 7 matchLabels:##標簽選擇器要求列表 8 namespaces: ##指明選定的pod親和對象是哪組名稱空間下的,不指定則為第一個pod所運行的命名空間下。 9 topologyKey: ##位置拓撲鍵,用來判定擁有哪些標簽的節點是同一位置。
(3)Pod反親和性:podAffinity(pod.spec.affinity.podAntiAffinity)
意義與上面相反,區別是topologyKey一定不能是相同的。這里不再敘述
一組pod具有反親和性,則這組pod一定不會被調度到同一位置節點上。
這里的同一位置與上面一樣。
資源清單只需將podAffinity改為podAntiAffinity即可,然后定義topologyKey。
3.污點和容忍度:Taint、toleration(nodes.spec.taints)(pod.spec.tolerations)
污點就是定義在節點上的鍵值屬性數據:三類:1.標簽。2.注解。3.污點。
其中,標簽和注解可以在節點或pod上使用,而污點只能在節點上使用。
污點主要是讓節點拒絕那些不能容忍自己污點的pod的。
而pod上可以定義容忍度,只要是節點上的污點是pod的容忍度的子集,則pod就可以運行在這個節點上。
taints是用在節點上的鍵值數據定義污點的,toleration是用在pod上的鍵值數據定義容忍度的。
污點:taints(nodes.spec.taints)
在節點上定義污點:
1 nodes.spec.taints. 2 - effect: ##當pod不能容忍污點時采取的措施是什么。 3 NoSchedule: ##僅影響調度過程,對現存的pod不產生影響; 4 PreferNoSchedule: ##柔性版的NoSchedule 5 NoExecute: ##不僅影響調度,而且影響現存pod對象,不容忍的pod對象將被驅逐; 6 key: ##鍵 7 timeAdded: 8 value: ##值 9 添加污點命令:kubectl taint node NODE_NAME KEY_1=VAL_1:TAINT_EFFECT_1 ... KEY_N=VAL_N:TAINT_EFFECT_N [options]
10 刪除污點命令:kubectl taint node NODE_NAME KEY_NAME-
容忍度:toleration(pod.spec.tolerations)
在pod中定義容忍度:
1 pod.spec.tolerations. 2 - effect: ##同上 3 key: ##同上 4 value: ##同上 5 operator:##有效的運算符是Exists、Equal。默認為Equal。這樣pod就可以容忍某一特定類別的污點 6 tolerationSeconds:##若不能容忍污點,多長時間后被驅逐。