k8s–基礎(chǔ)–20–污點(diǎn)和容忍度
1、什么是污點(diǎn)和容忍度
1.1、官方解釋
- 節(jié)點(diǎn)親和性,是pod的一種屬性(偏好或硬性要求),它使pod被吸引到一類特定的節(jié)點(diǎn)。
- Taint(污點(diǎn))與節(jié)點(diǎn)親和性相反,它使節(jié)點(diǎn)能夠排斥一類特定的pod。
- Taint(污點(diǎn))和toleration(容忍度)相互配合,可以用來避免pod被分配到不合適的節(jié)點(diǎn)上。
- 每個(gè)節(jié)點(diǎn)上都可以應(yīng)用一個(gè)或多個(gè)taint,這表示對(duì)于那些不能容忍這些taint的pod,是不會(huì)被運(yùn)行在該節(jié)點(diǎn)上。
- 如果將toleration應(yīng)用于pod上,則表示這些pod可以(但不要求)被調(diào)度到具有匹配taint的節(jié)點(diǎn)上。
1.2、自我理解:
- 污點(diǎn)和容忍度是相互匹配的關(guān)系,我們?cè)趎ode上定義一個(gè)污點(diǎn),pod上定義容忍度
- 如果pod能容忍這個(gè)污點(diǎn),就會(huì)被調(diào)度到擁有這個(gè)污點(diǎn)的節(jié)點(diǎn)上
- 如果pod不能容忍這個(gè)污點(diǎn),就不會(huì)被調(diào)度到擁有這個(gè)污點(diǎn)的節(jié)點(diǎn)上
- 如果node節(jié)點(diǎn)上沒有定義污點(diǎn),那么任何pod都會(huì)調(diào)度到這個(gè)節(jié)點(diǎn)上
- 我們可以給node節(jié)點(diǎn)打一個(gè)污點(diǎn),pod如果不能容忍這個(gè)節(jié)點(diǎn)上定義的污點(diǎn),那就調(diào)度不到這個(gè)節(jié)點(diǎn)上
- taints:污點(diǎn)
- 定義在節(jié)點(diǎn)上,是鍵值數(shù)據(jù)
- tolerations:容忍度
- 定義在pod上,可以定義能容忍哪些污點(diǎn)
2、一個(gè)toleration和一個(gè)taint是怎么匹配的
2.1、案例
2.1.1、給node1節(jié)點(diǎn)增加一個(gè)taint
kubectl taint nodes node1 k1=v1:NoSchedule
給節(jié)點(diǎn)node1增加一個(gè)taint,它的key是k1,value是v1,effect是NoSchedule。
這表示只有擁有和這個(gè)taint相匹配的toleration的pod才能夠被分配到node1這個(gè)節(jié)點(diǎn)。
2.1.2、給一個(gè)pod增加tolerations
tolerations:
- key: "k1"
operator: "Equal"
value: "v1"
effect: "NoSchedule"
tolerations:
- key: "k1"
operator: "Exists"
effect: "NoSchedule"
上面兩個(gè)容忍標(biāo)簽都與2.1.1創(chuàng)建的污點(diǎn)"匹配", 因此具有任一容忍標(biāo)簽的Pod都可以將其調(diào)度到node1上
2.2、總結(jié)
一個(gè)toleration和一個(gè)taint相"匹配"是指它們有一樣的key和effect
- 如果 operator 是 Exists,此時(shí)toleration不能指定value
- 如果 operator 是 Equal,此時(shí)它們的value應(yīng)該相等
- 如果一個(gè)toleration的effect為空,則key值與之相同的相匹配taint的effect可以是任意值。
tolerations: - key: "key" operator: "Exists"
2.2.1、effect:用來定義節(jié)點(diǎn)污點(diǎn)對(duì)pod對(duì)象的排斥效果
- NoSchedule:不允許調(diào)度,已經(jīng)調(diào)度的不受影響
- PreferNoSchedule
- 表示k8s將盡量避免將pod調(diào)度到這個(gè)污點(diǎn)的節(jié)點(diǎn)上,但是如果沒有節(jié)點(diǎn)可以被調(diào)度,也是可以調(diào)度到擁有這個(gè)污點(diǎn)的node節(jié)點(diǎn)上的
- NoExecute:
- 當(dāng)pod能夠容忍這個(gè)節(jié)點(diǎn)污點(diǎn),會(huì)被調(diào)度到節(jié)點(diǎn)
- 當(dāng)pod不能容忍節(jié)點(diǎn)污點(diǎn),將會(huì)被驅(qū)逐
2.2.2、注意
- 可以給一個(gè)節(jié)點(diǎn)添加多個(gè)taint
- 可以給一個(gè)pod添加多個(gè)toleration。
3、pod調(diào)度到節(jié)點(diǎn)的過程
3.1、原理
Kubernetes處理多個(gè)taint和toleration的過程就像一個(gè)過濾器,假設(shè)存在一個(gè)pod(A),存在一個(gè)節(jié)點(diǎn)(node1),A調(diào)度到node1的過程如下
- node1節(jié)點(diǎn)上的所有taint和A中的toleration匹配,過濾掉匹配掉的taint
- 過濾后,如果node1上不存在taint
- A可以分配到node1節(jié)點(diǎn)
- 過濾后,如果node1上存在taint,剩余taint的effect值決定了A是否會(huì)被分配到node1
3.1.1、過濾后,剩余taint的effect值決定了A是否會(huì)被分配到node1
- taint中存在一個(gè)以上effect值為NoSchedule的taint,則Kubernetes不會(huì)將A分配到node1節(jié)點(diǎn)上。
- taint中存在一個(gè)以上effect值為NoExecute的taint
- 如果A未在node1上運(yùn)行,則Kubernetes不會(huì)將A分配到node1節(jié)點(diǎn)上
- 如果A在node1上運(yùn)行,將A從該node1上驅(qū)逐
- taint中不存在effect值為NoSchedule的taint,但是存在effect值為PreferNoSchedule的taint,則Kubernetes會(huì)嘗試將A分配到node1s上。
3.2、案例1
給node1節(jié)點(diǎn)添加了如下的taint
kubectltaintnodes node1 k1=v1:NoSchedule
kubectltaintnodes node1 k1=v1:NoExecute
kubectltaintnodes node1 k2=v2:NoSchedule
然后存在一個(gè)pod(A),它有兩個(gè)toleration:
tolerations:
- key: "k1"
operator: "Equal"
value: "v1"
effect: "NoSchedule"
- key: "k1"
operator: "Equal"
value: "v1"
effect: "NoExecute"
在這個(gè)例子中,A不會(huì)被分配到node1節(jié)點(diǎn),因?yàn)槠錄]有toleration和第3個(gè)taint相匹配。
但是如果在給節(jié)點(diǎn)添加上述taint之前,該pod已經(jīng)在上述節(jié)點(diǎn)運(yùn)行,那么它還可以繼續(xù)運(yùn)行在該節(jié)點(diǎn)上,因?yàn)榈谌齻€(gè)taint是三個(gè)taint中唯一不能被這個(gè)pod容忍的。
通常情況下,如果給一個(gè)節(jié)點(diǎn)添加了一個(gè)effect值為 NoExecute 的taint,則任何不能忍受這個(gè)taint的pod都會(huì)馬上被驅(qū)逐,任何可以忍受這個(gè)taint的pod都不會(huì)被驅(qū)逐。
但是,如果pod存在一個(gè)effect值為 NoExecute 的toleration指定了可選屬性 tolerationSeconds 的值,則表示在給節(jié)點(diǎn)添加了上述taint之后,pod 還能繼續(xù)在節(jié)點(diǎn)上運(yùn)行的時(shí)間。例如,
tolerations:
- key: "k1"
operator: "Equal"
value: "v1"
effect: "NoExecute"
tolerationSeconds: 3600
這表示如果這個(gè)pod正在運(yùn)行,然后一個(gè)匹配的taint被添加到其所在的節(jié)點(diǎn),那么pod還將繼續(xù)在節(jié)點(diǎn)上運(yùn)行 3600 秒,然后被驅(qū)逐。如果在此之前上述taint被刪除了,則pod不會(huì)被驅(qū)逐。
4、使用場景
- 可以靈活地讓 pod避開某些節(jié)點(diǎn)
- 可以靈活地讓 pod從某些節(jié)點(diǎn)驅(qū)逐。
4.1、專用節(jié)點(diǎn)
將某些節(jié)點(diǎn)專門分配給特定的一組用戶使用
4.1.1、操作
操作1:給這些節(jié)點(diǎn)添加一個(gè)taint
kubectl taint nodes nodename dedicated=groupName:NoSchedule
操作2:給特定用戶的pod添加一個(gè)相對(duì)應(yīng)的 toleration
通過編寫一個(gè)自定義的 admission controller
4.1.2、總結(jié)
- 擁有上述toleration的pod就能夠被分配到上述專用節(jié)點(diǎn),同時(shí)也能夠被分配到集群中的其它節(jié)點(diǎn)。
- 如果你希望這些pod只能被分配到上述專用節(jié)點(diǎn),那么你還需要給這些專用節(jié)點(diǎn)另外添加一個(gè)和上述taint類似的label(例如:dedicated=groupName),同時(shí) 還要在上述 admission controller 中給pod增加節(jié)點(diǎn)親和性,要求上述pod只能被分配到添加了 dedicated=groupName 標(biāo)簽的節(jié)點(diǎn)上。
4.2、配備了特殊硬件的節(jié)點(diǎn)
在部分節(jié)點(diǎn)配備了特殊硬件(比如 GPU)的集群中,我們希望如下
- 不需要這類硬件的pod 不要 被分配到這些特殊節(jié)點(diǎn)
- 只有需要這類硬件的pod 才 被分配到這些特殊節(jié)點(diǎn)
4.2.1、操作
操作1:給配備了特殊硬件的節(jié)點(diǎn)添加taint
kubectl taint nodes nodename special=true:NoSchedule
# 或者
# kubectl taint nodes nodename special=true:PreferNoSchedule
操作2:給使用了這類特殊硬件的pod添加一個(gè)相匹配的 toleration
和專用節(jié)點(diǎn)的例子類似,添加這個(gè)toleration的最簡單的方法是使用自定義 admission controller。比如
1. 我們推薦使用 Extended Resources 來表示特殊硬件,給配置了特殊硬件的節(jié)點(diǎn)添加taint時(shí)包含 extended resource 名稱
2. 然后運(yùn)行一個(gè) ExtendedResourceToleration admission controller。
4.2.2、總結(jié)
此時(shí),因?yàn)楣?jié)點(diǎn)已經(jīng)被打上taint了,沒有對(duì)應(yīng)toleration的pod會(huì)被調(diào)度到這些節(jié)點(diǎn)。但當(dāng)你創(chuàng)建一個(gè)使用了 extended resource 的pod時(shí),ExtendedResourceToleration admission controller 會(huì)自動(dòng)給pod加上正確的toleration,這樣pod就會(huì)被自動(dòng)調(diào)度到這些配置了特殊硬件件的節(jié)點(diǎn)上。
這樣就能夠確保這些配置了特殊硬件的節(jié)點(diǎn)專門用于運(yùn)行 需要使用這些硬件的 Pod,并且你無需手動(dòng)給這些pod添加 toleration。
4.2、基于taint的驅(qū)逐
當(dāng)節(jié)點(diǎn)出現(xiàn)問題,pod就不會(huì)被驅(qū)逐
5、基于taint的驅(qū)逐
5.1、taint的effect值為NoExecute,它會(huì)影響已經(jīng)在節(jié)點(diǎn)上運(yùn)行的pod
- 如果pod不能忍受effect值為NoExecute的taint,那么pod將馬上被驅(qū)逐
- 如果pod能夠忍受effect值為NoExecute的taint,但是在toleration定義中沒有指定tolerationSeconds,則pod還會(huì)一直在這個(gè)節(jié)點(diǎn)上運(yùn)行。
- 如果pod不能夠忍受effect值為NoExecute的taint,而且指定了tolerationSeconds,則pod還能在這個(gè)節(jié)點(diǎn)上繼續(xù)運(yùn)行這個(gè)指定的時(shí)間長度。
5.2、當(dāng)某種條件為真時(shí),node controller會(huì)自動(dòng)給節(jié)點(diǎn)添加一個(gè)taint
當(dāng)前內(nèi)置的taint如下
5.2.1、node.kubernetes.io/not-ready
- 節(jié)點(diǎn)未準(zhǔn)備好。
- 相當(dāng)于節(jié)點(diǎn)狀態(tài) Ready 的值為 “False”。
5.2.2、node.kubernetes.io/unreachable
- 節(jié)點(diǎn)控制器訪問不到節(jié)點(diǎn)
- 相當(dāng)于節(jié)點(diǎn)狀態(tài) Ready 的值為 “Unknown”。
5.2.3、node.kubernetes.io/out-of-disk
節(jié)點(diǎn)磁盤耗盡。
5.2.4、node.kubernetes.io/memory-pressure
節(jié)點(diǎn)存在內(nèi)存壓力。
5.2.5、node.kubernetes.io/disk-pressure
節(jié)點(diǎn)存在磁盤壓力。
5.2.6、node.kubernetes.io/network-unavailable
節(jié)點(diǎn)網(wǎng)絡(luò)不可用。
5.2.7、node.kubernetes.io/unschedulable
節(jié)點(diǎn)不可調(diào)度。
5.2.8、node.cloudprovider.kubernetes.io/uninitialized
如果kubelet啟動(dòng)時(shí)指定了一個(gè) “外部” cloud provider,它將給當(dāng)前節(jié)點(diǎn)添加一個(gè)taint將其標(biāo)志為不可用。
在cloud-controller-manager的一個(gè)controller初始化這個(gè)節(jié)點(diǎn)后,kubelet將刪除這個(gè)taint。
5.3、自動(dòng)給節(jié)點(diǎn)添加和刪除污點(diǎn)
- 在節(jié)點(diǎn)被驅(qū)逐時(shí),節(jié)點(diǎn)控制器或者kubelet會(huì)添加帶有NoExecute效應(yīng)的相關(guān)污點(diǎn)。
- 在節(jié)點(diǎn)異常狀態(tài)恢復(fù)正常,節(jié)點(diǎn)控制器或者kubelet會(huì)移除相關(guān)的污點(diǎn)。
5.4、怎么避免pod被大量驅(qū)逐
- 為了保證由于節(jié)點(diǎn)問題引起的pod驅(qū)逐rate limiting行為正常,系統(tǒng)實(shí)際上會(huì)以rate-limited 的方式添加taint。 在像 master 和 node 通訊中斷等場景下,這避免了pod被大量驅(qū)逐。
- 使用這個(gè)功能特性,結(jié)合tolerationSeconds,pod就可以指定當(dāng)節(jié)點(diǎn)出現(xiàn)一個(gè)或全部上述問題時(shí)還將在這個(gè)節(jié)點(diǎn)上運(yùn)行多長的時(shí)間。
5.4.1、案例1
一個(gè)pod在網(wǎng)絡(luò)斷開時(shí),仍然希望停留在當(dāng)前節(jié)點(diǎn)上運(yùn)行一段較長的時(shí)間,愿意等待網(wǎng)絡(luò)恢復(fù)以避免被驅(qū)逐。在這種情況下,pod的toleration可能是下面這樣的:
tolerations:
-key: "node.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 6000
5.5、DefaultTolerationSeconds admission controller
給pod自動(dòng)添加如下tolerations
tolerations:
-key: "node.kubernetes.io/not-ready"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300
tolerations:
-key: "node.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 300
- 這種自動(dòng)添加toleration機(jī)制保證了在其中一種問題被檢測到時(shí)pod默認(rèn)能夠繼續(xù)停留在當(dāng)前節(jié)點(diǎn)運(yùn)行5分鐘。
- 這兩個(gè)默認(rèn)toleration是由 DefaultTolerationSeconds admission controller添加的。
- DaemonSet中的pod被創(chuàng)建時(shí),針對(duì)以下taint自動(dòng)添加的NoExecute的toleration將不會(huì)指定tolerationSeconds,這保證了出現(xiàn)上述問題時(shí)DaemonSet中的pod永遠(yuǎn)不會(huì)被驅(qū)逐。
node.kubernetes.io/unreachable
node.kubernetes.io/not-ready
6、基于節(jié)點(diǎn)狀態(tài)添加taint
-
Node生命周期控制器會(huì)自動(dòng)創(chuàng)建與Node條件相對(duì)應(yīng)的帶有NoSchedule效應(yīng)的污點(diǎn)。同樣,調(diào)度器不檢查節(jié)點(diǎn)條件,而是檢查節(jié)點(diǎn)污點(diǎn)。
這確保了節(jié)點(diǎn)條件不會(huì)影響調(diào)度到節(jié)點(diǎn)上的內(nèi)容。用戶可以通過添加適當(dāng)?shù)膒od容忍度來選擇忽略某些Node的問題(表示為Node的調(diào)度條件)。 -
自Kubernetes1.8起,DaemonSet控制器自動(dòng)為所有守護(hù)進(jìn)程添加如下NoSchedule toleration以防DaemonSet崩潰
node.kubernetes.io/memory-pressure
node.kubernetes.io/disk-pressure
node.kubernetes.io/out-of-disk (只適合 criticalpod)
node.kubernetes.io/unschedulable (1.10 或更高版本)
node.kubernetes.io/network-unavailable (只適合 host network)添加上述toleration確保了向后兼容,你也可以選擇自由的向DaemonSet添加toleration。
7、pod容忍度,node污點(diǎn) 操作命令
7.1、給節(jié)點(diǎn)添加污點(diǎn)
kubectltaintnodes node1 k1=v1:NoSchedule
在node1上添加了污點(diǎn). 這個(gè)污點(diǎn)的key是k1,value是v1, 污點(diǎn)的effect是NoSchedule
如果pod沒有定義容忍度的話就不會(huì)調(diào)度到擁有這個(gè)污點(diǎn)的節(jié)點(diǎn)上
7.2、給節(jié)點(diǎn)移除污點(diǎn)
kubectl taint nodes node1 k1=v1:NoSchedule-
7.3、給Pod設(shè)置容忍
spec:
tolerations: #設(shè)置容忍性
- key: "test"
operator: "Equal" # 如果操作符為Exists,那么value屬性可省略,如果不指定operator,則默認(rèn)為Equal
value: "16"
effect: "NoSchedule"
- 意思是這個(gè)Pod要容忍的有污點(diǎn)的Node的key是test,value是16,effect是NoSchedule,
- 注意:
- tolerations屬性下各值必須使用引號(hào)
- 容忍的值都是設(shè)置Node的taints時(shí)給的值。
7.4、修改effect為NoExecute
一般不要玩
kubectltaintnodes node1 k1=v1:NoExecute
7.5、tolerations屬性補(bǔ)充
其中的key、value、effect與Node的Taint設(shè)置需保持一致,還有以下幾點(diǎn)說明
- 如果operator的值是Exists,則value屬性可省略。
- 如果operator的值是Equal,則表示其key與value之間的關(guān)系是equal(等于)。
- 如果不指定operator屬性,則默認(rèn)值為Equal。
- 還有兩個(gè)特殊值:
- 空的key 如果再配合Exists,就能匹配所有的key與value,也就是能容忍所有node上的所有Taints。
- 空的effect,匹配所有的effect
8、驗(yàn)證
驗(yàn)證effect是NoSchedule情況
8.1、node1添加污點(diǎn)
kubectl taint nodes node1 k1=v1:NoSchedule
8.2、一個(gè)沒有容忍度的pod
8.2.1、定義
vi /root/test2/tolerations-no.yaml
內(nèi)容
apiVersion: v1
kind: Pod
metadata:
name: tolerations-no
spec:
containers:
- name: nginx
image: nginx
8.2.2、執(zhí)行
kubectl apply -f /root/test2/tolerations-no.yaml
kubectl get pods
kubectl describe pods tolerations-no
顯示pod不能容忍節(jié)點(diǎn)污點(diǎn),不能完成調(diào)度
8.3、一個(gè)有容忍度的pod
8.3.1、定義
vi /root/test2/tolerations-yes.yaml
內(nèi)容
apiVersion: v1
kind: Pod
metadata:
name: tolerations-yes
spec:
containers:
- name: nginx
image: nginx
tolerations:
- key: k1
value: v1
effect: NoSchedule
8.3.2、執(zhí)行
kubectl apply -f /root/test2/tolerations-yes.yaml
kubectl get pods -o wide
文章來源:http://www.zghlxwxcb.cn/news/detail-469679.html
可以看到tolerations-yes已經(jīng)完成調(diào)度了,可以調(diào)度到node1節(jié)點(diǎn)上文章來源地址http://www.zghlxwxcb.cn/news/detail-469679.html
到了這里,關(guān)于k8s--基礎(chǔ)--20--污點(diǎn)和容忍度的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!