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