K8s調(diào)度之污點(diǎn)與容忍

前言

前面介紹了節(jié)點(diǎn)親和性調(diào)度,它可以使得我們的Pod調(diào)度到指定的Node節(jié)點(diǎn)上轨蛤,而污點(diǎn)(Taints)與之相反蜜宪,它可以讓Node拒絕Pod的運(yùn)行,甚至驅(qū)逐已經(jīng)在該Node上運(yùn)行的Pod

污點(diǎn)是Node上設(shè)置的一個(gè)屬性祥山,通常設(shè)置污點(diǎn)表示該節(jié)點(diǎn)有問題圃验,比如磁盤要滿了,資源不足缝呕,或者該Node正在升級(jí)暫時(shí)不能提供使用等情況澳窑,這時(shí)不希望再有新的Pod進(jìn)來,這個(gè)時(shí)候就可以給該節(jié)點(diǎn)設(shè)置一個(gè)污點(diǎn)供常。

但是有的時(shí)候其實(shí)Node節(jié)點(diǎn)并沒有故障摊聋,只是不想讓一些Pod調(diào)度進(jìn)來,比如這臺(tái)節(jié)點(diǎn)磁盤空間比較大栈暇,希望是像Elasticsearch麻裁、Minio這樣需要較大磁盤空間的Pod才調(diào)度進(jìn)來,那么就可以給節(jié)點(diǎn)設(shè)置一個(gè)污點(diǎn)源祈,給Pod設(shè)置容忍(Tolerations)對(duì)應(yīng)污點(diǎn)煎源,如果再配合節(jié)點(diǎn)親和性功能還可以達(dá)到獨(dú)占節(jié)點(diǎn)的效果

一般時(shí)候 Taints 總是與 Tolerations配合使用

污點(diǎn)(Taints)

我們已經(jīng)知道了設(shè)置污點(diǎn)后,一般Pod將不會(huì)調(diào)度到該節(jié)點(diǎn)上來香缺,大家看過我先前的文章會(huì)發(fā)現(xiàn)手销,我的K8s集群有三個(gè)節(jié)點(diǎn),分別是master图张、node01锋拖、node02,但是每次Pod都不會(huì)調(diào)度到master節(jié)點(diǎn)祸轮,那是因?yàn)榇罱↘8s集群的時(shí)候姑隅,K8s給master自帶了一個(gè)污點(diǎn)。

查看污點(diǎn)

查看master上是否有污點(diǎn)倔撞,通過describe命令可以看到節(jié)點(diǎn)上的所有污點(diǎn)

[root@master ~]# kubectl describe node master
...
Taints:             node-role.kubernetes.io/master:NoSchedule
...

還可以通過如下命令查看

[root@master ~]# kubectl get nodes master -o go-template={{.spec.taints}}
[map[effect:NoSchedule key:node-role.kubernetes.io/master]]

發(fā)現(xiàn)master上自帶了一個(gè)沒有value的污點(diǎn) node-role.kubernetes.io/master 讲仰,effect 為 NoSchedule,由于我們的Pod都沒有容忍這個(gè)污點(diǎn)痪蝇,所以一直都不會(huì)調(diào)度到master

污點(diǎn)類別

上面我們看到了污點(diǎn)有一個(gè)effect 屬性為NoSchedule鄙陡,其實(shí)還有其它兩種類別分別是 PreferNoSchedule與 NoExecute

  • NoSchedule: 如果沒有容忍該污點(diǎn)就不能調(diào)度進(jìn)來。
  • PreferNoSchedule: 相當(dāng)于NoExecute的一個(gè)軟限制躏啰,如果沒有容忍該污點(diǎn)趁矾,盡量不要把Pod調(diào)度進(jìn)來,但也不是強(qiáng)制的给僵。
  • NoExecute: 如果沒有設(shè)置容忍該污點(diǎn)毫捣,新的Pod肯定不會(huì)調(diào)度進(jìn)來, 并且已經(jīng)在運(yùn)行的Pod沒有容忍該污點(diǎn)也會(huì)被驅(qū)逐
設(shè)置污點(diǎn)

污點(diǎn)分別由key详拙、value(可以為空)、effect 組成蔓同,設(shè)置命令如下

# 設(shè)置污點(diǎn)并不允許Pod調(diào)度到該節(jié)點(diǎn)
$ kubectl taint node node01 key=value:NoSchedule
# 設(shè)置污點(diǎn)盡量不要讓Pod調(diào)度到該節(jié)點(diǎn)
$ kubectl taint node node01 key=value:PreferNoSchedule
# 設(shè)置污點(diǎn)饶辙,不允許Pod調(diào)度到該節(jié)點(diǎn),并且且將該節(jié)點(diǎn)上沒有容忍該污點(diǎn)的Pod將進(jìn)行驅(qū)逐
$ kubectl taint node node01 key=value:NoExecute
刪除污點(diǎn)
# 刪除該key的所有污點(diǎn)
$ kubectl taint node node01 key-
# 刪除該key的某一個(gè)污點(diǎn)
$ kubectl taint node node01 key=value:NoSchedule-
# 刪除該key的某一個(gè)污點(diǎn)可以不寫value
$ kubectl taint node node01 key:NoSchedule-
污點(diǎn)測(cè)試

給node01節(jié)點(diǎn)設(shè)置一個(gè)污點(diǎn)斑粱,表示只有前臺(tái)web應(yīng)用才能調(diào)度弃揽,后端app應(yīng)用不能調(diào)度

[root@master ~]# kubectl taint node node01 web=true:NoSchedule
node/node01 tainted

編寫 web-taint.yaml 內(nèi)容如下,有三個(gè)Pod均沒有容忍該污點(diǎn)

apiVersion: v1
kind: Pod
metadata:
  name: web-taint1
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent # 本地有不拉取鏡像
---
apiVersion: v1
kind: Pod
metadata:
  name: web-taint2
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent # 本地有不拉取鏡像
---
apiVersion: v1
kind: Pod
metadata:
  name: web-taint3
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent # 本地有不拉取鏡像

啟動(dòng)Pod则北,觀察Pod是否都被調(diào)度到node02節(jié)點(diǎn)

# 啟動(dòng)三個(gè)Pod
[root@master taint]# kubectl create -f web-taint.yaml 
pod/web-taint1 created
pod/web-taint2 created
pod/web-taint3 created

# 查看pod詳情發(fā)現(xiàn)均被調(diào)度到node02節(jié)點(diǎn)
[root@master taint]# kubectl get pod -o wide
NAME         READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
web-taint1   1/1     Running   0          13s   10.244.2.35   node02   <none>           <none>
web-taint2   1/1     Running   0          13s   10.244.2.34   node02   <none>           <none>
web-taint3   1/1     Running   0          13s   10.244.2.36   node02   <none>           <none>

給node02節(jié)點(diǎn)天津污點(diǎn) app=true:NoExecute矿微,表示只有后端服務(wù)才能調(diào)度進(jìn)來,并且已經(jīng)在node02節(jié)點(diǎn)上運(yùn)行的不是后端服務(wù)的節(jié)點(diǎn)將被驅(qū)逐

# 設(shè)置污點(diǎn)
[root@master taint]# kubectl taint node node02 app=true:NoExecute
node/node02 tainted
# 查看Pod詳情尚揣,發(fā)現(xiàn)三個(gè)Pod已經(jīng)被驅(qū)逐
[root@master taint]# kubectl get pod -o wide
No resources found in default namespace.

從上面可以知道我們雖然設(shè)置了污點(diǎn)涌矢,但是我們的節(jié)點(diǎn)其實(shí)很正常,既然是正常節(jié)點(diǎn)快骗,那么就可以有服務(wù)運(yùn)行蒿辙,這就需要用到容忍機(jī)制來運(yùn)行這些Pod

容忍(Toletations)

如果需要Pod忽略Node上的污點(diǎn),就需要給Pod設(shè)置容忍滨巴,并且是需要容忍該P(yáng)od上的所有污點(diǎn)。

通過 kubectl explain pod.spec.tolerations 可以查看容忍的配置項(xiàng)

配置項(xiàng)
tolerations: # 數(shù)組類型俺叭,可以設(shè)置多個(gè)容忍
- key: # 污點(diǎn)key
  operator: # 操作符恭取,有兩個(gè)選項(xiàng) Exists and Equal 默認(rèn)是Equal
  value: # 污點(diǎn)value,如果使用Equal需要設(shè)置熄守,如果是Exists就不需要設(shè)置
  effect: # 可以設(shè)置為NoSchedule蜈垮、PreferNoSchedule、NoExecute裕照,如果為空表示匹配該key下所有污點(diǎn)攒发,
  tolerationSeconds: # 如果污點(diǎn)類型為NoExecute,還可以設(shè)置一個(gè)時(shí)間晋南,表示這一個(gè)時(shí)間段內(nèi)Pod不會(huì)被驅(qū)逐惠猿,過了這個(gè)時(shí)間段會(huì)立刻驅(qū)逐,0或者負(fù)數(shù)會(huì)被立刻驅(qū)逐
設(shè)置容忍

給Pod設(shè)置容忍node01節(jié)點(diǎn)的污點(diǎn)web=true:NoSchedule

編寫 web-tolerations.yaml 內(nèi)容如下负间,容忍污點(diǎn)web=true:NoSchedule

apiVersion: v1
kind: Pod
metadata:
  name: web-tolerations
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent # 本地有不拉取鏡像
  tolerations:
  - key: web
    operator: Equal
    value: "true"
    effect: NoSchedule

啟動(dòng)web-tolerations偶妖,觀察Pod是否正常運(yùn)行

# 啟動(dòng)web-tolerations
[root@master taint]# kubectl create -f web-tolerations.yaml  
pod/web-tolerations created

# Pod正常運(yùn)行,且運(yùn)行在node01節(jié)點(diǎn)
[root@master taint]# kubectl get pod -o wide
NAME              READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
web-tolerations   1/1     Running   0          8s    10.244.1.92   node01   <none>           <none>

查看該P(yáng)od上的容忍

[root@master taint]# kubectl describe pod web-tolerations

Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
                             web=true:NoSchedule

可以看到我們?cè)O(shè)置的Tolerations在里邊政溃,除了我們自己的趾访,K8s還會(huì)給每個(gè)Pod設(shè)置兩個(gè)默認(rèn)Tolerations,并且Tolerations時(shí)間為五分鐘董虱,表示某些節(jié)點(diǎn)發(fā)生一些臨時(shí)性問題扼鞋,Pod能夠繼續(xù)在該節(jié)點(diǎn)上運(yùn)行五分鐘等待節(jié)點(diǎn)恢復(fù),并不是立刻被驅(qū)逐,從而避免系統(tǒng)的異常波動(dòng)


編寫 app-tolerations.yaml 內(nèi)容如下云头,容忍污點(diǎn)app=true:NoExecute捐友,并且只容忍60s

apiVersion: v1
kind: Pod
metadata:
  name: app-tolerations
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  tolerations:
  - key: app
    operator: Exists
    effect: NoExecute
    tolerationSeconds: 60

啟動(dòng)app-tolerations,查看Pod是否能夠正常運(yùn)行盘寡,且運(yùn)行在node02節(jié)點(diǎn)楚殿,等待60秒,查看Pod是否已被驅(qū)逐

# 啟動(dòng)app-tolerations
[root@master taint]# kubectl create -f app-tolerations.yaml 
pod/app-tolerations created

# 查看詳情竿痰,已經(jīng)運(yùn)行成功并且調(diào)度到了node02節(jié)點(diǎn)脆粥,此時(shí)運(yùn)行59秒
[root@master taint]# kubectl get pod -o wide
NAME              READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
app-tolerations   1/1     Running   0          59s   10.244.2.37   node02   <none>           <none>

# 運(yùn)行60秒查看,狀態(tài)已經(jīng)變?yōu)門erminating
[root@master taint]# kubectl get pod -o wide
NAME              READY   STATUS        RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
app-tolerations   1/1     Terminating   0          60s   10.244.2.37   node02   <none>           <none>

# 立刻再次查看影涉,已經(jīng)被驅(qū)逐
[root@master taint]# kubectl get pod -o wide
No resources found in default namespace.

如果一個(gè)節(jié)點(diǎn)沒有任何污點(diǎn)变隔,另一個(gè)節(jié)點(diǎn)有污點(diǎn),并且Pod容忍了該污點(diǎn)蟹倾,那么最終會(huì)調(diào)度到哪個(gè)節(jié)點(diǎn)呢匣缘?

刪除node02節(jié)點(diǎn)的污點(diǎn)app=true:NoExecute,保留node01節(jié)點(diǎn)的web=true:NoSchedule鲜棠,再次啟動(dòng)之前的web-tolerations.yaml 觀察Pod所在節(jié)點(diǎn)

# 刪除node02上的污點(diǎn)
[root@master taint]# kubectl taint node node02 app:NoExecute- 
node/node02 untainted

# 啟動(dòng)Pod web-tolerations
[root@master taint]# kubectl create -f web-tolerations.yaml 
pod/web-tolerations created

# Pod正常運(yùn)行肌厨,并且運(yùn)行在node02節(jié)點(diǎn)
[root@master taint]# kubectl get pod -o wide                 
NAME              READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
web-tolerations   1/1     Running   0          2s    10.244.2.38   node02   <none>           <none>

上面表明,即使是容忍了該污點(diǎn)豁陆,如果有其它節(jié)點(diǎn)不需要容忍就可以調(diào)度的話柑爸,那還是會(huì)優(yōu)先選擇沒有污點(diǎn)的機(jī)器,但是生產(chǎn)上往往設(shè)置污點(diǎn)就是為了給你這個(gè)Pod使用的盒音,不能調(diào)度到其它節(jié)點(diǎn)表鳍,這個(gè)時(shí)候需要配合節(jié)點(diǎn)親和性調(diào)度一起使用。

Equal 與 Exists

Exists 表示key是否存在所以無需設(shè)置value祥诽,Equal 則必須設(shè)置value需要完全匹配譬圣,默認(rèn)為Equal

空的key配合Exists 可以匹配所有的key-value,也就是容忍所有的污點(diǎn)雄坪,生產(chǎn)上非常不建議使用

節(jié)點(diǎn)故障后Pod的驅(qū)逐行為

上面也提到了厘熟,K8s為每個(gè)Pod設(shè)置了兩個(gè)容忍,如果是一些臨時(shí)性故障维哈,可以容忍五分鐘不被驅(qū)逐

在K8s 1.6之后還引入了Taint的兩個(gè)新特性盯漂,TaintNodesByCondition與TaintBasedEvictions用來改善出現(xiàn)異常時(shí)對(duì)Pod的調(diào)度與驅(qū)逐問題

TaintNodesByCondition的特性如下(為節(jié)點(diǎn)添加NoSchedule的污點(diǎn))

  • Node節(jié)點(diǎn)會(huì)不斷的檢查Node的狀態(tài),并且設(shè)置對(duì)應(yīng)的Condition
  • 不斷地根據(jù)Condition的變更設(shè)置對(duì)應(yīng)的Taint
  • 不斷地根據(jù)Taint驅(qū)逐Node上的Pod

主要污點(diǎn)如下

node.kubernetes.io/not-ready 節(jié)點(diǎn)未就緒笨农,節(jié)點(diǎn)Ready為False

node.kubernetes.io/unreachable 節(jié)點(diǎn)不可觸達(dá)

node.kubernetes.io/out-of-disk 磁盤空間已滿

node.kubernetes.io/network-unavailable 網(wǎng)絡(luò)不可用

node.kubernetes.io/unschedulable 節(jié)點(diǎn)不可調(diào)度

node.cloudprovider.kubernetes.io/uninitialized 如果 kubelet 從 外部 云服務(wù)商啟動(dòng)的就缆,該污點(diǎn)用來標(biāo)識(shí)某個(gè)節(jié)點(diǎn)當(dāng)前為不可用狀態(tài),當(dāng)云控制器 cloud-controller-manager 初始化這個(gè)節(jié)點(diǎn)后,kubelet 會(huì)將此污點(diǎn)移除

**TaintBasedEvictions **特性添加的是NoExecute的污點(diǎn),例如內(nèi)存與磁盤有壓力時(shí)哨啃,如果Pod沒有設(shè)置容忍這些污點(diǎn)洋访,則會(huì)被驅(qū)逐琅催,以保證Node不會(huì)崩潰

主要污點(diǎn)如下

node.kubernetes.io/memory-pressure 內(nèi)存不足

node.kubernetes.io/disk-pressure 磁盤不足

1.13版本之后TaintNodesByCondition 與 TaintBasedEvictions 都是默認(rèn)開啟


污點(diǎn)與容忍就介紹到這里妈倔,后面將會(huì)介紹Pod的控制器等曼。

歡迎關(guān)注巡验,學(xué)習(xí)不迷路廓旬!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末哼审,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子孕豹,更是在濱河造成了極大的恐慌涩盾,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件励背,死亡現(xiàn)場(chǎng)離奇詭異春霍,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)叶眉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門址儒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人衅疙,你說我怎么就攤上這事莲趣。” “怎么了饱溢?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵喧伞,是天一觀的道長。 經(jīng)常有香客問我理朋,道長,這世上最難降的妖魔是什么绿聘? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任嗽上,我火速辦了婚禮,結(jié)果婚禮上熄攘,老公的妹妹穿的比我還像新娘兽愤。我一直安慰自己,他們只是感情好挪圾,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布浅萧。 她就那樣靜靜地躺著,像睡著了一般哲思。 火紅的嫁衣襯著肌膚如雪洼畅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天棚赔,我揣著相機(jī)與錄音帝簇,去河邊找鬼徘郭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛丧肴,可吹牛的內(nèi)容都是我干的残揉。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼芋浮,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼抱环!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起纸巷,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤镇草,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后何暇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體陶夜,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年裆站,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了条辟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡宏胯,死狀恐怖羽嫡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情肩袍,我是刑警寧澤杭棵,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站氛赐,受9級(jí)特大地震影響魂爪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜艰管,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一滓侍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧牲芋,春花似錦撩笆、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至裂逐,卻和暖如春歹鱼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背卜高。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來泰國打工醉冤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留秩霍,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓蚁阳,卻偏偏與公主長得像铃绒,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子螺捐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容