iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 18
0
DevOps

從題目中學習k8s系列 第 18

【從題目中學習k8s】-【Day18】第十題 - Pod Scheduling 2


title: 【從題目中學習k8s】-【Day18】第十題 - Pod Scheduling 2
description: 以無比的恆毅力堅持30天鍊成鐵人--連續30天,一天發表一篇IT技術文章

【從題目中學習k8s】-【Day18】第十題 - Pod Scheduling 2

tags: DevOps CICD K8s Docker

Question

Taint the worker node g8node1 to be Unschedulable. Once done, create a pod called dev-redis, image redis:alpine to ensure workloads are not scheduled to this worker node. Finally, create a new pod called prod-redis and image redis:alpine with toleration to be scheduled on g8node1.

  • key: env_type
  • value: production
  • operator: Equal
  • effect: NoSchedule

概念

這題也是個Pod Scheduling的問題,但是它和我們第一題學的label的方式明顯不同,題目要求我們將g8node1標註為Unschedulable,且第一個Pod不可以被分派到g8node1上,但是第二個創建的Pod卻必須assing到g8node1上,這樣特殊的Scheduling方式要如何辦到呢?就需要依靠K8s中的Taint&Toleration啦~ 按照慣例,我們先來介紹一下這是個甚麼東西吧~

所謂的Taints即是允許Node抵制 (repel) 某些Pod,使Pod無法在該節點上運行
Tolerations則是搭配Taints一同使用,擁有Tolerations的Pod可以被分派到擁有Taints的節點上,但前提是兩者能夠匹配

TaintsTolerations共同使用,以避免將Pod調度到不適合的節點上。一個或多個Taints應用於Node,表示該節點不應接受任何不能容忍TaintsPod

Taints用於NodeTolerations則用於Pod

要使用Taints可以透過kubectl taint指命:

## 新增 taint
$ kubectl taint nodes <node-name> <key>=<value>:<effect>
## 例如
$ kubectl taint nodes g8node1 size=large:NoSchedule
## 刪除 taint
$ kubectl taint nodes <node-name> <key>=<value>:<effect>-
## 例如
$ kubectl taint nodes g8node1 size=large:NoSchedule-

effect欄位是指:當Pod因為此Taint而無法調度到該節點上的時候,該怎麼處理,一共有三種處理方式:

  • NoSchedule
  • PreferNoSchedule
  • NoExcute

後面會介紹這三種的差別

若要讓Pod可以被分派到有taintNode上,則需要宣告Tolerations。下面兩個Tolerations的設定都可以容忍上述例子的taint,因此可被調度到g8node1節點上:

tolerations:
- key: "size"
  operator: "Equal"
  value: "large"
  effect: "NoSchedule"

tolerations:
- key: "size"
  operator: "Exists"
  effect: "NoSchedule"

所有的value都要以雙引號""標註

PodToleration宣告中的keyeffect需要與Taint的設定保持一致,並滿足以下條件之一:

  • operator的值是Exists(無須指定value)
  • operator的值是Equal且value值相等

若無指定operator,則effect預設為Equal

上面的例子使用了NoScheduleeffect,意思是:除非Pod明確宣告可以容忍這個Taint,否則不會被調度到g8node1上。除了NoSchedule外,還可以使用PreferNoScheduleeffect,意思是優先,一個Pod若沒有宣告容忍這個Taint,則K8s會盡量避免把該Pod調度到這個節點上,但不是強制的。

K8s允許在同個Node上設定多個Taints;當然也可以在Pod上設定多個TolerationsK8s調度器處理多個TaintsTolerations的邏輯順序是這樣:首先列出節點中所有的Taints,忽略PodToleration能符合的部分,剩下沒有忽略的Taints就是對Pod的效果了。下面有幾種特殊情況:

  • 若在剩餘Taints中存在effect=NoSchedule,則調度器不會把該Pod調度到此節點上
  • 若在剩餘Taints中沒有effect=NoSchedule,但有PreferNoSchedule,則會試著不把該Pod調度到此節點
  • 若在剩餘Taints中有effect=NoExcute,並且該Pod已經在此節點上運行,則會被驅逐;若沒有在此節點上運行,也不會再被調度到此節點上

TaintToleration是一種處理節點驅逐Pod或讓Pod避開不適合節點的彈性調度方式,常見的使用TaintToleration的應用場景有:

  • 獨佔節點
  • 具有特資源(硬體裝置)的節點
  • 應對節點故障(先將Pod移除,才能對Node做trobleshooting)

有沒有發現我們創建的Pod都不會運行在Control Plane節點上,聰明的你肯定發現原因了!沒錯,就是因為Control Plane節點default都有Taint在上面,因此無法在上面運行Pod哦~
可以用kubectl describe node指令,觀察Control Plane上的Taint欄位資訊~

回到題目,這題就是TaintToleration的應用題型,但值得注意的是,這題只在單一節點上設定Taint是不行的,因為Taint只能確保沒有TolerationPod不會被調度到該Node上,但是不能保證有TolerationPod一定可以被調度到有TaintNode

可能有點繞口,但這兩者是有差別的,你可以想像A,B兩節點,只有A有Taint,B沒有,有一個Pod要啟動,它有A的Toleration,所以它可以在A上運行,但其實它也可以在B上運行,兩者是沒有衝突的

因此,我們需要在每一節點上設置不同的TaintPod才能依照Toleration的設定調度到目標節點上。

其實想要讓某一pod一定運行在某一節點上,在K8s中有更聰明的方法,就是Node Affinity。但是這題限定我們使用Taint&Toleration,而且我們還沒學過Node Affinity,就先這樣吧~

想法如下:

  1. Taint g8node1g8node2
  2. Pod1能容忍g8node2但無法容忍g8node1
  3. Pod2能容忍g8node1但無法容忍g8node2

Answer

首先將g8node1g8node2加上Taint

$ kubectl taint nodes g8node1 env_type=production:NoSchedule
$ kubectl taint nodes g8node2 other_type=development:NoSchedule

創建第一個Pod,讓它無法被調度到g8node1上,那就讓它能容忍g8node2Taint

$ kubectl run dev-redis --image=redis:alpine --restart=Never --dry-run=client -o yaml > q10-1.yaml
$ vim q10-1.yaml
## 加上toleration,如下圖

創建第二個Pod,讓它可以被調度到g8node1上,讓它能容忍g8node1Taint

$ kubectl run prod-redis --image=redis:alpine --restart=Never --dry-run=client -o yaml > q10-2.yaml
$ vim q10-2.yaml
## 加上toleration,如下圖

接著創建這兩個Pod,以kubectl get po -o wide命令即可看見調度的成果

因為我們的集群環境只有兩個節點,所以其實不用這麼麻煩,g8node2根本不用Taint。但是考試時的環境可能不會只有兩個Node,所以建議練習時還是要作完整的考量哦~


結論

今天介紹了K8s中更進階的Scheduling方式--TaintToleration,要特別注意它們的使用時機和各自作用的物件喔~ 好啦,今天就到這囉~ 謝謝大家~

參考資料

Taints and Tolerations

Thank you!

You can find me on

  • george4908090@gmail.com

上一篇
【從題目中學習k8s】-【Day17】第九題 - PV&PVC
下一篇
【從題目中學習k8s】-【Day19】第十一題 - initContainer
系列文
從題目中學習k8s31

尚未有邦友留言

立即登入留言