iT邦幫忙

2024 iThome 鐵人賽

DAY 26
0

*只能從 Node 下手嗎?也不一定啦.... (´・Д・)」


前篇介紹了利用標籤(label)為 Pod 和 Node 做對應,以此去限制或調整部署的偏好。
其實,不只是 Node,也可以基於 Node 中運行的 Pod 做判斷喔!

Inter-pod affinity and anti-affinity

nodeAffinity 些微不同,podAffinity 也兩種設定類型可以使用:

  • requiredDuringSchedulingIgnoredDuringExecution
  • preferredDuringSchedulingIgnoredDuringExecution
    其運作方式與 nodeAffinity 一致,就不贅述。

podAffinity 不支援 requiredDuringSchedulingRequiredDuringExecution

Affinity

apiVersion: v1 
kind: Pod 
metadata:  
  name: myapp 
spec: 
  affinity: 
    podAffinity: 
      requiredDuringSchedulingIgnoredDuringExecution: 
      - labelSelector:
        matchExpressions:
        - key: app
          operator: In
          values:
            - backend
      topologyKey: "kubernetes.io/hostname"
  containers:
    - name: nginx-container 
      iamge: nginx

看起來跟 nodeAffinity 差不多啊

格式和邏輯基本上是一樣的。
適用於 Pod 有相依性的場景使用,部署在同一個節點上可以降低延遲,提升運行效率。

比如說:
https://ithelp.ithome.com.tw/upload/images/20240927/20168437bD9t8vwywk.png

Pod 的 設定如下:

affinity: 
    podAffinity: 
      requiredDuringSchedulingIgnoredDuringExecution: 
      - labelSelector:
        matchExpressions:
        - key: app
          operator: In
          values:
            - backend
        topologyKey: "kubernetes.io/hostname"

Pod 必須 與包含標籤:app:backendPod 運行在同一個 Node 上。
所以當然就...
https://ithelp.ithome.com.tw/upload/images/20240927/20168437HgG8SUXl66.png

這時候就出現了一個疑問,如果我有很多選擇呢?

https://ithelp.ithome.com.tw/upload/images/20240927/20168437bJ6CFtKy9j.png
部署的結果會是:
https://ithelp.ithome.com.tw/upload/images/20240927/20168437PryurqO2DR.png
還是:
https://ithelp.ithome.com.tw/upload/images/20240927/201684370QwU5v93tQ.png

... ...誰知道啦哈哈哈哈哈!

雖說單純照圖中的判斷,Kubernetes 可能會判斷右邊的 Node 比較資源比較充裕,所以把待部署的 nginx Pod 綁定上去,但實際上運行的場景複雜得多,誰知道一定會怎麼樣。

如果 Affinity 沒設定好,難保不會發生這種情況...
https://ithelp.ithome.com.tw/upload/images/20240927/20168437d90z610bun.png
也不說不行... 但萬一有個 Node 壞掉,上面的整套系統也就跟著掛了。
比較理想的情況應該是這樣:
https://ithelp.ithome.com.tw/upload/images/20240927/20168437LvvNVvl0JK.png

這時候排除邏輯就派上用場啦!

anti-affinity

為了達到將平均分散在 Cluster 中的效果,需增加兩個部署條件:

  • tier:backend:避開已經部署過同一套系統 tier:backend 的 Node
  • tier:nginx:邏輯同上

設定方式:

  • nginx Pod (system-1)
    affinity: 
        podAffinity: 
          requiredDuringSchedulingIgnoredDuringExecution: 
          - labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
                - system-1
            - key: tier
              operator: In
              values:
                - backend
            topologyKey: "kubernetes.io/hostname"
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
    	     matchExpressions:
    	     - key: app
                operator: In
                values:
                  - system-1
              - key: app
                operator: In
                values:
                  - nginx
              topologyKey: "kubernetes.io/hostname"
    

podAffinity:與包含 app:system-1tier:backend 的 Pod 運行在同一個 Node 上
podAntiAffinity:避開已經運行 app:system-1tier:nginx Pod 的 Node

  • backend Pod (system-1)
    affinity: 
        podAffinity: 
          requiredDuringSchedulingIgnoredDuringExecution: 
          - labelSelector:
            matchExpressions:
            - key: app
              operator: In
              values:
                - system-1
            - key: tier
              operator: In
              values:
                - nginx
            topologyKey: "kubernetes.io/hostname"
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
    	     matchExpressions:
    	     - key: app
                operator: In
                values:
                  - system-1
              - key: app
                operator: In
                values:
                  - backend
              topologyKey: "kubernetes.io/hostname"
    

以此類推做設定,就可以確保 backendfrontend 在同一個 Node 上,又不會相同系統全都擠在一起了!

概念是這樣啦...

理想很美好但現實很骨感。
官方文件有特別提醒:
podAffinitypodAntiAffinity 邏輯需要大量的處理,若 Cluster 中運行的 Pod 數量很多,會明顯減慢 Kubernetes 的調度效率,如果 Cluster 中運行著逾百個 Node,請不要使用這個調度設定。

podAffinity可用的設定邏輯:

Affinity Operators

  • In:包含符合的 key-value
  • NotIn:排除符合的 key-value
  • Exists:包含符合的 key-value
  • DoesNotExist:排除符合的 key

podAffinity 不支援 Gt(大於)和 Lt(小於),這兩個邏輯只能在 nodeAffinity 使用。

另外補充幾個設定:

  • topologyKey
    定義 podAffinitypodAntiAffinity 的生效層級,是必要設定值。
    除了 hostname,另外還有 zoneregion
    範圍大小: hostname < zone < region
  • weight:權重
    只有在 preferred 規則中使用,為必要設定值,用於定義多個偏好之間設置優先級。
    設定範圍 1~100,數字越大權重越高。

小結

目前提到的調度策略,包含 Taints & TolerationsnodeAffinitypodAffinity 都是可以同時使用的。它們是三種不同的調度機制,每一種機制用來解決不同的需求。這三者可以互相協作來提供更靈活的調度策略,不過也須留意別讓配置過於複雜,導致難以維護跟偵錯。


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

尚未有邦友留言

立即登入留言