自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何用三只兔子的故事來輕松理解 Kubernetes 污點和容忍

系統(tǒng) Linux
本文通過自身理解進行述說,如有不準確的地方,請指正。

前言

本文通過自身理解進行述說,如有不準確的地方,請指正。

在講述一系列相關(guān)專業(yè)術(shù)語之前,先嘗試用一個通俗易懂的故事來說明 Kubernetes 中 node 與 pod 之間的愛恨情仇。

雄性(node)| 雌性(pod)

在銀河系以外的一個星球上,有著一群兩性生物,分別是雌性(pod)和雄性(node)。雌性生物居多,而雄性生物由于優(yōu)勝劣汰,只剩下 3 只優(yōu)質(zhì)的雄性生物(node)。雄雌在一起就容易產(chǎn)生吸引,就會有以下的情況產(chǎn)生:

(1)雄(node)少雌(pod)多,而這三只優(yōu)質(zhì)的雄性生物性格、優(yōu)點都是一致的,雌性生物選誰都一樣。于是,雌性生物就分為均等分為三列和三只雄性生物在一起。這種類似于平均分配的原則。

k8s 中的概念:在 k8s 中是最常見最普通的 pod 分布方式,常用與 deployment 和 daemonset 控制器。

(2)時間一長,生物開始了進化。三只雄性(node)生物各自有了不一樣的地方,編號 1 的雄性學(xué)會了種植(node01 label skill='grow');編號 2 的雄性學(xué)會了打獵(node02 label skill='hunt');編號 3 的雄性啥也沒學(xué)會(沒學(xué)會就保持默認)。普通的雌性(pod)仍然保持著平均分配的原則。而一些進化快的雌性(pod)生物發(fā)現(xiàn)了三只優(yōu)質(zhì)雄性(node)生物各自的不同,各自也開始有了一些選擇。一些雌性更加青睞學(xué)會種植的雄性生物(nodeSelector skill='grow') ;一些雌性更加青睞學(xué)打獵的雄性生物(nodeSelector skill='hunt') ;而有些雌性生物喜歡的特點很奇特,它們喜歡會飛的雄性,而僅存的三只雄性生物都無法滿足這一特點。如果有天一只雄性生物進化會飛了,它們就會依附與會飛的雄性生物,如果始終沒有進化出會飛的雄性生物,則它們一直等下去這在 k8s 中,就是 yaml 文件中 nodeSelector 的使用。

 k8s 中的概念:當 node 打上特定的標簽后,會出現(xiàn)如下情況:

  1.   pod 中未指定 nodeSelector ,則保持默認 schedule 調(diào)度算法的方式;
  2.   pod 中指定了 nodeSelector ,且指定 nodeSelector 中的 key、value 符合某一個 node 中的某一個 key、value,則這個 pod 直接調(diào)度到該 node;
  3.   pod 中指定了 nodeSelector ,指定 nodeSelector 中的 key、value 不包含在任何一個 node 中,則這個 pod 會一直處于 padding 狀態(tài)。

(3)三只雄性(node)不僅優(yōu)點增長了,缺點也隨之而來。編號 1 的雄性喜歡打臉(node01 taint hobby='face');編號 2 的雄性喜歡打屁股(node01 taint hobby='hunkers');編號 3 的雄性喜歡踩腳(node01 taint hobby='foot');普通的雌性(pod)生物仍然保持平均分配的原則,而一些再次進化的雌性生物也有了自己的性格。能夠容忍打臉的雌性則和編號 1 的雄性在一起(tolerations hobby='face'),但是這個容忍可能是永久,也可能是 1 天(tolerationSeconds=86400)。而這三只雄性生物偶爾會在一起鬼混,編號 1 的雄性生物說不定哪天就嗜好就變?yōu)榱讼矚g睡懶覺。而一些無法容忍它睡懶覺嗜好的雌性生物就會隔一段時間或者馬上就離開它。

k8s 中的概念:這就是 污點 與 容忍。

污點和容忍還有其他的選項參數(shù),后文展開解說。

nodeSelector

將 pod 分配給指定的節(jié)點。

集群如下: 

  1. $ kubectl get nodes  
  2. NAME         STATUS   ROLES    AGE   VERSION  
  3. k8s-master   Ready    master   20h   v1.19.7  
  4. k8s-node01   Ready    <none>   20h   v1.19.7  
  5. k8s-node02   Ready    <none>   20h   v1.19.7 

為 k8s-node01 添加一個標簽 

  1. $ kubectl label nodes k8s-node01 disktype=ssd  
  2. node/k8s-node01 labeled 

查看標簽 

  1. $ kubectl get nodes --show-labels  
  2. NAME         STATUS   ROLES    AGE   VERSION   LABELS  
  3. k8s-master   Ready    master   20h   v1.19.7   ..., kubernetes.io/hostname=k8s-master  
  4. k8s-node01   Ready    <none>   20h   v1.19.7   ..., disktype=ssd,kubernetes.io/hostname=k8s-node01  
  5. k8s-node02   Ready    <none>   20h   v1.19.7   ..., kubernetes.io/hostname=k8s-node02 

可以看到 k8s-node01 節(jié)點標簽:disktype=ssd

創(chuàng)建一個調(diào)度到 選擇節(jié)點的 Pod 

  1. apiVersion: apps/v1  
  2. kind: Deployment  
  3. metadata:  
  4.   labels:  
  5.     app: ngx  
  6.   name: ngx  
  7. spec:  
  8.   replicas: 2  
  9.   selector:  
  10.     matchLabels:  
  11.       app: ngx  
  12.   template:  
  13.     metadata:  
  14.       labels: 
  15.         app: ngx  
  16.     spec:  
  17.       containers:  
  18.       - image: nginx:alpine-arm64  
  19.         name: nginx  
  20.       nodeSelector:  
  21.         disktype: ssd    #### 選擇服務(wù) key: value 的節(jié)點  

創(chuàng)建 pod 查看是否調(diào)度到指定的節(jié)點 

  1. $ kubectl apply -f  ngx.yaml  
  2. deployment.apps/ngx created  
  3. $ kubectl get po -o wide  
  4. NAME                   READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES  
  5. ngx-5f4df66559-hjmzg   1/1     Running   0          10s   10.244.1.13   k8s-node01   <none>           <none>  
  6. ngx-5f4df66559-wqgdb   1/1     Running   0          10s   10.244.1.14   k8s-node01   <none>           <none> 

k8s 親和性

說道親和性,親和性主要分為兩類:nodeAffinity 和 podAffinity 。

nodeAffinity

nodeAffinity 就是節(jié)點親和性,調(diào)度可以分成軟策略和硬策略兩種方式,軟策略就是如果你沒有滿足調(diào)度要求的節(jié)點的話,POD 就會忽略這條規(guī)則,繼續(xù)完成調(diào)度過程,說白了就是滿足條件最好了,沒有的話也無所謂了的策略;而硬策略就比較強硬了,如果沒有滿足條件的節(jié)點的話,就不斷重試直到滿足條件為止,簡單說就是你必須滿足我的要求,不然我就不干的策略。nodeAffinity就有兩上面兩種策略:

  •  requiredDuringSchedulingIgnoredDuringExecution :硬策略
  •  preferredDuringSchedulingIgnoredDuringExecution :軟策略

硬策略 

  1. apiVersion: apps/v1  
  2. kind: Deployment  
  3. metadata:  
  4.   labels:  
  5.     app: ngx  
  6.   name: ngx  
  7. spec:  
  8.   replicas: 2  
  9.   selector: 
  10.      matchLabs:  
  11.       app: ngx  
  12.   template:  
  13.     metadata:  
  14.       labels:  
  15.         app: ngx  
  16.     spec:  
  17.       affinity:  
  18.         nodeAffinity:  
  19.           requiredDuringSchedulingIgnoredDuringExecution:  
  20.             nodeSelectorTerms:  
  21.             - matchExpressions:  
  22.               - key: disktype ## key 的值  
  23.                 operator: In ## 包括  
  24.                 values:  
  25.                 - ssd ## value  
  26.       containers:  
  27.       - image: nginx:alpine-arm64  
  28.         name: nginx  
  29.       nodeSelector:  
  30.         disktype: ssd 

上面這兩個 pod 只會運行在 滿足 node label disktype=value 的節(jié)點上,如果沒有節(jié)點滿足這個條件,則一直處于 pending 狀態(tài)。 

  1. $ kubectl get po -o wide  
  2. NAME                  READY   STATUS    RESTARTS   AGE     IP            NODE         NOMINATED NODE   READINESS GATES  
  3. ngx-7b65b44bc-gff9x   1/1     Running   0          3m53s   10.244.1.15   k8s-node01   <none>           <none>  
  4. ngx-7b65b44bc-w7bsf   1/1     Running   0          3m53s   10.244.1.16   k8s-node01   <none>           <none>  
  5. $ kubectl get nodes k8s-node01 --show-labels  
  6. NAME         STATUS   ROLES    AGE   VERSION   LABELS  
  7. k8s-node01   Ready    <none>   22h   v1.19.7   ..., disktype=ssd,kubernetes.io/arch=arm64,kubernetes.io/hostname=k8s-node01 

軟策略 

  1. apiVersion: apps/v1  
  2. kind: Deployment  
  3. metadata:  
  4.   labels:  
  5.     app: ngx  
  6.   name: ngx 
  7. spec:  
  8.   replicas: 2  
  9.   selector:  
  10.     matchLabels:  
  11.       app: ngx  
  12.   template:  
  13.     metadata:  
  14.       labels:  
  15.         app: ngx  
  16.     spec:  
  17.       affinity:  
  18.         nodeAffinity:  
  19.           preferredDuringSchedulingIgnoredDuringExecution:  
  20.           - weight: 10  
  21.             preference:  
  22.               matchExpressions:  
  23.               - key: disktype  
  24.                 operator: In  
  25.                 values: 
  26.                 - hdd 
  27.       containers:  
  28.       - image: nginx:alpine-arm64  
  29.         name: nginx 

軟策略就是,第一選擇是 node label disktype=hdd 的節(jié)點,如果沒有,就采用默認 scheduler 的調(diào)度策略,沒有強制性。 

  1. $ kubectl get po -o wide  
  2. NAME                  READY   STATUS    RESTARTS   AGE     IP            NODE         NOMINATED NODE   READINESS GATES  
  3. ngx-d4754b6fd-lr96g   1/1     Running   0          2m55s   10.244.2.13   k8s-node02   <none>           <none>  
  4. ngx-d4754b6fd-ns7hs   1/1     Running   0          2m55s   10.244.1.28   k8s-node01   <none>           <none> 

operator 提供如下幾種操作:

  •  In:label 的值在某個列表中
  •  NotIn:label 的值不在某個列表中
  •  Gt:label 的值大于某個值
  •  Lt:label 的值小于某個值
  •  Exists:某個 label 存在
  •  DoesNotExist:某個 label 不存在

如果nodeSelectorTerms下面有多個選項的話,滿足任何一個條件就可以了;如果matchExpressions有多個選項的話,則必須同時滿足這些條件才能正常調(diào)度 POD。

污點和容忍

在 Kubernetes 中,節(jié)點親和性 NodeAffinity 是 Pod 上定義的一種屬性,能夠使 Pod 按我們的要求調(diào)度到某個節(jié)點上,而 Taints(污點) 則恰恰相反,它是 Node 上的一個屬性,可以讓 Pod 不能調(diào)度到帶污點的節(jié)點上,甚至?xí)埸c節(jié)點上已有的 Pod 進行驅(qū)逐。當然,對應(yīng)的 Kubernetes 可以給 Pod 設(shè)置 Tolerations(容忍) 屬性來讓 Pod 能夠容忍節(jié)點上設(shè)置的污點,這樣在調(diào)度時就會忽略節(jié)點上設(shè)置的污點,將 Pod 調(diào)度到該節(jié)點。一般時候 Taints 通常與 Tolerations 配合使用。

污點(Taints)

查看污點

查看 node 的污點 

  1. $ kubectl describe nodes k8s-master  
  2. ...  
  3. Taints:             node-role.kubernetes.io/master:NoSchedule  
  4. ...  
  5. # 也可通過下面操作查看:  
  6. $ kubectl get nodes k8s-master -o go-template={{.spec.taints}}  
  7. [map[effect:NoSchedule key:node-role.kubernetes.io/master]] 

污點內(nèi)容一般組成為 key、value 及一個 effect 三個元素,表現(xiàn)為:

  1. <key>=<value>:<effect> 

這里的 value 可以為空,表現(xiàn)形式為: 

  1. node-role.kubernetes.io/master:NoSchedule  
  2. - key: node-role.kubernetes.io/master  
  3. - value: 空 
  4. - effect: NoSchedule 

設(shè)置污點

一般我們需要想要設(shè)置某個節(jié)點只允許特定的 Pod 進行調(diào)度,這時候就得對節(jié)點設(shè)置污點,可以按 kubectl taint node [node] key=value[effect] 格式進行設(shè)置,其中 effect 可取值如下:

  •  PreferNoSchedule: 盡量不要調(diào)度。
  •  NoSchedule: 一定不能被調(diào)度。
  •  NoExecute: 不僅不會調(diào)度, 還會驅(qū)逐 Node 上已有的 Pod。

一般時候我們設(shè)置污點,就像下面例子一樣對齊進行設(shè)置: 

  1. ### 設(shè)置污點并不允許 Pod 調(diào)度到該節(jié)點  
  2. $ kubectl taint node k8s-master key1=value1:NoSchedule  
  3. ### 設(shè)置污點盡量阻止污點調(diào)度到該節(jié)點  
  4. $ kubectl taint node k8s-master key2=value2:PreferNoSchedule  
  5. ### 設(shè)置污點,不允許普通 Pod 調(diào)度到該節(jié)點,且將該節(jié)點上已經(jīng)存在的 Pod 進行驅(qū)逐  
  6. $ kubectl taint node k8s-master key3=value3:NoExecute 

刪除污點

上面說明了如何對 Node 添加污點阻止 Pod 進行調(diào)度,下面再說一下如何刪除節(jié)點上的污點,可以使用下面命令: 

  1. kubectl taint node [node] [key]- 

上面語法和創(chuàng)建污點類似,不過需要注意的是刪除污點需要知道 key 和最后面設(shè)置一個 "-" 兩項將污點刪除,示例如下:

為了方便演示,先給節(jié)點設(shè)置污點: 

  1. ### 設(shè)置污點1  
  2. $ kubectl taint node k8s-master key1=value1:PreferNoSchedule  
  3. node/k8s-master tainted  
  4. ### 設(shè)置污點2  
  5. $ kubectl taint node k8s-master key2=value2:NoSchedule  
  6. node/k8s-master tainted  
  7. ### 設(shè)置污點3,并且不設(shè)置 value  
  8. $ kubectl taint node k8s-master key2=:PreferNoSchedule  
  9. node/k8s-master tainted 

查看污點,可以看到上面設(shè)置的三個值: 

  1. $ kubectl describe nodes k8s-master  
  2. ...  
  3. Taints:             key2=value2:NoSchedule  
  4.                     node-role.kubernetes.io/master:NoSchedule  
  5.                     key1=value1:PreferNoSchedule  
  6.                     key2:PreferNoSchedule 
  7.  ... 

然后刪除污點 

  1. ### 刪除污點,可以不指定 value,指定 [effect] 值就可刪除該 key[effect] 的污點  
  2. $ kubectl taint node k8s-master key1:PreferNoSchedule-  
  3. ### 也可以根據(jù) key 直接將該 key2 的所有 [effect] 都刪除:  
  4. $ kubectl taint node k8s-master key2- 

再次查看污點,可以看到以上污點都被刪除: 

  1. $ kubectl describe nodes k8s-master  
  2. ...  
  3. Taints:             node-role.kubernetes.io/master:NoSchedule  
  4. ...  

容忍 (toleratints)

Pod 設(shè)置容忍

為了使某些 Pod 禁止調(diào)度到某些特定節(jié)點上,就可以對節(jié)點設(shè)置污點 taints。當然,如果希望有些 Pod 能夠忽略節(jié)點的污點,繼續(xù)能夠調(diào)度到該節(jié)點,就可以對 Pod 設(shè)置容忍,讓 Pod 能夠容忍節(jié)點上設(shè)置的污點,例如:

對一個節(jié)點設(shè)置污點: 

  1. kubectl taint node k8s-node01 key=value:NoSchedule 

對于 Pod 設(shè)置容忍, 以下兩種方式都可以: 

  1. ### 容忍的 key、value 和對應(yīng) effect 也必須和污點 taints 保持一致  
  2. ......  
  3. tolerations:  
  4. - key: "key"  
  5.   operator: "Equal" 
  6.   value: "value"  
  7.   effect: "NoSchedule"  
  8. ### 容忍 tolerations 的 key 和要污點 taints 的 key 一致,且設(shè)置的 effect 也相同,不需要設(shè)置 value  
  9. ......  
  10. tolerations:  
  11. - key: "key"  
  12.   operator: "Exists"  
  13.   effect: "NoSchedule" 

Node 和 Pod 對于污點與容忍基本概念

概念

  •  一個 node 可以有多個污點;
  •  一個 pod 可以有多個容忍;
  •  kubernetes 執(zhí)行多個污點和容忍方法類似于過濾器

如果一個 node 有多個污點,且 pod 上也有多個容忍,只要 pod 中容忍能包含 node 上設(shè)置的全部污點,就可以將 pod 調(diào)度到該 node 上。如果 pod 上設(shè)置的容忍不能夠包含 node 上設(shè)置的全部污點,且 node 上剩下不能被包含的污點 effect 為 PreferNoSchedule,那么也可能會被調(diào)度到該節(jié)點。

注意

當 pod 總存在 容忍,首先 pod 會選擇沒有污點的節(jié)點,然后再次選擇容忍污點的節(jié)點。

  •  如果 node 上帶有污點 effect 為 NoSchedule,而 pod 上不帶響應(yīng)的容忍,kubernetes 就不會調(diào)度 pod 到這臺 node 上。
  •  如果 Node 上帶有污點 effect 為 PreferNoShedule,這時候 Kubernetes 會努力不要調(diào)度這個 Pod 到這個 Node 上。
  •  如果 Node 上帶有污點 effect 為 NoExecute,這個已經(jīng)在 Node 上運行的 Pod 會從 Node 上驅(qū)逐掉。沒有運行在 Node 的 Pod 不能被調(diào)度到這個 Node 上。一般使用與當某個節(jié)點處于 NotReady 狀態(tài)下,pod 迅速在其他正常節(jié)點啟動。

Deployment 中設(shè)置容忍

在 kubernetes 中 deployment 設(shè)置容忍,示例如下: 

  1. apiVersion: apps/vl  
  2. kind: Deployment  
  3. metadata:  
  4.   name: example  
  5. spec:  
  6.   replicas: 5  
  7.   template:  
  8.     spec:  
  9.       ......  
  10.       tolerations:  
  11.       - key: "key"  
  12.         operator: "Equal"  
  13.         value: "value"  
  14.         effect: "NoSchedule" 

設(shè)置容忍時間

正常情況下, 如果一個污點帶有 effect=NoExecute 被添加到了這個 Node。那么不能容忍這個污點的所有 Pod 就會立即被踢掉。而帶有容忍標簽的 Pod 就不會踢掉。然而,一個帶有 effect=Noexecute 的容忍可以指定一個 tolerationSeconds 來指定當這個污點被添加的時候在多長時間內(nèi)不被踢掉。例如: 

  1. tolerations:  
  2. - key: "key"  
  3.   operator: "Equal"  
  4.   value: "value"  
  5.   effect: "Noexecute"  
  6.   tolerationSeconds: 3600 

如果這個 Pod 已經(jīng)在這個帶污點且 effect 為 NoExecute 的 node 上。這個 pod 可以一直運行到 3600s 后再被踢掉。如果這時候 Node 的污點被移除了,這個 Pod 就不會被踢掉。

容忍示例

Operator 默認是 Equal,可設(shè)置為 Equal 與 Exists 兩種,按這兩種進行示例:

Operator 是 Exists

容忍任何污點

例如一個空的 key,將匹配所有的 key、value、effect。即容忍任何污點。 

  1. tolerations:  
  2. - operator: "Exists" 

容忍某 key 值的污點

例如一個空的 effect,并且 key 不為空,那么將匹配所有與 key 相同的 effect: 

  1. tolerations:  
  2. - key: "key"  
  3.   operator: "Exists" 

Operator 是 Equal

node 上有一個污點

Node 和 Pod 的 key 為 key1、value1 與 effect 相同則能調(diào)度: 

  1. #污點  
  2. key1=value1:NoSchedule  
  3. #Pod設(shè)置  
  4. tolerations:  
  5. - key: "key1"  
  6.   operator: "Equal"  
  7.   value: "value1"  
  8.   effect: "NoSchedule" 

node 上有多個污點

Node 的污點的 key、value、effect 和 Pod 容忍都相同則能調(diào)度: 

  1. ## 設(shè)置污點  
  2. key1=value1:NoSchedule  
  3. key2=value2:NoExecute  
  4. ## Pod設(shè)置容忍  
  5. tolerations:  
  6. - key: "key1"  
  7.   operator: "Equal"  
  8.   value: "value1"  
  9.   effect: "NoSchedule"  
  10. - key: "key2"  
  11.   operator: "Equal"  
  12.   value: "value2"  
  13.   effect: "NoExecute" 

Node 的污點和 Pod 的大部分都相同,不同的是 Node 污點 effect 為 PreferNoSchedule 的,可能會調(diào)度: 

  1. ## 污點  
  2. key1=value1:NoSchedule  
  3. key2=value2:NoExecute  
  4. key3=value3:PreferNoSchedule  
  5. ## Pod設(shè)置容忍  
  6. tolerations:  
  7. - key: "key1"  
  8.   operator: "Equal"  
  9.   value: "value1"  
  10.   effect: "NoSchedule"  
  11. - key: "key2"  
  12.   operator: "Equal"  
  13.   value: "value2"  
  14.   effect: "NoExecute" 

Node 的污點和 Pod 的大部分都相同,不同的是 Node 污點 effect 為 NoSchedule 和 NoExecute 的,不會被調(diào)度: 

  1. ## 污點  
  2. key1=value1:NoSchedule  
  3. key2=value2:NoExecute  
  4. key3=value3:PreferNoSchedule  
  5. ## Pod設(shè)置容忍  
  6. tolerations:  
  7. - key: "key1"  
  8.   operator: "Equal"  
  9.   value: "value1"  
  10.   effect: "NoSchedule"  
  11. - key: "key3"  
  12.   operator: "Equal"  
  13.   value: "value3"  
  14.   effect: "PreferNoSchedule" 

對比理解 Exists 和 Equal 之間的區(qū)別:

  •  Exists 是包含,Equal 是等于,Exists 使用范圍更廣,而 Equal 則是精準匹配。
  •  當污點中存在 NoExecute 時,而容忍中不存在 NoExecute 時,不會被調(diào)度到該節(jié)點。
  •  Exists 可以不寫 value , 而 Equal 則一定要指定對應(yīng)的 value

污點驅(qū)逐

在使用 kubernetes 時,會遇到 某個 node 節(jié)點明明已經(jīng) 宕機了,查看 node 狀態(tài)從 Ready 狀態(tài)變?yōu)?NotReady 狀態(tài),但是 節(jié)點所在的 pod 卻已經(jīng)處于 running 狀態(tài),過了很長一段時間才會轉(zhuǎn)為 Terminating 狀態(tài),這是為什么呢?

污點是對于 node 節(jié)點來講,如果 node 節(jié)點 effect 設(shè)置為 NoExecute ,它會影響節(jié)點上已經(jīng)運行的 Pod,如下所示:

  •  立即將沒有匹配容忍的 pod 驅(qū)逐。
  •  設(shè)置容忍但是沒有指定 tolerationSeconds 參數(shù)的,那么該容忍永久生效,不會被驅(qū)逐。
  •  設(shè)置容忍但是有指定 tolerationSeconds 參數(shù)的,那么在指定的時間內(nèi)容忍有效,超過指定時間后將被剔除。(pod 默認設(shè)置,tolerationSeconds = 300s)

此外,當某些條件為 true 時,節(jié)點控制器會自動污染節(jié)點。內(nèi)置以下污點:

key 注釋
node.kubernetes.io/not-ready 節(jié)點尚未準備好。這對應(yīng)于 NodeCondition Ready 為 false。
node.kubernetes.io/unreachable 無法從節(jié)點控制器訪問節(jié)點。這對應(yīng)于 NodeCondition Ready 為 Unknown。
node.kubernetes.io/out-of-disk 節(jié)點磁盤不足。
node.kubernetes.io/memory-pressure 節(jié)點有內(nèi)存壓力。
node.kubernetes.io/disk-pressure 節(jié)點有磁盤壓力。
node.kubernetes.io/network-unavailable 節(jié)點的網(wǎng)絡(luò)不可用。
node.kubernetes.io/unschedulable 節(jié)點不可調(diào)度。
node.cloudprovider.kubernetes.io/uninitialized 當 kubelet 從 "外部" 云提供程序開始時,此污點在節(jié)點上設(shè)置為將其標記為不可用。來自 cloud-controller-manager 的控制器初始化此節(jié)點后,kubelet 刪除此污點。

通過上面知識的鋪墊,當一個節(jié)點宕機時,kubernetes 集群會給它打上什么樣的污點呢?

一個 Ready 狀態(tài)的節(jié)點 

  1. $ kubectl get node k8s-node02 -o go-template={{.spec.taints}}  
  2. <no value> 

一個 NotReady 狀態(tài)的節(jié)點 

  1. $ kubectl get node k8s-node02 -o go-template={{.spec.taints}}  
  2. [map[effect:NoSchedule key:node.kubernetes.io/unreachable timeAdded:2021-12-23T13:49:58Z] map[effect:NoExecute key:node.kubernetes.io/unreachable timeAdded:2021-12-23T13:50:03Z]] 

 處于 NotReady 狀態(tài)的節(jié)點被打上了下面兩個污點: 

  1. Taints:             node.kubernetes.io/unreachable:NoExecute  
  2.                     node.kubernetes.io/unreachable:NoSchedule 

接下來測試 kubernetes 集群會給 Pod 分配什么樣的容忍。 

  1. $ kubectl get po nginx-745b4df97d-mgdmp -o yaml  
  2. ...  
  3.   tolerations:  
  4.   - effect: NoExecute  
  5.     key: node.kubernetes.io/not-ready  
  6.     operator: Exists  
  7.     tolerationSeconds: 300  ## 300/60=5min  
  8.   - effect: NoExecute  
  9.     key: node.kubernetes.io/unreachable  
  10.     operator: Exists  
  11.     tolerationSeconds: 300 ## 300/60=5min  
  12. ... 

看到這里,Pod 的失效機制已經(jīng)很明白了, 當 node 節(jié)點處于 NotReady 狀態(tài)或者 unreachable 狀態(tài)時,Pod 會容忍它 5 分鐘,然后被驅(qū)逐。而這 5 分鐘內(nèi)就算 Pod 處于 running 狀態(tài),也是無法正常提供服務(wù)的。因此,可以在 yaml 清單中 手動指明 0 容忍,清單文件如下: 

  1. apiVersion: apps/v1  
  2. kind: Deployment  
  3. metadata:  
  4.   labels:  
  5.     app: nginx  
  6.   name: nginx  
  7. spec:  
  8.   replicas: 4  
  9.   selector:  
  10.     matchLabels:  
  11.       app: nginx  
  12.   template:  
  13.     metadata:  
  14.       labels:  
  15.         app: nginx  
  16.     spec:  
  17.       tolerations:  
  18.       - effect: NoExecute  
  19.         key: node.kubernetes.io/not-ready  
  20.         operator: Exists  
  21.         tolerationSeconds: 0  
  22.       - effect: NoExecute  
  23.         key: node.kubernetes.io/unreachable  
  24.         operator: Exists  
  25.         tolerationSeconds: 0  
  26.       containers:  
  27.       - image: nginx:alpine  
  28.         name: nginx 

生成 Pod 

  1. $ kubectl get po -o wide  
  2. NAME                    READY   STATUS    RESTARTS   AGE   IP            NODE         NOMINATED NODE   READINESS GATES  
  3. nginx-84f6f75c6-c76fm   1/1     Running   0          6s    10.244.3.16   k8s-node02   <none>           <none>  
  4. nginx-84f6f75c6-hsxq5   1/1     Running   0          6s    10.244.3.15   k8s-node02   <none>           <none>  
  5. nginx-84f6f75c6-wkt52   1/1     Running   0          6s    10.244.1.63   k8s-node01   <none>           <none>  
  6. nginx-84f6f75c6-xmkjs   1/1     Running   0          6s    10.244.3.17   k8s-node02   <none>           <none> 

接下來強制關(guān)閉 k8s-node02 節(jié)點,查看 Pod 是否轉(zhuǎn)移。 

  1. $ kubectl get po -o wide  
  2. NAME                    READY   STATUS        RESTARTS   AGE    IP            NODE         NOMINATED NODE   READINESS GATES  
  3. nginx-84f6f75c6-c76fm   1/1     Terminating   0          116s   10.244.3.16   k8s-node02   <none>           <none>  
  4. nginx-84f6f75c6-csqf4   1/1     Running       0          13s    10.244.1.66   k8s-node01   <none>           <none>  
  5. nginx-84f6f75c6-hsxq5   1/1     Terminating   0          116s   10.244.3.15   k8s-node02   <none>           <none>  
  6. nginx-84f6f75c6-r2v4p   1/1     Running       0          13s    10.244.1.64   k8s-node01   <none>           <none>  
  7. nginx-84f6f75c6-v4knq   1/1     Running       0          13s    10.244.1.65   k8s-node01   <none>           <none>  
  8. nginx-84f6f75c6-wkt52   1/1     Running       0          116s   10.244.1.63   k8s-node01   <none>           <none>  
  9. nginx-84f6f75c6-xmkjs   1/1     Terminating   0          116s   10.244.3.17   k8s-node02   <none>           <none> 

在 node 節(jié)點轉(zhuǎn)為 NotReady 狀態(tài)后,Pod 立刻進行了轉(zhuǎn)移。這是通過 在 yaml 清單文件中明確指定 容忍時間。還可以直接修改 apiserver 配置來修改默認容忍時間。 

  1. vim /etc/kubernetes/manifests/kube-apiserver.yaml  
  2. ...  
  3. spec:  
  4.   containers:  
  5.   - command:  
  6.     - kube-apiserver  
  7.     - --advertise-address=192.168.1.11  
  8.     - --default-not-ready-toleration-seconds=1    ## 新增行  
  9.     - --default-unreachable-toleration-seconds=1  ## 新增行  
  10. ... 

修改保存后, kube-apiserver-k8s-masterpod 會自動重載最新配置。 

  1. $ kubectl get po nginx-84f6f75c6-wkt52 -o yaml  
  2. ...  
  3.   tolerations:  
  4.   - effect: NoExecute  
  5.     key: node.kubernetes.io/not-ready  
  6.     operator: Exists  
  7.     tolerationSeconds: 0  
  8.   - effect: NoExecute  
  9.     key: node.kubernetes.io/unreachable  
  10.     operator: Exists  
  11.     tolerationSeconds: 0  
  12. ... 

對于小型集群,可以直接設(shè)置全局變量。

注意:當 kubernetes 集群只有一個 node 節(jié)點時,無法做到 Pod 轉(zhuǎn)移,因為 Pod 已經(jīng)無路可退了。 

責(zé)任編輯:龐桂玉 來源: 奇妙的Linux世界
相關(guān)推薦

2023-09-21 11:28:28

Kubernetes云原生

2010-08-20 10:41:20

史玉柱

2020-05-21 08:58:34

Kubernetes操作系統(tǒng)運維

2020-04-28 10:28:30

Kubernetes操作系統(tǒng)運維

2016-01-13 10:10:29

應(yīng)用開發(fā)容器Kubernetes

2020-01-10 17:45:06

Git共享文件開源

2020-11-04 00:00:29

Kerberos協(xié)議身份

2019-01-18 09:32:57

2022-03-03 08:42:10

NodePortServiceKubernetes

2023-12-06 08:48:36

Kubernetes組件

2024-03-01 19:03:14

kubernetesLinuxk8s

2010-05-24 10:23:34

實現(xiàn)MySQL

2022-09-29 10:51:18

ShellLinux命令審計

2021-09-09 17:59:14

AI

2011-08-30 14:29:31

數(shù)字簽名數(shù)字證書

2021-02-19 09:20:04

KubernetesSpark云帳戶

2010-05-25 13:47:53

MySQL 命令

2010-04-16 11:03:02

Oracle存儲過程

2021-02-19 09:33:01

kubernetesJAVA服務(wù)

2022-06-07 16:17:45

KubernetesAPI Schema
點贊
收藏

51CTO技術(shù)棧公眾號