linux数据污点标记,Taints和Tolerations(污点和容忍)
Taints和Tolerations(污點(diǎn)和容忍)
上面介紹的NodeAffinity節(jié)點(diǎn)親和性,是在pod上定義的一種屬性,是pod能夠被調(diào)度到某些node上運(yùn)行(優(yōu)先選擇或強(qiáng)制要求)。Taint則正好相反,使用kubectl taint命令可以給某個(gè)Node節(jié)點(diǎn)設(shè)置污點(diǎn),Node被設(shè)置上污點(diǎn)之后就和Pod之間存在了一種相斥的關(guān)系,可以讓Node拒絕Pod的調(diào)度執(zhí)行,甚至將Node已經(jīng)存在的Pod驅(qū)逐出去。
Taint需要和Toleration配合使用,讓pod避開那些不適合的node。在node上設(shè)置一個(gè)或多個(gè)Taint之后,除非pod明確聲明能夠容忍這些污點(diǎn),否則無法在這些node上運(yùn)行。Toleration是pod的屬性,讓pod能夠(注意,只是能夠,而非必須)運(yùn)行在標(biāo)注了Taint的node上。
每個(gè)污點(diǎn)的組成如下:
key=value:effect
每個(gè)污點(diǎn)有一個(gè) key 和 value 作為污點(diǎn)的標(biāo)簽,其中 value 可以為空,e?ect 描述污點(diǎn)的作用。
當(dāng)前 taint e?ect 支持如下三個(gè)選項(xiàng):
NoSchedule :表示k8s不會(huì)將新的不能容忍的Pod調(diào)度到具有該污點(diǎn)的Node上,但是之前運(yùn)行在node節(jié)點(diǎn)中的Pod不受影響
PreferNoSchedule :表示k8s將盡量避免將Pod調(diào)度到具有該污點(diǎn)的Node上
NoExecute :表示k8s不會(huì)將新的不能容忍的Pod調(diào)度到具有該污點(diǎn)的Node上,同時(shí)會(huì)將Node上已經(jīng)存在的Pod驅(qū)逐出去
可以用kubectl taint?命令為Node設(shè)置Taint信息:
kubectl taint nodes node1 env=pro:NoSchedule
查看所有Node上的污點(diǎn)
kubectl describe no|grep -e Hostname -e Taints|grep -v none|grep -A 1 "Taints"
查看指定node上的污點(diǎn)
kubectl describe no nodename|grep Taints
刪除taint:
kubectl taint nodes node1 env:NoSchedule-
這個(gè)設(shè)置為node1加上一個(gè)Taint。該Taint的鍵為key,值為value,Taint的效果是NoSchedule。這意味著除非pod明確聲明可以容忍這個(gè)Taint,否則就不會(huì)被調(diào)度到node1上。
然后,需要在pod上聲明 Toleration。下面的兩個(gè)Toleration都被設(shè)置為可以容忍(Toleration)具有該Taint的node,使得pod能夠被調(diào)度到node1上:
apiVersion: v1
kind: Pod
metadata:
name: pod-toleration
spec:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
containers:
- name: pod-toleration
image: gcr.io/google_containers/pause:2.0
或者
tolerations:
- key: "key"
operator: "Exists"
effect: "NoSchedule"
pod的toleration聲明中的key和effect需要與Taint的設(shè)置保持一致,并且滿足以下條件之一。operator的值是Exists(無需指定value)
operator的值是Equal?并且value相等。
如果不指定operator,則默認(rèn)值為Equal。
另外,有如下兩個(gè)特例:空的key配合Exists操作符能夠匹配所有的鍵和值。
空的effect匹配所有的effect。
系統(tǒng)允許在同一個(gè)Node上設(shè)置多個(gè)Taint,也可以在Pod上設(shè)置多個(gè)Toleration。Kubernetes調(diào)度器處理多個(gè)Taint和Toleration的邏輯順序?yàn)?#xff1a;首先列出節(jié)點(diǎn)中所有的Taint,然后忽略Pod的Toleration能夠匹配的部分,剩下的沒有忽略的Taint就是對Pod的效果了。下面是幾種特殊情況。
如果在剩余的Taint中存在effect=NoSchedule,則調(diào)度器不會(huì)把該P(yáng)od調(diào)度到這一節(jié)點(diǎn)上。
如果在剩余的Taint中沒有NoSchedule效果,但是有PreferNoSchedule效果,則調(diào)度器會(huì)嘗試不把這個(gè)Pod指派給這個(gè)節(jié)點(diǎn)。
如果在剩余的Taint中有NoExecute效果,并且這個(gè)Pod已經(jīng)在該節(jié)點(diǎn)上運(yùn)行,則會(huì)被驅(qū)逐;如果沒有在該節(jié)點(diǎn)上運(yùn)行,則也不會(huì)再被調(diào)度到該節(jié)點(diǎn)上。
例如,我們這樣對一個(gè)節(jié)點(diǎn)進(jìn)行Taint設(shè)置:
kubectl taint nodes node1 key1=value1:NoSchedule
kubectl taint nodes node1 key1=value1:NoExecute
kubectl taint nodes node1 key2=value2:NoSchedule
然后在Pod上設(shè)置兩個(gè)Toleration:
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
這樣的結(jié)果是該P(yáng)od無法被調(diào)度到node1上,這是因?yàn)榈?個(gè)Taint沒有匹配的Toleration。但是如果該P(yáng)od已經(jīng)在node1上運(yùn)行了,那么在運(yùn)行時(shí)設(shè)置第3個(gè)Taint,它還能繼續(xù)在node1上運(yùn)行,這是因?yàn)镻od可以容忍前兩個(gè)Taint。
一般來說,如果給Node加上effect=NoExecute的Taint,那么在該Node上正在運(yùn)行的所有無對應(yīng)Toleration的Pod都會(huì)被立刻驅(qū)逐,而具有相應(yīng)Toleration的Pod永遠(yuǎn)不會(huì)被驅(qū)逐。不過,系統(tǒng)允許給具有NoExecute效果的Toleration加入一個(gè)可選的tolerationSeconds字段,這個(gè)設(shè)置表明Pod可以在Taint添加到Node之后還能在這個(gè)Node上運(yùn)行多久(單位為s):
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
tolerationSeconds: 3600
上述定義的意思是,如果Pod正在運(yùn)行,所在節(jié)點(diǎn)都被加入一個(gè)匹配的Taint,則這個(gè)Pod會(huì)持續(xù)在這個(gè)節(jié)點(diǎn)上存活3600s后被逐出。如果在這個(gè)寬限期內(nèi)Taint被移除,則不會(huì)觸發(fā)驅(qū)逐事件。
Taint和Toleration是一種處理節(jié)點(diǎn)并且讓Pod進(jìn)行規(guī)避或者驅(qū)逐Pod的彈性處理方式,下面列舉一些常見的用例。
1.專用節(jié)點(diǎn)(dedicated)
如果想要拿出一部分節(jié)點(diǎn)專門給一些特定應(yīng)用使用,則可以為節(jié)點(diǎn)添加這樣的Taint:
kubectl taint nodes nodename dedicated=groupName:NoSchedule
然后給這些應(yīng)用的Pod加入對應(yīng)的Toleration。這樣,帶有合適Toleration的Pod就會(huì)被允許同使用其他節(jié)點(diǎn)一樣使用有Taint的節(jié)點(diǎn)。
通過自定義Admission Controller也可以實(shí)現(xiàn)這一目標(biāo)。如果希望讓這些應(yīng)用獨(dú)占一批節(jié)點(diǎn),并且確保它們只能使用這些節(jié)點(diǎn),則還可以給這些Taint節(jié)點(diǎn)加入類似的標(biāo)簽dedicated=groupName,然后Admission Controller需要加入節(jié)點(diǎn)親和性設(shè)置,要求Pod只會(huì)被調(diào)度到具有這一標(biāo)簽的節(jié)點(diǎn)上。
2.具有特殊(special)硬件設(shè)備的節(jié)點(diǎn)
在集群里可能有一小部分節(jié)點(diǎn)安裝了特殊的硬件設(shè)備(如GPU芯片),用戶自然會(huì)希望把不需要占用這類硬件的Pod排除在外,以確保對這類硬件有需求的Pod能夠被順利調(diào)度到這些節(jié)點(diǎn)。
可以用下面的命令為節(jié)點(diǎn)設(shè)置Taint:
kubectl taint nodes nodename special=true:NoSchedule
kubectl taint nodes nodename special=true:PreferNoSchedule
然后在Pod中利用對應(yīng)的Toleration來保障特定的Pod能夠使用特定的硬件。
和上面的獨(dú)占節(jié)點(diǎn)的示例類似,使用Admission Controller來完成這一任務(wù)會(huì)更方便。例如,Admission Controller使用Pod的一些特征來判斷這些Pod,如果可以使用這些硬件,就添加Toleration來完成這一工作。要保障需要使用特殊硬件的Pod只被調(diào)度到安裝這些硬件的節(jié)點(diǎn)上,則還需要一些額外的工作,比如將這些特殊資源使用opaque-int-resource的方式對自定義資源進(jìn)行量化,然后在PodSpec中進(jìn)行請求;也可以使用標(biāo)簽的方式來標(biāo)注這些安裝有特別硬件的節(jié)點(diǎn),然后在Pod中定義節(jié)點(diǎn)親和性來實(shí)現(xiàn)這個(gè)目標(biāo)。
3.基于污點(diǎn)的驅(qū)逐,以應(yīng)對節(jié)點(diǎn)故障
前面提到的NoExecute這個(gè)Taint效果對節(jié)點(diǎn)上正在運(yùn)行的Pod有以下影響。
◎ 沒有設(shè)置Toleration的Pod會(huì)被立刻驅(qū)逐。
◎ 配置了對應(yīng)Toleration的Pod,如果沒有為tolerationSeconds賦值,則會(huì)一直留在這一節(jié)點(diǎn)中。
◎ 配置了對應(yīng)Toleration的Pod且指定了tolerationSeconds值,則會(huì)在指定時(shí)間后驅(qū)逐。
◎ 把節(jié)點(diǎn)故障標(biāo)記為Taint
當(dāng)某種條件為真時(shí),節(jié)點(diǎn)控制器會(huì)自動(dòng)給節(jié)點(diǎn)添加一個(gè)污點(diǎn)。當(dāng)前內(nèi)置的污點(diǎn)包括:
node.kubernetes.io/not-ready:節(jié)點(diǎn)未準(zhǔn)備好。這相當(dāng)于節(jié)點(diǎn)狀態(tài)?Ready?的值為 "False"。
node.kubernetes.io/unreachable:節(jié)點(diǎn)控制器訪問不到節(jié)點(diǎn). 這相當(dāng)于節(jié)點(diǎn)狀態(tài)?Ready?的值為 "Unknown"。
node.kubernetes.io/out-of-disk:節(jié)點(diǎn)磁盤耗盡。
node.kubernetes.io/memory-pressure:節(jié)點(diǎn)存在內(nèi)存壓力。
node.kubernetes.io/disk-pressure:節(jié)點(diǎn)存在磁盤壓力。
node.kubernetes.io/network-unavailable:節(jié)點(diǎn)網(wǎng)絡(luò)不可用。
node.kubernetes.io/unschedulable: 節(jié)點(diǎn)不可調(diào)度。
node.cloudprovider.kubernetes.io/uninitialized:如果 kubelet 啟動(dòng)時(shí)指定了一個(gè) "外部" 云平臺(tái)驅(qū)動(dòng), 它將給當(dāng)前節(jié)點(diǎn)添加一個(gè)污點(diǎn)將其標(biāo)志為不可用。在 cloud-controller-manager 的一個(gè)控制器初始化這個(gè)節(jié)點(diǎn)后,kubelet 將刪除這個(gè)污點(diǎn)。
在節(jié)點(diǎn)被驅(qū)逐時(shí),節(jié)點(diǎn)控制器或者 kubelet 會(huì)添加帶有 NoExecute 效應(yīng)的相關(guān)污點(diǎn)。 如果異常狀態(tài)恢復(fù)正常,kubelet 或節(jié)點(diǎn)控制器能夠移除相關(guān)的污點(diǎn)。
說明: 為了保證由于節(jié)點(diǎn)問題引起的 Pod 驅(qū)逐 速率限制行為正常, 系統(tǒng)實(shí)際上會(huì)以限定速率的方式添加污點(diǎn)。在像主控節(jié)點(diǎn)與工作節(jié)點(diǎn)間通信中斷等場景下, 這樣做可以避免 Pod 被大量驅(qū)逐。
例如,一個(gè)包含很多本地狀態(tài)的應(yīng)用可能需要在網(wǎng)絡(luò)發(fā)生故障時(shí),還能持續(xù)在節(jié)點(diǎn)上運(yùn)行,期望網(wǎng)絡(luò)能夠快速恢復(fù),從而避免被從這個(gè)節(jié)點(diǎn)上驅(qū)逐。
Pod的Toleration可以這樣定義:
tolerations :
- key : "node.kubernetes.io/unreachable"
operator:"Exists"
effect : "NoExecute"
tolerationSeconds : 6000
說明:
如果沒有為Pod指定node.kubernetes.io/not-ready的Toleration,那么Kubernetes會(huì)自動(dòng)為Pod加入tolerationSeconds=300 的node.kubernetes.io/not-ready類型的Toleration。
同樣,如果Pod沒有定義node.kubernetes.io/unreachable的Toleration,那么系統(tǒng)會(huì)自動(dòng)為其加入tolerationSeconds=300 的node.kubernetes.io/unreachable類型的Toleration。
這些系統(tǒng)自動(dòng)設(shè)置的toleration在Node發(fā)現(xiàn)問題時(shí),能夠?yàn)镻od確保驅(qū)逐前再運(yùn)行5min。這兩個(gè)默認(rèn)的Toleration由AdmissionController“DefaultTolerationSeconds”自動(dòng)加入。
DaemonSet 中的 Pod 被創(chuàng)建時(shí), 針對以下污點(diǎn)自動(dòng)添加的 NoExecute 的容忍度將不會(huì)指定 tolerationSeconds:node.kubernetes.io/unreachable
node.kubernetes.io/not-ready
這保證了出現(xiàn)上述問題時(shí) DaemonSet 中的 Pod 永遠(yuǎn)不會(huì)被驅(qū)逐。
總結(jié)
以上是生活随笔為你收集整理的linux数据污点标记,Taints和Tolerations(污点和容忍)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 主机大师linux,113资讯网(www
- 下一篇: linux阿波罗配置文件放在哪,Apol