整理 Pod 的十種方式
早安,這是一個關於 Kubernetes 的文章,如果你不知道 Kubernetes 是什麼,建議先去看一下官方文件,另外本文會搭配 GKE 使用。
方法一 什麼都不管,雜成一鍋粥
- 說明:把所有的 pod 都放在同一個 node 或 node pool 裡,自動擴展開起來,方便又省事
- 優點:方便快速,菜雞工程師都這麼幹
- 缺點:混亂
方法二 指定 node pool (指定 node)
-
說明:
- 如果用的不是 GKE,可能沒有 node pool,如果是拿一般機器建,可能是直接指定 node
- GKE 直接指定 node 的風險很高,因為 GKE 很常莫名回收掉你的機器,建議指定 node pool
-
方式:
nodeSelector:
cloud.google.com/gke-nodepool: pool-backend
-
優點:
- 容易操作
- 很好預測 GKE 的行為
- 可以指定特定的服務使用特定規格的機器
-
缺點
- 不能將 pod 的 replica 分散
- 如果要為每個服務細分機器規格,那口袋要有點深度
方法三 設定互斥(強互斥)
-
說明:
- 文件好像是寫「親和性」與「反親和性」
- 要求特定 Pod 不要跟某些 label 的 Pod 放在同一個 node
-
方式
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "app.kubernetes.io/name"
operator: In
values:
- backend
topologyKey: "kubernetes.io/hostname"
-
優點:
- 可以拆散 pod 的 replica 讓他們分佈在不同的 node 上
- 也可以拆散某些服務,讓他們不會一起出現在同一個 node 上
-
缺點
- code 又臭又長,設定當下要讀十分鐘的文件,三個月後的自己可能都看不懂
- 多個互斥疊加的時候,不好預測會發生什麼事
- 想像一下:你在安排員旅房間,只有兩間雙人房。A 討厭 B ,B 跟 D 互相討厭,C 討厭所有人,A 先住進房間 1 。接下來要怎麼安排。
- node 可能會不夠用
- 假設機器只有 2 臺,但是 Pod A 有 3 個 replica ,且 Pod A 彼此不能在同一臺機器。第 3 個 Pod A 就會起不來
方法四 設定相吸(強相吸)
-
說明:
- 可以互斥,就可以相吸,這個是互斥的相反
- 優缺點亦同,不多做解說
-
方式
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- backend
topologyKey: "kubernetes.io/hostname"
方法五 驅逐多餘的 pod(汙點與容忍)
-
說明:
- 為 node 設下結界,把它看不上的 pod 通通驅逐
- 可以讓某個 node 不能佈署它指定的 pod
- 可以佈署在上面的 pod 一定是被 node 選中的 pod
-
方式
- GKE 的話,要在 GKE 的頁面上設定,而且是以 node pool 為單位(當然,你也可以用 terraform 或 gcloud 設定)
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
-
如果要讓 Pod 可以被佈署到這臺 node 上,就要在 pod 上寫
tolerations:
- key: "job"
operator: "Equal"
value: "true"
effect: "NoSchedule"
-
優點
- 不用再為每個 pod 都設定上 nodeSelector ,也不用擔心有迷途的 pod 誤入特定 node
- 簡單就可以掌握一臺機器會出現哪些 pod
-
缺點
- GKE 的話,設定界面在 GKE 上,三年後的自己可能會忘記當時設定了什麼
- 不符合直覺,而且很隱晦。第一次看到的人可能不會知道原來某臺機器不接受其他的 pod
方法六 勉強互斥(弱互斥)
-
說明:
- 雖然我討厭你,但是在不得已的情況下,我們還是可以住在一起 — by Pod A 對 Pod B 的告白
- 設定上,Kubernetes 會優先選擇符合條件的 node,但是沒有符合條件,還是會佈署
-
方式
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/name: backend
topologyKey: kubernetes.io/hostname
-
優點
- 就算 node 不夠用,也不用擔心 pod 會建立不起來
- 為互斥增加了彈性
-
缺點
- 他的 code 跟設定互斥的 code 長得超像
- 存在模糊地帶,更不容易預測 pod 的分佈
方法七 勉強相吸(弱相吸)
- 說明:
- 有互斥,就有相吸,這段是來充字數的
- 優缺點亦同,不多做解說
方法八 調整濃度(拓撲傳播約束)
-
說明:
- 跟勉強互斥自己的 replica 設定雷同,你可以設定特地 pod 在多個 nodes 間的濃度
-
方式
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
- matchLabels:
app: nginx
maxSkew
表示能容忍的 pod 數量差異,設定為 1 代表只容忍差異為 1 個 pod
whenUnsatisfiable
設定當不滿條件下,要如何行動,DoNotSchedule
代表保持 Pending (意同相斥),ScheduleAnyway
代表管他的,就是要佈署(意同勉強相斥)
-
優點
- 為勉強互斥又增加更多的彈性
-
缺點
- 預測 Pod 的分佈越來越像在通靈了
方法九 組合拳
- 說明:
- 例如:把方法二的指定 node 跟方法五的驅逐多餘的 pod,一起用的話,就可以製造一臺專屬某個 pod 的 node ,而且那個 pod 不會像變了心的女友一樣,突然就跑到別的 node 串門子
- 優點:
- 靈活性高,是個一般人,都會想到這麼做
- 缺點:
- 複雜度變大,管理成本變高
方法十 還是把那些藩籬通通打掉吧
- 說明:
- 當你費盡心思,結合上面的方法,把所有的 pod 都安排的妥妥當當,明明白白,結果因為機器開太多,所以帳單爆炸貴。老闆詢問:我們要不要把一些 pod 整併到其中一臺 node 裡?
- 當你好不容易把 pod 整併進去,但是某天一個斷電,那個 node 剛好死掉,然後服務就掛了。老闆詢問:我們還是開兩臺 node 互相 cover 好了。
- 當你好不容易把 pod 設定好 replica 然後把互斥設定都處理好了。老闆詢問:這兩個服務的資源競爭很嚴重,好像會互相影響,要不要把他們分開來?
- 歷史總是輪迴的,讓我們回到說明 1
- 最後,我們到底為什麼要設定這些東西,把 pod 從東邊搬到西邊,再搬到東邊呢?混在一起做撒尿牛丸不好嗎?
- 於是你把阻斷 pod 在 node 間穿梭的高牆推倒,只留下一個 node pool ,並且設定自動擴展
- 優點:方便快速,大神工程師都這麼幹
- 缺點:
混亂(什麼混亂,這是美學 (´ _ > `) ,沒看過下面這張圖嗎?)
