iT邦幫忙

2024 iThome 鐵人賽

DAY 24
1
Kubernetes

Kubernetes圖解筆記系列 第 24

Day-24 Taints & Tolerations

  • 分享至 

  • xImage
  •  

前篇沒有細講的,這篇補上 (。・ω・。)


嗨!這位朋友,吃香菜嗎 ( ´▽` )ノ

https://ithelp.ithome.com.tw/upload/images/20240925/20168437ygkO4YyU5x.png

想像一個聞到香菜味道就皺眉,吃到香菜會崩潰的人看見端上桌的東西長成這樣會有什麼反應。

其實根本就不會看到,這種店他一開始就不會進去。

但對於喜歡香菜無香菜不歡甚至可以單吃炒香菜的人就不一樣了,對吧?
不排斥香菜的人可能也會覺得不妨試試。

TaintsTolerations 就是這樣。

不要亂講

  • Taints
    直譯的意思是污點,是屬於 Node 的屬性,標示了這個屬性的 Node 就像是附加了香菜屬性,對於怕香菜味道的人來說一定是敬而遠之。
  • Tolerations
    意思是忍受力,可以理解成抗性或耐受性,是屬於 Pod 的屬性。就算是添加「 香菜Taints」 的店家(Node),只要 Pod 擁有對應的抗性還是照進不誤,甚至會刻意去嘗試。

設定方式

Taints

設定在 Node 上,使用指令添加。

kubectl taint node <node-name> <key>=<value>:<taint-effect>
# 範例
kubectl taint node node-01 key1=value1:NoSchedule
  • taint-effect

    Taints 的三種機制:
    • NoSchedule:Pod 不在此 Node 上佈署
    • PreferNoSchedule:Pod 盡量避免在此 Node 上佈署 (不保證)
    • NoExecute:Pod 不在此 Node 上佈署,且「移除現存無對應 Toleration」的 Pod

如果要移除 Taint,加上減號-就能移除:

kubectl taint nodes node-01 key1=value1:NoSchedule-

Toleration

Pod 的設定方式則是在 spec 中添加相關設定,範例如下:
(operator 的預設值是 Equal)

  • 對 key=key1, value=value1 的 NoSchedule 有抗性
    tolerations:
    - key: "key1"
      operator: "Equal"
      value: "value1"
      effect: "NoSchedule"
    
  • 對 key=key1 的 NoSchedule 有抗性
    tolerations:
    - key: "key1"
      operator: "Exists"
      effect: "NoSchedule"
    

以上兩種設定 都符合 Taint 範例的設定。

蛤?為什麼?
value 不用一致嗎?

這牽涉到 Toleration 的判斷機制,抗性和污點的對應標準是他們有相同的keytaint-effect
(嘿對,沒有 value)
以 "NoSchedule" 為例:

  • operator 為 Equal,則 TolerationTaintvalue 必須相等
  • operator 為 ExistsToleration 不允許設定 value,只判斷 key

另外有兩種特殊情況:

  1. 如果 key 為空,則 operator 必須要是 Exists,代表只判斷 effect 是否相符,無視所有 Taints 設定的 key 和 value。
  2. effect 為空,則可以與所有包含 key1Taint 對應

完整的 yaml 會像這樣:

apiVersion: v1
kind: Pod
metadata:
  name: pod-nginx
spec:
  containers:
  - name: nginx
    image: nginx
  tolerations:
  - key: "example-key"
    operator: "Exists"
    effect: "NoSchedule"

Kubernetes Scheduler 在篩選 Nodes 時都會評估污點(Taint)和耐受度(Toleration),除非使用者指定了 nodeName
這個行為會使操作跳過調度策略,直接將 Pod 綁定在 Node 上。
即使是 Node 包含 NoSchedule Taint 亦然。

但是,若此時 Node 上存在著 NoExecute Taintkubelet 就會啟動將 Pod 移出 Node。


Kubernetes 允許在 Node 上設定多組 Taint ,也允許在 Pod 上設定多組 Toleration ,判斷方式會是逐筆過濾,當 Pod 有對應抗性則略過,最後剩下的 Taint 所包含的 effect 才會對 Pod 產生影響 。
處理方式如下:

  • 餘下的 effect 中包含 NoSchedule 時,排除該 Node
  • 若除了 effect 中包含 NoSchedule 以外尚有其他 Node 可用,排除 PreferNoSchedule
  • effect 中包含 NoExecute,則將 Pod 移除 (尚未部署則不運行在該 Node 中)

NodePodTaintTolerationEffect 還有各種類型看得眼花?

直接舉個 🌰

在 Node 上設定幾個 Taint

kubectl taint nodes node-01 key1=value1:NoSchedule
kubectl taint nodes node-01 key1=value1:NoExecute
kubectl taint nodes node-01 key2=value2:NoSchedule

另外在 Pod 設定兩個 Toleration(圖中以不同顏色標示)

tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoSchedule"
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoExecute"

https://ithelp.ithome.com.tw/upload/images/20240925/201684375phYtXaDkO.png

經過 Scheduler 判斷後的結果會像這樣:
https://ithelp.ithome.com.tw/upload/images/20240925/20168437tR9rMCkMwK.png
在這個情況下,因為還有一個無法處理的 NoSchedule,還沒有被調度的 Pod 就不會被部署到這個 Node 上。
但若是另一種情境:
https://ithelp.ithome.com.tw/upload/images/20240925/20168437mrBVS7qdyT.png
此時加入新的 NoSchedule Taint
https://ithelp.ithome.com.tw/upload/images/20240925/20168437rrjBKs0xTj.png
則不會影響到原 Pod 的運行
https://ithelp.ithome.com.tw/upload/images/20240925/20168437SpJ7Qt3TT0.png

那如果是被驅除的 Pod 會怎麼樣?

https://ithelp.ithome.com.tw/upload/images/20240925/20168437tjCZXcFjlT.png

此時 Pod 會從這個 Node 上被驅離,然後會分成兩種情況:

  • Pod 就是個單純的 Pod:消失
    Kubernetes 會向 Pod 中的容器發送 SIGTERM,Pod 進行 graceful shutdown 或被 Kubernetes 發送 SIGKILL 強制終止後將相關資源回收。
  • Pod 是由其他元件(如 Deployment 或 StatefulSet)管理:重建
    管理元件會嘗試在其他節點上重新建立服務。

所以說建立管理元件真的很重要。

在很多情況下,Kubernetes 也會用 Taints & Tolerations 機制去管理資源,當系統判斷需將 Node 淨空時自動添加 NoExecute 屬性,當 Node 恢復可用時將該 Taint 移除。

  • node.kubernetes.io/not-ready:Node 尚非可運行狀態
  • node.kubernetes.io/unreachable:node controller 呼叫不到 Node,等同於 Node 狀態為 Unknown
  • node.kubernetes.io/memory-pressure:Node Memory 資源已到臨界點
  • node.kubernetes.io/disk-pressure:Node Disk 資源已到臨界點
  • node.kubernetes.io/pid-pressure:Node 運行過多 PID
  • node.kubernetes.io/network-unavailable:Node 網路不可用
  • node.kubernetes.io/unschedulable:Node 不允許調度
  • node.cloudprovider.kubernetes.io/uninitialized:這是給雲平台使用的 Taint,指 Node 尚未初始化完成。

在預設情況下,Pod 的驅離會立刻被執行。
嗯,預設情況下。
也就是有自訂的空間:tolerationSeconds
當 Pod 添加了這個設定,可以在對應的 Taint 被建立時,延緩被驅離的時間:

tolerations:
- key: "key1"
  operator: "Equal"
  value: "value1"
  effect: "NoExecute"
  tolerationSeconds: 3600

如果在 3600秒 (也就是一小時內)Node 恢復可用(就是對應的 Taint 被刪除),這個 Pod 就不會被驅除。比如當 Node 需要做升級或維護的時候,可以透過 tolerationSeconds 設定讓 Pod 有時間做 graceful shutdown。

其實 Kubernetes 也有在用:
Kubernetes 會自動為 Pod 添加兩個 Tolerationnode.kubernetes.io/not-ready 和 node.kubernetes.io/unreachable,並預設 tolerationSeconds=300
即是在無人為設定的情況下,當 Node 尚未準備完成或 Node controller 無法呼叫到的時候,Pod 會有五分鐘的緩衝時間。


小結

透過在節點上設置 Taints 以及在 Pod 上設置 Toleration,就可以影響或者控制 Kubernetes Scheduler 對 Pod 的調度方式,並更近一步用來實現一些特殊需求,比如:將特定的 Pod 移動到特定的 Node 上、將某些類型的 workload 隔離到特定的 Node 上。不過在調整的時候也需要特別留意,避免 Pod 運行太集中影響 Cluster 平衡,或延伸出資源浪費的議題。


上一篇
Day-23 Scheduling
下一篇
Day-25 nodeAffinity
系列文
Kubernetes圖解筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言