DevOps: Where is My PodPod — Pod Arrangement

smalltown
smalltown
Sep 28 · 12 min read
Image for post
Image for post

Background

這次在 iThome 舉辦的 Kubernetes Summit 有幸可以上台分享,嘗試將 K8S 世界裡維運的所有動作都一對一且映成到牧場管理上,內容雖然簡單易懂,不過由於時間的關係,所以將牧場情境對應回真實 K8S 使用案例的敘述不太完整,因此透過離線文章的撰寫來進行一些補充XD 而這篇的內容會先以 Pod Arrangement 為主,假如還有下一篇的話,就會將重點擺到 Resource Management 上 ==+

Image for post
Image for post

Pet vs Cattle

此概念差不多在 4,5 年前於 DevOps 領域被提出來,主張大家在維運應用服務的方式,應該要像飼養家畜一般,有哪個應用服務出問題,應該要有辦法立即將其替換掉,而不應該像家裡養的寵物不可替代性這麼高 ;照顧寵物方式對應到日常工作就好像是手動 GUI 操作,需要發 Ticket 請 Operation 的人幫忙替你執行任務,遇到流量變大只能將機器開的更大…等,飼養家畜對應過來就是凡事都可以透過 API 操作,很多事情都可以自動化完成,流量變大的時候應該可以透過多開機器輕鬆解決…等

Image for post
Image for post

Kubernetes 整個核心概念其實就可以讓你的應用服務像是家畜一般地活著,例如今天某個 Pod 或是某個節點遇到不預期的問題時,讓 Pod 重新產生,或是把節點替換掉,都是很正常且日常會發生的行為,所以使用了 Kubernetes 就可以放鬆什麼事情都不用做了嗎?當然不是,既然說使用 Kubernets 像是在飼養家畜一樣,那我們就來看看管理一個牧場需要做什麼事情?例如需要負責幫忙牛隻的生產,準備草地給牛吃飯,避免牛隻跑到錯誤的草地…等,在完成這些工作任務之間一定會遇到不少的問題

Image for post
Image for post

因此當把等同於家畜的應用服務運行在 K8S 中時,是不是也會遇到一樣的問題?答案當然是肯定的?例如 Pod 一直處於 Pending 的狀態 (小牛難產生不出來),Node 呈現 Not Ready 的狀態 (新的草地準備不出來),Pod 跑到你不希望他去的 Node (某些牛跑錯地方吃草)

Image for post
Image for post

聽完上面的敘述有沒有發現使用 K8S 的你/妳其實跟在管理牧場並沒有什麼兩樣,從前用來戲謔工程師的詞彙,如今好像想賴也賴不掉了XD 那麼底下就開始我們這篇文章的重點,如̸何̸讓̸牛̸隻̸走̸到̸他̸該̸去̸的̸草̸地̸上̸吃̸草̸,如何讓 K8S Pod 可以運行在正確的 K8S Node 上!

不過在開始進入文章重點前,先把下面會用到的一些圖示稍微簡單說明一下,土地用來類比 K8S Node,而不同種的土地就代表著不同的 K8S Node,例如在不同的 Zone,硬體資源…等;而家畜羊,豬,牛就代表著不同的應用程式 K8S Pod ,而且會使用不同的樣貌來比喻 Pod 正在 Running, Starting, Pending 跟 Terminating…等

Image for post
Image for post

而在文章的一開頭就有提到,這裡想要談到的是有關 Pod Arrangement 的議題,為什麼會需要在意這個呢?不是讓 K8S 的 Scheduler 挑選還有餘裕的 Node 並且把 Pod 放上去運行就好?!不過現實環境當然沒有那麼的單純,常見的情況有三種:1) 某些 K8S Node 是特地準備給特定應用程式運行的 2) Node 上有特殊的硬體資源,譬如說高階顯卡 3) 有的節點平常是不隨便給任意 Pod 隨便使用的,因此 K8S 隨著版本不斷的更新也開始加入越來越多的功能來滿足以上提到的需求

Node Selector

Image for post
Image for post

Virtual Farm

假設今天要把牛 (Pod) 放到綠意盎然的草地 (Node),那麼就可以在土地 (Node) 加上這裡是草地的告示牌 (K8S Node Label),接著讓牛隻默默地走進去吃草即可

Real Use Case

nodeSelector 算是 K8S 在 Pod 分配功能中最早被提出來的,只要 Label 加得妥當,便可以將 Pod 如使用者所願的分配到特定的節點上,例如把 Pod 放到某個 Zone 裡的 Node ,或是有特殊硬體的資源上,某個作業系統版本…等;Label 可以事後加,也可以在 Node 一產生的時候就自動加好,除此之外,K8S 其實也會自動幫節點加上不少的 Label,在自己動手要加之前,可以先參考看看,搞不好預設的就已經夠用了也說不一定

Node Affinity

Image for post
Image for post
Image for post
Image for post

Virtual Farm

假設今天有好幾塊草地 (Node),但是上面長的草不太一樣,我們養的牛 (Pod) 喜歡吃牧場1 跟牧場2 的草 (在第一張圖使用的是 required 語法,第二張是 prefreed 語法),所以假如牧場1 跟牧場2還有空間可以容納牛隻,那麼就可以把牛繼續趕進去,假如兩個牧場都滿了的話,使用 required 語法的意思就是說老子只吃這兩個牧場的,其他的我餓死也不要吃XD preferred 的牛就比較隨和一些,把它放到牧場3 也還是可以吃得很開心

Real Use Case

可以看到 Node Affinity 的功能彈性很多,除了可以用 operator (In, NotIn, Exists, DoesNotExist, Gt, Lt) 達成多種操作之外,更可以透過 required/preferred 兩種不同的方式來讓 Pod 在無法找到滿足條件 Node 的情況之下,仍然可以有運行的機會;例如今天有一個應用程式需要比較好的 CPU 等級才可以跑得平穩,就可以用 Operator In 選擇某些特定型別的機器,但同時希望找不到時還是可以加減運行的話,就可以使用 preferred 的語法

Taint

Image for post
Image for post

Virtual Farm

上面提到都是從牛 (Pod) 的角度去做正面選擇,接下來反過來從土地 (Node) 的角度出發,假設今天某塊土地 (Node) 都是泥土不希望有牛跑過來,所以就立下都是泥土不要過來的警告標示立牌,所以牛 (Pod) 看到就不走過去了,而是跑去正常的草地 (Node)

Real Use Case

其實這個 Taint 功能我最一開始接觸到是在 Master Node 上,因為整個 K8S Cluster 會希望 Master 可以專心運行 Control Plane 就好,因此就會加上 Taint,讓一般的應用程式不會被分配到 Master Node;假如某些 Node 有重要且昂貴的運算資源,不希望被一般應用程式拿來使用,導致真正需要的程式使用不到,就是使用 Taint 功能的最佳時機點

Toleration

Image for post
Image for post

Virtual Farm

看過佩佩豬的人應該都知道豬 (Pod) 喜歡玩泥巴,所以假如今天走過來的是豬 (Pod),那麼他看到泥巴的警告標語將會視若無睹地走進去泥巴地 (Node) 大玩特玩

Real Use Case

其實這就是 Taint 的反面用法,在 Pod 裡面定義可以容忍 (Toleration) 的條件,那麼該 Pod 就可以被分配到該種 Node 上,所以就像上面提到的,通常下了 Taint 的 Node 就是有其特殊用途,使用 Toleration 便可以讓 Pod 跑到這些已經下了 Taint 的 Node 內享用位於其上的運算資源

Inter-Pod Affinity

Image for post
Image for post

Virtual Farm

看完了家畜 (Pod) 跟土地 (Node) 之間的恩恩怨怨之後,讓我們更進一步的把家畜間 (Inter-Pod) 的愛恨情仇也加進來看來看XD 假設我們照顧的牛群 (Pods) 個性都很像,很喜歡做一樣的選擇,例如今天某隻牛 (Pod) 選擇去草地 (Node),其他的牛群 (Pods) 就會跟他做出一樣的選擇,反之亦然,假如第一隻牛 (Pod) 選擇了泥巴地 (Node),其他的牛群 (Pods) 就會選泥巴地 (Node)

Real Use Case

Inter-Pod 的 Affinity 設定上有三個屬性需要注意:

  1. labelSelector: 此 Label 是 Pod 所擁有的 Label,而不是 Node,例如選擇 Label 等於牛,就表示這個設定會套用在牛群身上
  2. topologyKey: 則是指用來散佈這些被挑中 Pod 的 Node,例如:位於同一個 Zone 中的 Node,使用同樣作業系統的 Node …等
  3. required/preferred: 跟上面 Node Affinity 一樣,也是可以分成必要偏好兩種選擇

自己最常用到的就是希望運行某些應用程式的 Pod 可以散佈在同一個 Zone 當中,為什麼會想要這麼做呢?因為在同一個 Zone 享有更低的網路延遲,還有不會被收取傳輸費用的優點,所以假如某些應用程式間溝通的流量很驚人,而且對於速度變化很敏感的話,就可以利用 Inter-Pod Affinity 將它們放到同一個 Zone 當中;或是某些應用程式一定要在同一台 Node 內運行也可以使用此功能

Inter-Pod Anti-Affinity

Image for post
Image for post

Virtual Farm

假設今天某些牛 (Pod) 生病了,希望讓他們開始過防疫新生活,每隻牛都選擇不一樣的土地 (Node),避免他們靠太近而互相傳染疾病

Real Use Case

Inter-Pod Anti-Affinity 剛好跟上面相反,希望的是被選到的 Pod 可以在規定的 topologyKey 下做不一樣的選擇,例如 topologyKey 是 Host 好了,那麼 Pods 就會開在不同的 Node 上,或是讓 Pods 分配在不同的 Zone 達成備援機制;一般具有 Cluster 機制的應用程式都應該要使用到才對,例如讓 ElasticSearch 的 Data Node 分散在不同的 K8S Node 以達成 Redundancy,MySQL, Redis 的 Primary, Secondary Node 分散在不同的 Zone, 避免當一個 Zone 壞掉時,整個資料庫或是快取功能就無法正常使用

PodTopologySpread

Image for post
Image for post
Image for post
Image for post

Virtual Farm

讓感情好意見相同的牛群 (Pods) 到一樣類型的土地 (Node) 是沒有什麼問題,但是農場主人不希望他們都擠在同一塊土地 (Node) 上面,所以要是有牛 (Pod) 一直往某塊地 (Node) 走過去吃草時,就會適時地將他驅逐到另外一塊草地 (Node)

Real Use Case

有在維運 K8S Cluster 的人應該常常會遇到這樣的問題,就是 Pod 不知道為什麼有時候會集中在同一個 Node 上,假如不是同一個應用服務就還好,但要是都屬於同一個應用服務的話,那就表示該服務會不具備 HA 機制,所以 K8S 在比較後期的版本推出 PodTopologySpread 這個功能,這個功能的設定中最容易讓大家混肴的便是 maxSkew 這個屬性 (Pod 放到某個 Node 後,此 Node 具有該種 Pod 的個數 — Cluster 中具有最少該種 Pod 數目的 Node),所以讓我對這個屬性做更詳細的解釋 (就用上面的圖),至於其他的屬性則可以參考官方文件

  • 假設牛 (Pod) 打算去左邊的草地 (Node),那這塊草地 (Node) 就有 3 隻牛 (Pods),而整個農場最少牛 (Pod) 的就是右邊的草地 (Node),連一隻都沒有,所以 Skew 就是 3 — 0 = 3
  • 假設牛 (Pod) 打算去右邊的草地 (Node),那這塊草地 (Node) 就有了第一隻牛 (Node),而整個農場最少牛的就是這塊草地,因為只有剛走過來的一隻,所以 Skew 就是 1 — 1 = 0
  • 而根據 maxSkew 設定值為 1,所以第二個選擇才符合條件,沒有超過 1,因此新來的牛隻 (Pod) 會被驅趕到右邊的草地 (Node)

Conclusion

從一開始 Kubernetes 只有 Node Selector,後來多了 Taint & Toleration,Node Affinity, Inter-Pod Affinity & Anti-Affinity,一直到最新的 PodTopologySpread,在 Pod 的分配機制上多了不少的選擇,符合了大多數人的需求,讓 Pod 更能夠適得其所!

不過官方有提到假如 Cluster 中 Node 超過百台的話,會建議 Affinity 跟 Topology 的功能少用,因為可以發現在做選擇的當下其實會耗損到 Scheduler 的運算資源,因此當 Node 個數太大的話,將會成為分配 Pod 到 Node 效能上的 Bottleneck T_T 文章就先寫到這邊,希望透過此種方式可以讓大家輕鬆地理解這些有點複雜的 Pod 分配功能 ^^

Reference

Starbugs Weekly 星巴哥技術專欄

一群技術人想寫出一些好文章,所建立的技術專欄。每週二會發佈技術週刊,分享科技新知,歡迎大家訂閱…

smalltown

Written by

smalltown

原來只是一介草 QA,但開始研究自動化維運雲端服務後,便一頭栽進 DevOps 的世界裏,熱愛鑽研各種可以提升雲端服務品質及增進團隊開發效率的開源技術

Starbugs Weekly 星巴哥技術專欄

一群技術人想寫出一些好文章,所建立的技術專欄。每週二會發佈技術週刊,分享科技新知,歡迎大家訂閱 https://weekly.starbugs.dev/。

smalltown

Written by

smalltown

原來只是一介草 QA,但開始研究自動化維運雲端服務後,便一頭栽進 DevOps 的世界裏,熱愛鑽研各種可以提升雲端服務品質及增進團隊開發效率的開源技術

Starbugs Weekly 星巴哥技術專欄

一群技術人想寫出一些好文章,所建立的技術專欄。每週二會發佈技術週刊,分享科技新知,歡迎大家訂閱 https://weekly.starbugs.dev/。

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store