iT邦幫忙

2024 iThome 鐵人賽

DAY 25
0
Kubernetes

Kubernetes圖解筆記系列 第 25

Day-25 nodeAffinity

  • 分享至 

  • xImage
  •  

有排斥的設定那有沒有偏好設定?有! \(^o^)/


在部署 Pod 的時候,除了使用 TaintsTolerations 設定避免 Pod 被部署到不適合的 Node 上,也可以透過偏好設定讓 Pod 優先在特定的 Node 上運行。

有幾種方式:

  • nodeName
  • nodeSelector
  • Affinity & Anti-affinity
  • Pod topology spread constraints
    (後兩種與 Pod 相關的會分篇說明)

nodeName

由 Pod 去指定要部署的 Node。
設定方式:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
  nodeName: <要部署的 node name>

前篇也有提到,使用這個方式會有些風險。

nodeName 的設定會使部署繞過所有策略,直接將 Pod 部署在設定的 Node 上。
就算該 Node 包含 Taints 也一樣。

那我都沒在使用 Taints ,是不是就適合 nodeName 設定?

欸... 也不是這樣。
Taints 不是只有使用者在使用,Kubernetes 也會因為調度需求而在 Node 上自動設定/移除 Taints 。若使用 nodeName 指定部署 Node,又遇上 Node 屬於不可用或資源不足狀態時,就會造成 Pod 部署失敗。

那 nodeName 用在哪裡?
通常會用在偵錯或測試階段,需要在指定 Node 上執行的時候;或是 Cluster 只有一個 Node 時,也不會產生負面影響。

那有沒有更彈性的方法?

有的!可以使用 nodeSelector

nodeSelector

由 Pod 去選擇要部署的 Node。

蛤?聽起來跟前面一樣啊?

同款不同師傅啦 (。・ω・。)
Node 名稱是不可重複的,nodeName 設定是直接指定要部署的 那一個 Node,但 nodeSelector 的判斷標準是標籤 (Label),而標籤,可以重複使用,還可以設定多組。

打個比方,今天使用 Node 的資源配置去設定標籤。
設定指令:

kubectl label nodes <node-name> <key>=<value>
#範例
kubectl label nodes demo-01 size=large

標籤好的 Node 像這樣:
https://ithelp.ithome.com.tw/upload/images/20240926/20168437Sd123iP3zm.png

當 Scheduler 接到新的 Pod 需要部署:

apiVersion: v1 
kind: Pod 
metadata: 
  name: myapp 
spec: 
  containers: 
    - name: nginx-container 
      iamge: nginx 
  nodeSelector: 
    size: large

https://ithelp.ithome.com.tw/upload/images/20240926/20168437PRLhOyPcxA.png

https://ithelp.ithome.com.tw/upload/images/20240926/20168437EVhQAuir48.png
https://ithelp.ithome.com.tw/upload/images/20240926/20168437woMM7sAKa8.png
擁有對應的標籤才會被選擇。
若有多組設定,條件之間則為 AND 邏輯,Node 需要 全部 都符合才會被選擇。

當有多個 Node 符合 selector 條件會怎麼樣?

Scheduler 會綜合考量其他因素,最終選定要部署的 Node。
可參考前篇:Scheduling

萬一沒有任何一個 Node 符合 selector 又會怎麼樣?

Pod 將會無法部署,一直保持在 pending 狀態直到有符合條件的 Node 出現。

就這樣卡住也不是辦法啊!沒有什麼好方法嗎?

有啊有啊,本篇的主角:nodeAffinity

nodeSelector 設置簡單,但只能處理=邏輯,且一旦沒有對應到的 Node 就會部署失敗。
如果需要更有彈性的設定,可以使用 nodeAffinity
相較於nodeSelector

  • nodeAffinity 的表達功能更強,可處理邏輯更豐富。
  • 可以明定規則為必須遵循或者是偏好,提供沒有對應 Node 時仍可以成功部署的空間。

Affinity 包含兩種類型:Affinity & anti-affinity
在 Node 的操作會使用的是 nodeAffinityanti-affinity 的邏輯則是透過 Taints & Tolerations 實現
(官方文件的 anti-affinity 是全小寫,就依循使用了。)

Affinity

概念上類似於 nodeSelector,但是支援更複雜的邏輯判斷。
Affinity 主要使用類型:

  • requiredDuringSchedulingIgnoredDuringExecution
    重點在 required,當 Scheduler 有找到符合條件的 Node,才執行 Pod 的調度。。
  • preferredDuringSchedulingIgnoredDuringExecution
    preferred,當有符合條件的 Node,會優先調度。但是當無 Node 符合 Pod 設定,Scheduler 仍會找尋其他 Node 來部署。

IgnoredDuringExecution:
只要 Pod 已經部署到 Node 上,即便 Node 的標籤產生異動,也不影響 Pod 繼續運行。

整段一起看的話:DuringSchedulingIgnoredDuringExecution
其實就是這個設定條件在調度期間才有效,運行中則忽略。

另外還有一種比較特別的設定:

  • requiredDuringSchedulingRequiredDuringExecution
    Pod 必須 要運行在對應標籤的 Node 上,若是運行中 Pod 或是 Node 標籤發生異動,則 Pod 會被驅除,可能會刪除或是重新部署(取決於 Pod 上層是否有管理元件)。

設定方式:

apiVersion: v1 
kind: Pod 
metadata:  
  name: myapp 
spec: 
  affinity: 
    nodeAffinity: 
      requiredDuringSchedulingIgnoredDuringExecution: 
        nodeSelectorTerms:
          - matchExpressions: 
            - key: size
              operator: In
              values: 
                - large
                - medium 
  containers:
    - name: nginx-container 
      iamge: nginx

超級長一串,其實就是這樣:
當 Node 包含 size=large 或 size=medium 標籤時,才可選為可用 Node。
https://ithelp.ithome.com.tw/upload/images/20240926/201684374RjZ0874hu.png

想到就再提一下

注意!Kubernetes 大多數的配置都是大小寫敏感的,包含標籤。
所以在上述範例中,如果 Node 的標籤是 size=Large 或 size=Medium,是 不符合 比對條件的喔!

在 Kubernetes 中雖不存在 nodeAntiAffinity,但是可以用 nodeAffinityNotIn 屬性來達到類似的效果:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: NotIn
            values:
            - ssd
  containers:
  - name: my-container
    image: nginx

這個設定就可以將 disktype=ssd 的 Node 排除囉!

最後補充Affinity可用的設定邏輯:

Affinity Operators

  • In:包含符合的 key-value
  • NotIn:排除符合的 key-value
  • Exists:包含符合的 key-value
  • DoesNotExist:排除符合的 key
  • Gt:對應 key 的 value 需大於設定值
  • Lt:對應 key 的 value 需小於設定值

小結

nodeAffinity 是 Kubernetes 中富有彈性的調度機制,用來控制 Pod 被分配到特定的節點上。藉由nodeAffinity,使用者可以根據 Node 的規劃和特性去定義標籤,以確保 Pod 被調度到它該去的地方。


上一篇
Day-24 Taints & Tolerations
下一篇
Day-26 podAffinity
系列文
Kubernetes圖解筆記26
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言