作者:Daniel Weibel

翻譯:Bach(才雲)

上篇文章《搭建叢集時,要如何選擇叢集大小》詳細描述了搭建叢集時,大小叢集兩種選擇各自利弊之處。當我們選擇搭建其中一種 K8s 叢集時,腦海中可能還會冒出這樣一個問題,我應該使用哪種型別的工作節點?需要多少個這樣的節點?

換個場景,如果是內部部署 K8s 叢集,我們是應該訂購一些新伺服器,還是用資料中心裡的那十幾臺舊機器,亦或者我們選擇 Kubernetes 託管服務,那要使用八個

n1-standard-1

例項還是兩個

n1-standard-4

本文從多個維度闡述了使用少數大型節點和多個小節點搭建 K8s 叢集時各自的優劣,希望可以為大家解決上述問題提供參考。

叢集容量

通常 Kubernetes 叢集可以被視為由一組單個節點組成的“超級節點”。該超級節點的總計算容量(就 CPU 和記憶體而言)是所有組成節點容量的總和。假設現在需要一個總容量為 8 個 CPU 核心和 32GB RAM 的叢集。以下是設計叢集的兩種方法:

搭建叢集時,要如何選擇節點大小?

這兩個選項都會產生具有相同容量的叢集,一個使用 4 個較小的節點,而另一個選擇使用 2 個較大的節點。哪個更好?為了解決這個問題,讓我們來看看“少數大節點”和“多個小節點”這兩個相反方向思路的優缺點。

本文中的“節點”指的是工作節點(worker node)。主節點的數量和大小的選擇是其他問題。

使用少數大節點

這種選擇最極端的情況是僅使用一個可以提供整個叢集所需容量的工作節點。如果要滿足上述例子中的容量需求,那就是一個具有 16 個 CPU 核心和 16GB RAM 的單個工作節點。這種方法有什麼優勢呢?

管理成本低

簡單而言,管理少量機器比管理大量機器來的輕鬆。我們可以更快的完成應用更新和補丁,機器也更容易保持同步。另外,機器數量少的話,預期故障也肯定比機器多的時候少。但請注意,這主要適用於裸機伺服器而不適用於雲實例。如果使用雲實例(作為託管Kubernetes服務的一部分或在雲基礎架構上安裝的Kubernetes),會將底層機器的管理外包給雲提供商。因此,管理雲中的 10 個節點並不比管理雲中的單個節點成本多得多。

每個節點的成本更低

雖然好的機器會比低端機器更貴,但二者價格不一定是線性的。換句話說,一臺具有 10 個 CPU 核心和 10GB RAM 的機器可能比 10 臺僅有 1 個 CPU 核心和 1GB RAM 的機器便宜。

這裡要注意,如果是雲實例,情況可能會不太一樣。因為在目前的主要的雲提供商定價方案中,例項價格是隨著容量線性增加的。例如, 64 個

n1-standard-1

例項與單個

n1-standard-64

例項都提供 64 個 CPU 核心和 240GB 記憶體,價格也是一樣的。在雲上,我們一般沒法透過使用更好的機器來節省成本。

允許執行資源消耗較大的應用程式

大型節點可能是在叢集中執行某種應用程式的必須要求。如果有一個需要 8GB 記憶體的機器學習應用程式,我們可以在一個具有 10GB 記憶體節點的叢集上執行它,但具有 10 個 1GB 記憶體節點的叢集就不行。

看過大型節點的優勢後,讓我們再來看看其弊端又是什麼。

節點上的 Pod 太多

在少量節點上執行相同的工作負載,這意味著每個節點上需要執行更多的 Pod。這是個問題,因為每個 Pod 都會在節點中執行的 Kubernetes 代理上引入一些東西,例如容器執行時的 kubelet 和 cAdvisor。

kubelet 會對節點上的每個容器執行常規活動和就緒檢測,這意味著在容器越多,每次迭代 kubelet 就做更多的工作。cAdvisor 收集節點上所有容器的資源使用統計資訊,kubelet 會定期查詢此資訊並透過 API 釋出。這意味著每次迭代 cAdvisor 和 kubelet 的工作量都會很大。如果 Pod 數量很多,上面這些東西就會拖慢系統速度,甚至使系統出現各種問題。

搭建叢集時,要如何選擇節點大小?

有報告稱,因為 kubelet 花費太長時間對節點上的容器進行執行狀況檢查,導致節點處於非就緒狀態,所以 Kubernetes 建議每個節點上不要超過 110 個 Pod。這個 Pod 數是 Kubernetes 透過測試,一般節點可以正常工作的數量。我們現在雖然可能在每個節點上可以成功執行更多的 Pod,但很難預測後面是否會遇到問題。大多數 Kubernetes 託管服務都對每個節點的 Pod 數量進行了嚴格的限制。如果要在節點上執行大量 Pod,一定要事先測試能否正常工作。

複製程度有限

節點數量少可能會限制應用程式的有效複製。如果有一個由 5 個副本組成的應用程式,但我們只有 2 個節點,那麼該應用程式的有效複製程度將減少到 2。這是因為此時 5 個副本只能分佈在 2 個節點上,如果其中一個失敗,那它可能會同時刪除多個副本。但如果有至少 5 個節點,那理想情況下每個副本可以在單獨的節點上執行,並且單個節點出現故障最多隻會刪除一個副本。因此,如果有高可用性需求,那叢集中的最小節點數就要有一定要求。

影響範圍更大

如果節點數量少,那麼節點故障的影響會比多個節點大很多。例如,只有兩個節點,並且其中一個節點出現故障,那麼一半的節點會受到影響。雖然 Kubernetes 可以將故障節點的工作負載重新安排到其他節點,但如果節點數量少,風險會很高,因為剩餘節點上沒有足夠的備用容量來容納故障節點的所有工作負載。這樣的結果就是,部分應用程式將停機,直到再次啟動故障節點。因此,如果想減少硬體故障的影響,我們就需要選擇多個節點。

容量伸縮笨重

Kubernetes 為雲基礎架構提供了 Cluster Autoscaler,其允許根據當前需求自動新增或刪除節點。大型節點因為有很大的伸縮量,所以伸縮非常笨重。例如只有 2 個節點,那麼新增其他節點需要將叢集容量增加 50%,這比我們實際需要的要多得多,還要為這些用不掉的資源付費。如果要使用叢集自動伸縮功能,那麼選擇多個小型節點會更流暢且經濟高效。

使用多個小節點

這種方法是使用多個小節點搭建叢集,它的優點是什麼?

影響範圍小

如果節點數量多,那麼每個節點上的 Pod 自然會少。如果有 100 個 Pod 和 10 個節點,那麼每個節點平均包含 10 個 Pod。假如其中一個節點發生故障,影響就僅限於總工作負載的一小部分,可能是一小部分應用程式,甚至只是少量副本,因此整個應用程式都會保持執行狀態。另外,剩餘節點上的備用資源還可以容納故障節點的工作負載。一旦出現故障,Kubernetes 可以重新安排所有 Pod,這樣應用程式就能快速地回到正常執行的狀態。

可複製性高

如果有高可用性需求的應用程式和足夠的可用節點,Kubernetes 排程程式可以將每個副本分配給不同的節點。

我們可以透過 node affinites、pod affinities/anti-affinities 以及 taint 和 tolerations 來影響排程程式對 Pod 放置位置的選擇。

看完多個小節點的優點後,再看看它的缺點。

節點數量可能過多

如果使用小節點,則自然需要更多數量的節點來滿足叢集容量,但是大量的節點對於 Kubernetes 控制平面而言是一個挑戰。例如,每個節點都需要能夠與其他節點通訊,這樣通訊路徑的數量會以節點數量的平方進行量級增長,而且所有節點都由控制平面管理。Kubernetes 控制管理器中的節點控制器會定期遍歷叢集中所有節點以進行狀況檢查,這樣節點數量越多就意味著節點控制器的負載更多。

另外,etcd 資料庫上的負載也會受到節點數量影響,每個 kubelet 和 kube-proxy 都會引發 etcd 的 watch(透過 API 伺服器),etcd 需要廣播物件更新。通常,每個工作節點都會給主節點上的系統元件增加一些工作。

搭建叢集時,要如何選擇節點大小?

雖然 Kubernetes 支援最多 5000 個節點的叢集,但在實踐中,500 個節點已經是非常大的挑戰了。所以使用效能更高的主節點,可以減輕工作節點數量過多的影響。因此,如果打算使用大量小節點,需要記住兩件事:

工作節點越多,需要的效能就越高

如果計劃使用超過 500 個節點,可能會遇到需要付出一些努力才能解決效能瓶頸

系統開銷大

Kubernetes 會在每個工作節點上執行一組系統守護程序,例如上文提到的 kube-proxy 和包含 cAdvisor 的 kubelet。所有的這些守護程序會消耗固定數量的資源。如果使用多個小節點,這些系統元件使用的資源部分比例會更大。假設單個節點的所有系統守護程式一共使用 0。1 個 CPU 核心和 0。1GB 記憶體。那麼一共有 10 個 CPU 核心和 10GB 記憶體的節點,守護程式將佔用叢集容量的 1%,但如果是 10 個有 1 個 CPU 核心和 1GB 記憶體的節點,那麼將佔用叢集容量的 10%。因此,要最大化基礎架構支出的回報,更少數量的大型節點會更好。

資源利用率低

小節點可能會出現資源片段太小而無法分配給任何工作負載,造成資源浪費的情況。假設所有的 Pod 都需要 0。75GB 的記憶體,如果有 10 個 1GB 記憶體的節點,那麼可以執行 10 個這樣的 Pod,但每個節點上會有 0。25GB 的記憶體無法利用。這意味著,叢集總記憶體的25%被浪費了。但如果是一個具有 10GB 記憶體的節點,那麼執行 13 個這樣的 Pod,並且僅有 0。25GB 的記憶體沒有被利用。這種情況下只浪費了 2。5% 的記憶體。因此,要最大限度地減少資源浪費,大型節點效果會更好。

節點上的 Pod 限制大

在某些雲基礎架構上,小節點上允許的最大 Pod 數會比我們預期的要少得多。有時每個節點的最大 Pod 數要取決於例項型別。例如,一個

t2。medium

例項,Pod 的最大數量是 17;

t2。small

例項的最大 Pod 數量是 11;

t2。micro

例項最大 Pod 數量是 4。這些數字都非常小。

任何超出這些限制的 Pod 都無法被 Kubernetes 排程程式安排,這些 Pod 會一直保持在 Pending 狀態。如果不瞭解這些限制,可能會導致難以發現的錯誤。因此,如果在雲上使用小節點,要檢查相應每個節點的 Pod 數,並計算清楚節點是否可以容納所有 Pod。

結論

那麼我們應該在叢集中使用少量大型節點還是許多小型節點?它沒有明確的答案。我們要根據部署到叢集的應用程式型別才能做好決策。如果應用程式需要 10GB 記憶體,那不要使用小節點,因為叢集中的節點應至少具有 10GB 記憶體,但如果應用程式需要 10 倍的複製性以實現高可用性,那麼叢集應該至少有 10 個節點。對於以上場景,我們的決策就取決於具體要求。

另外,沒有規則規定所有節點大小必須相同,Kubernetes 叢集的工作節點可以是完全異構的,我們也可以在叢集中使用不同大小節點的方案。最後,布丁好不好,吃了才知道,選擇大小節點最好的方法就是嘗試並找到最適合你的組合!