Pod資源調度
API Server在接受客戶端提交Pod對象創建請求后,然后是通過調度器(kube-schedule)從集群中選擇一個可用的最佳節點來創建並運行Pod。而這一個創建Pod對象,在調度的過程當中有3個階段:節點預選、節點優選、節點選定,從而篩選出最佳的節點。如圖:
- 節點預選:基於一系列的預選規則對每個節點進行檢查,將那些不符合條件的節點過濾,從而完成節點的預選
- 節點優選:對預選出的節點進行優先級排序,以便選出最合適運行Pod對象的節點
- 節點選定:從優先級排序結果中挑選出優先級最高的節點運行Pod,當這類節點多於1個時,則進行隨機選擇
當我們有需求要將某些Pod資源運行在特定的節點上時,我們可以通過組合節點標簽,以及Pod標簽或標簽選擇器來匹配特定的預選策略並完成調度,如MatchInterPodAfinity、MatchNodeSelector、PodToleratesNodeTaints
等預選策略,這些策略常用於為用戶提供自定義Pod親和性或反親和性、節點親和性以及基於污點及容忍度的調度機制。
1、常用的預選策略
預選策略實際上就是節點過濾器,例如節點標簽必須能夠匹配到Pod資源的標簽選擇器(MatchNodeSelector實現的規則),以及Pod容器的資源請求量不能大於節點上剩余的可分配資源(PodFitsResource規則)等等。執行預選操作,調度器會逐一根據規則進行篩選,如果預選沒能選定一個合適的節點,此時Pod會一直處於Pending狀態,直到有一個可用節點完成調度。其常用的預選策略如下:
- CheckNodeCondition:檢查是否可以在節點報告磁盤、網絡不可用或未准備好的情況下將Pod對象調度其上。
- HostName:如果Pod對象擁有spec.hostname屬性,則檢查節點名稱字符串是否和該屬性值匹配。
- PodFitsHostPorts:如果Pod對象定義了ports.hostPort屬性,則檢查Pod指定的端口是否已經被節點上的其他容器或服務占用。
- MatchNodeSelector:如果Pod對象定義了spec.nodeSelector屬性,則檢查節點標簽是否和該屬性匹配。
- NoDiskConflict:檢查Pod對象請求的存儲卷在該節點上可用。
- PodFitsResources:檢查節點上的資源(CPU、內存)可用性是否滿足Pod對象的運行需求。
- PodToleratesNodeTaints:如果Pod對象中定義了spec.tolerations屬性,則需要檢查該屬性值是否可以接納節點定義的污點(taints)。
- PodToleratesNodeNoExecuteTaints:如果Pod對象定義了spec.tolerations屬性,檢查該屬性是否接納節點的NoExecute類型的污點。
- CheckNodeLabelPresence:僅檢查節點上指定的所有標簽的存在性,要檢查的標簽以及其可否存在取決於用戶的定義。
- CheckServiceAffinity:根據當前Pod對象所屬的Service已有其他Pod對象所運行的節點調度,目前是將相同的Service的Pod對象放在同一個或同一類節點上。
- MaxEBSVolumeCount:檢查節點上是否已掛載EBS存儲卷數量是否超過了設置的最大值,默認值:39
- MaxGCEPDVolumeCount:檢查節點上已掛載的GCE PD存儲卷是否超過了設置的最大值,默認值:16
- MaxAzureDiskVolumeCount:檢查節點上已掛載的Azure Disk存儲卷數量是否超過了設置的最大值,默認值:16
- CheckVolumeBinding:檢查節點上已綁定和未綁定的PVC是否滿足Pod對象的存儲卷需求。
- NoVolumeZoneConflct:在給定了區域限制的前提下,檢查在該節點上部署Pod對象是否存在存儲卷沖突。
- CheckNodeMemoryPressure:在給定了節點已經上報了存在內存資源壓力過大的狀態,則需要檢查該Pod是否可以調度到該節點上。
- CheckNodePIDPressure:如果給定的節點已經報告了存在PID資源壓力過大的狀態,則需要檢查該Pod是否可以調度到該節點上。
- CheckNodeDiskPressure:如果給定的節點存在磁盤資源壓力過大,則檢查該Pod對象是否可以調度到該節點上。
- MatchInterPodAffinity:檢查給定的節點能否可以滿足Pod對象的親和性和反親和性條件,用來實現Pod親和性調度或反親和性調度。
在上面的這些預選策略里面,CheckNodeLabelPressure和CheckServiceAffinity可以在預選過程中結合用戶自定義調度邏輯,這些策略叫做可配置策略。其他不接受參數進行自定義配置的稱為靜態策略。
2、優選函數
預選策略篩選出一個節點列表就會進入優選階段,在這個過程調度器會向每個通過預選的節點傳遞一系列的優選函數來計算其優先級分值,優先級分值介於0-10之間,其中0表示不適用,10表示最適合托管該Pod對象。
另外,調度器還支持給每個優選函數指定一個簡單的值,表示權重,進行節點優先級分值計算時,它首先將每個優選函數的計算得分乘以權重,然后再將所有優選函數的得分相加,從而得出節點的最終優先級分值。權重可以讓管理員定義優選函數傾向性的能力,其計算優先級的得分公式如下:
finalScoreNode = (weight1 * priorityFunc1) + (weight2 * priorityFunc2) + ......
下圖是關於優選函數的列表圖:
3、節點親和調度
節點親和性是用來確定Pod對象調度到哪一個節點的規則,這些規則基於節點上的自定義標簽和Pod對象上指定的標簽選擇器進行定義。
定義節點親和性規則有2種:硬親和性(require)和軟親和性(preferred)
- 硬親和性:實現的是強制性規則,是Pod調度時必須滿足的規則,否則Pod對象的狀態會一直是Pending
- 軟親和性:實現的是一種柔性調度限制,在Pod調度時可以盡量滿足其規則,在無法滿足規則時,可以調度到一個不匹配規則的節點之上。
定義節點親和規則的兩個要點:一是節點配置是否合乎需求的標簽,而是Pod對象定義合理的標簽選擇器,這樣才能夠基於標簽選擇出期望的目標節點。
需要注意的是preferredDuringSchedulingIgnoredDuringExecution
和requiredDuringSchedulingIgnoredDuringExecution
名字中后半段字符串IgnoredDuringExecution
表示的是,在Pod資源基於節點親和性規則調度到某個節點之后,如果節點的標簽發生了改變,調度器不會講Pod對象從該節點上移除,因為該規則僅對新建的Pod對象有效。
3.1、節點硬親和性
下面的配置清單中定義的Pod對象,使用節點硬親和性和規則定義將當前Pod調度到標簽為zone=foo的節點上:
apiVersion: v1
kind: Pod
metadata:
name: with-require-nodeaffinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- {key: zone,operator: In,values: ["foo"]}
containers:
- name: myapp
image: ikubernetes/myapp:v1
#創建Pod對象
[root@k8s-master ~]# kubectl apply -f require-nodeAffinity-pod.yaml
pod/with-require-nodeaffinity created
#由於集群中並沒有節點含有節點標簽為zone=foo,所以創建的Pod一直處於Pending狀態
[root@k8s-master ~]# kubectl get pods with-require-nodeaffinity
NAME READY STATUS RESTARTS AGE
with-require-nodeaffinity 0/1 Pending 0 35s
#查看Pending具體的原因
[root@k8s-master ~]# kubectl describe pods with-require-nodeaffinity
......
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 3s (x21 over 1m) default-scheduler 0/3 nodes are available: 3 node(s) didn't match node selector.
#給node01節點打上zone=foo的標簽,可以看到成功調度到node01節點上
[root@k8s-master ~]# kubectl label node k8s-node01 zone=foo
node/k8s-node01 labeled
[root@k8s-master ~]# kubectl describe pods with-require-nodeaffinity
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 58s (x25 over 2m) default-scheduler 0/3 nodes are available: 3 node(s) didn't match node selector.
Normal Pulled 4s kubelet, k8s-node01 Container image "ikubernetes/myapp:v1" already present on machine
Normal Created 4s kubelet, k8s-node01 Created container
Normal Started 4s kubelet, k8s-node01 Started container
[root@k8s-master ~]# kubectl get pods with-require-nodeaffinity -o wide
NAME READY STATUS RESTARTS AGE IP NODE
with-require-nodeaffinity 1/1 Running 0 6m 10.244.1.12 k8s-node01
在定義節點親和性時,requiredDuringSchedulingIgnoredDuringExecution
字段的值是一個對象列表,用於定義節點硬親和性,它可以由一個或多個nodeSelectorTerms
定義的對象組成,此時值需要滿足其中一個nodeSelectorTerms
即可。
而nodeSelectorTerms
用來定義節點選擇器的條目,它的值也是一個對象列表,由1個或多個matchExpressions
對象定義的匹配規則組成,多個規則是邏輯與的關系,這就表示某個節點的標簽必須要滿足同一個nodeSelectorTerms
下所有的matchExpression
對象定義的規則才能夠成功調度。如下:
#如下配置清單,必須存在滿足標簽zone=foo和ssd=true的節點才能夠調度成功
apiVersion: v1
kind: Pod
metadata:
name: with-require-nodeaffinity
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- {key: zone, operator: In, values: ["foo"]}
- {key: ssd, operator: Exists, values: []} #增加一個規則
containers:
- name: myapp
image: ikubernetes/myapp:v1
[root@k8s-master ~]# kubectl apply -f require-nodeAffinity-pod.yaml
pod/with-require-nodeaffinity created
[root@k8s-master ~]# kubectl get pods with-require-nodeaffinity
NAME READY STATUS RESTARTS AGE
with-require-nodeaffinity 0/1 Pending 0 16s
[root@k8s-master ~]# kubectl label node k8s-node01 ssd=true
node/k8s-node01 labeled
[root@k8s-master ~]# kubectl get pods with-require-nodeaffinity
NAME READY STATUS RESTARTS AGE
with-require-nodeaffinity 1/1 Running 0 2m
在預選策略中,還可以通過節點資源的可用性去限制能夠成功調度,如下配置清單:要求的資源為6核心CPU和20G內存,節點是無法滿足該容器的資源需求,因此也會調度失敗,Pod資源會處於Pending狀態。
apiVersion: v1
kind: Pod
metadata:
name: with-require-nodeaffinity
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
resources:
requests:
cpu: 6
memory: 20Gi
3.2、節點軟親和性
看下面一個配置清單:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy-with-node-affinity
spec:
replicas: 5
selector:
matchLabels:
app: myapp
template:
metadata:
name: myapp-pod
labels:
app: myapp
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 60
preference:
matchExpressions:
- {key: zone, operator: In, values: ["foo"]}
- weight: 30
preference:
matchExpressions:
- {key: ssd, operator: Exists, values: []}
containers:
- name: myapp
image: ikubernetes/myapp:v1
#首先先給node02和master都打上標簽,master標簽為zone=foo,node02標簽為ssd=true,這里node01是沒有對應標簽的
[root@k8s-master ~]# kubectl label node k8s-node02 ssd=true
node/k8s-node02 labeled
[root@k8s-master ~]# kubectl label node k8s-master zone=foo
node/k8s-master labeled
#進行創建
[root@k8s-master ~]# kubectl apply -f deploy-with-preferred-nodeAffinity.yaml
deployment.apps/myapp-deploy-with-node-affinity2 created
#可以看到5個Pod分別分布在不同的節點上,node01上沒有對應的標簽也會調度上進行創建Pod,體現軟親和性
[root@k8s-master ~]# kubectl get pods -o wide |grep deploy-with
myapp-deploy-with-node-affinity2-75b8f65f87-2gqjv 1/1 Running 0 11s 10.244.2.4 k8s-node02
myapp-deploy-with-node-affinity2-75b8f65f87-7l2sg 1/1 Running 0 11s 10.244.0.4 k8s-master
myapp-deploy-with-node-affinity2-75b8f65f87-cdrxx 1/1 Running 0 11s 10.244.2.3 k8s-node02
myapp-deploy-with-node-affinity2-75b8f65f87-j77f6 1/1 Running 0 11s 10.244.1.36 k8s-node01
myapp-deploy-with-node-affinity2-75b8f65f87-wt6tq 1/1 Running 0 11s 10.244.0.3 k8s-master
#如果我們給node01打上zone=foo,ssd=true的標簽,再去創建時,你會發現所有的Pod都調度在這個節點上。因為節點的軟親和性,會盡力滿足Pod中定義的規則,如下:
[root@k8s-master ~]# kubectl label node k8s-node01 zone=foo
[root@k8s-master ~]# kubectl label node k8s-node01 ssd=true
[root@k8s-master ~]# kubectl get pods -o wide |grep deploy-with
myapp-deploy-with-node-affinity2-75b8f65f87-4lwsw 0/1 ContainerCreating 0 3s <none> k8s-node01
myapp-deploy-with-node-affinity2-75b8f65f87-dxbxf 1/1 Running 0 3s 10.244.1.31 k8s-node01
myapp-deploy-with-node-affinity2-75b8f65f87-lnhgm 0/1 ContainerCreating 0 3s <none> k8s-node01
myapp-deploy-with-node-affinity2-75b8f65f87-snxbc 0/1 ContainerCreating 0 3s <none> k8s-node01
myapp-deploy-with-node-affinity2-75b8f65f87-zx8ck 1/1 Running 0 3s 10.244.1.33 k8s-node01
上面的實驗結果顯示,當2個標簽沒有都存在一個node節點上時,Pod對象會被分散在集群中的三個節點上進行創建並運行,之所以如此,是因為使用了 節點軟親和性的預選方式,所有的節點都能夠通過MatchNodeSelector
預選策略的篩選。當我們將2個標簽都集合在node01上時,所有Pod對象都會運行在node01之上。
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對象:
[root@k8s-master ~]# kubectl run tomcat -l app=tomcat --image=tomcat:alpine
deployment.apps/tomcat created
[root@k8s-master ~]# kubectl get pods -l app=tomcat -o wide
NAME READY STATUS RESTARTS AGE IP NODE
tomcat-75fd5cc757-w9qdb 1/1 Running 0 5m 10.244.1.37 k8s-node01
從上面我們可以看到新創建的tomcat
pod對象被調度在k8s-node01上,再寫一個配置清單定義一個Pod對象,通過labelSelector
定義的標簽選擇器挑選對應的Pod對象。
[root@k8s-master ~]# vim required-podAffinity-pod1.yaml
apiVersion: v1
kind: Pod
metadata:
name: with-pod-affinity-1
spec:
affinity:
podAffninity:
requiredDuringSchedulingIngnoreDuringExecution:
- labelSelector:
matchExpression:
- {key: app , operator: In , values: ["tomcat"]}
topologyKey: kubernetes.io/hostname
containers:
- name: myapp
image: ikubernetes/myapp:v1
kubernetes.io/hostname
標簽是Kubernetes集群節點的內建標簽,它的值為當前節點的主機名,對於各個節點來說都是不同的。所以新建的Pod對象要被部署到和tomcat
所在的同一個節點上。
[root@k8s-master ~]# kubectl apply -f required-podAffinity-pod1.yaml
pod/with-pod-affinity-1 created
[root@k8s-master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
with-pod-affinity-1 1/1 Running 0 31s 10.244.1.38 k8s-node01
tomcat-75fd5cc757-w9qdb 1/1 Running 0 5m 10.244.1.37 k8s-node01
基於單一節點的Pod親和性相對來說使用的情況會比較少,通常使用的是基於同一地區、區域、機架等拓撲位置約束。比如部署應用程序(myapp)和數據庫(db)服務相關的Pod時,這兩種Pod應該部署在同一區域上,可以加速通信的速度。
4.2、Pod軟親和度
同理,有硬親和度即有軟親和度,Pod也支持使用preferredDuringSchedulingIgnoredDuringExecuttion
屬性進行定義Pod的軟親和性,調度器會盡力滿足親和約束的調度,在滿足不了約束條件時,也允許將該Pod調度到其他節點上運行。比如下面這一配置清單:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-with-preferred-pod-affinity
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
name: myapp
labels:
app: myapp
spec:
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 80
podAffinityTerm:
labelSelector:
matchExpressions:
- {key: app, operator: In , values: ["cache"]}
topologyKey: zone
- weight: 20
podAffinityTerm:
labelSelector:
matchExpressions:
- {key: app, operator: In, values: ["db"]}
topologyKey: zone
containers:
- name: myapp
image: ikubernetes/mapp:v1
上述的清單配置當中,pod的軟親和調度需要將Pod調度到標簽為app=cache
並在區域zone當中,或者調度到app=db
標簽節點上的,但是我們的節點上並沒有類似的標簽,所以調度器會根據軟親和調度進行隨機調度到k8s-node01
節點之上。如下:
[root@k8s-master ~]# kubectl apply -f deploy-with-preferred-podAffinity.yaml
deployment.apps/myapp-with-preferred-pod-affinity created
[root@k8s-master ~]# kubectl get pods -o wide |grep myapp-with-preferred-pod-affinity
myapp-with-preferred-pod-affinity-5c44649f58-cwgcd 1/1 Running 0 1m 10.244.1.40 k8s-node01
myapp-with-preferred-pod-affinity-5c44649f58-hdk8q 1/1 Running 0 1m 10.244.1.42 k8s-node01
myapp-with-preferred-pod-affinity-5c44649f58-kg7cx 1/1 Running 0 1m 10.244.1.41 k8s-node01
4.3、Pod反親和度
podAffinity
定義了Pod對象的親和約束,而Pod對象的反親和調度則是用podAntiAffinty
屬性進行定義,下面的配置清單中定義了由同一Deployment創建但是彼此基於節點位置互斥的Pod對象:
[root@k8s-master ~]# cat deploy-with-required-podAntiAffinity.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-with-pod-anti-affinity
spec:
replicas: 4
selector:
matchLabels:
app: myapp
template:
metadata:
name: myapp
labels:
app: myapp
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- {key: app,operator: In,values: ["myapp"]}
topologyKey: kubernetes.io/hostname
containers:
- name: myapp
image: ikubernetes/myapp:v1
[root@k8s-master ~]# kubectl apply -f deploy-with-required-podAntiAffinity.yaml
deployment.apps/myapp-with-pod-anti-affinity created
[root@k8s-master ~]# kubectl get pods -l app=myapp
NAME READY STATUS RESTARTS AGE
myapp-with-pod-anti-affinity-79c7b6c596-77hrz 1/1 Running 0 8s
myapp-with-pod-anti-affinity-79c7b6c596-fhxmv 0/1 Pending 0 8s
myapp-with-pod-anti-affinity-79c7b6c596-l9ckr 1/1 Running 0 8s
myapp-with-pod-anti-affinity-79c7b6c596-vfv2s 1/1 Running 0 8s
由於在配置清單中定義了強制性反親和性,所以創建的4個Pod副本必須 運行在不同的節點當中呢,但是集群中只存在3個節點,因此,肯定會有一個Pod對象處於Pending的狀態。
5、污點和容忍度
污點(taints)是定義在節點上的一組鍵值型屬性數據,用來讓節點拒絕將Pod調度到該節點上,除非該Pod對象具有容納節點污點的容忍度。而容忍度(tolerations)是定義在Pod對象上的鍵值型數據,用來配置讓Pod對象可以容忍節點的污點。
前面的節點選擇器和節點親和性的調度方式都是通過在Pod對象上添加標簽選擇器來完成對特定類型節點標簽的匹配,實現的是Pod選擇節點的方式。而污點和容忍度則是通過對節點添加污點信息來控制Pod對象的調度結果,讓節點擁有了控制哪種Pod對象可以調度到該節點上的 一種方式。
Kubernetes使用PodToleratesNodeTaints預選策略和TaintTolerationPriority優選函數來完成這種調度方式。
5.1、定義污點和容忍度
污點的定義是在節點的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對象調度到該節點上,如下:
[root@k8s-master ~]# kubectl describe node k8s-master
Name: k8s-master
Roles: master
......
Taints: node- role. kubernetes. io/ master: NoSchedule
......
而一些系統級別的應用在創建時,就會添加相應的容忍度來確保被創建時可以調度到master節點上,如flannel插件:
[root@k8s-master ~]# kubectl describe pods kube-flannel-ds-amd64-2p8wm -n kube-system
......
Tolerations: node-role.kubernetes.io/master:NoSchedule
node.kubernetes.io/disk-pressure:NoSchedule
node.kubernetes.io/memory-pressure:NoSchedule
node.kubernetes.io/not-ready:NoExecute
node.kubernetes.io/unreachable:NoExecute
......
5.2、管理節點的污點
使用命令行向節點添加污點
語法:kubectl taint nodes <nodename> <key>=<value>:<effect>......
#定義k8s-node01上的污點
[root@k8s-master ~]# kubectl taint nodes k8s-node01 node-type=production:NoSchedule
node/k8s-node01 tainted
#查看節點污點信息
[root@k8s-master ~]# kubectl get nodes k8s-node01 -o go-template={{.spec.taints}}
[map[effect:NoSchedule key:node-type value:production]]
此時,node01節點上已經存在的Pod對象不受影響,僅對新建Pod對象有影響,需要注意的是,如果是同一個鍵值數據,但是最后的標識不同,也是屬於不同的污點信息,比如再給node01上添加一個污點的標識為:PreferNoSchedule
[root@k8s-master ~]# kubectl taint nodes k8s-node01 node-type=production:PreferNoSchedule
node/k8s-node01 tainted
[root@k8s-master ~]# kubectl get nodes k8s-node01 -o go-template={{.spec.taints}}
[map[value:production effect:PreferNoSchedule key:node-type] map[key:node-type value:production effect:NoSchedule]]
刪除污點
語法:kubectl taint nodes <node-name> <key>[: <effect>]-
#刪除node01上的node-type標識為NoSchedule的污點
[root@k8s-master ~]# kubectl taint nodes k8s-node01 node-type:NoSchedule-
node/k8s-node01 untainted
#刪除指定鍵名的所有污點
[root@k8s-master ~]# kubectl taint nodes k8s-node01 node-type-
node/k8s-node01 untainted
#補丁方式刪除節點上的全部污點信息
[root@k8s-master ~]# kubectl patch nodes k8s-node01 -p '{"spec":{"taints":[]}}'
5.3、Pod對象的容忍度
Pod對象的容忍度可以通過spec.tolerations
字段進行添加,同一的也有兩種操作符:Equal
和Exists
方式。Equal等值方式如下:
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "Noexecute"
tolerationSeconds: 3600
Exists方式如下:
tolerations:
- key: "key1"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 3600