Kubernetes 彈性伸縮全場景解析 (一)- 概念延伸與組件布局


傳統彈性伸縮的困境

彈性伸縮是Kubernetes中被大家關注的一大亮點,在討論相關的組件和實現方案之前。首先想先給大家擴充下彈性伸縮的邊界與定義,傳統意義上來講,彈性伸縮主要解決的問題是容量規划與實際負載的矛盾。

 

如上圖所示,藍色的水位線表示集群的容量隨着負載的提高不斷的增長,紅色的曲線表示集群的實際的負載真實的變化。而彈性伸縮要解決的就是當實際負載出現激增,而容量規划沒有來得及反應的場景。

常規的彈性伸縮是基於閾值的,通過設置一個資源緩沖水位來保障資源的充盈,通常15%-30%左右的資源預留是比較常見的選擇。換言之就是通過一個具備緩沖能力的資源池用資源的冗余換取集群的可用。

這種方式表面上看是沒有什么問題的,確實在很多的解決方案或者開源組件中也是按照這種方式進行實現的,但是當我們深入的思考這種實現方案的時候會發現,這種方式存在如下三個經典問題。

  1. 百分比碎片難題

在一個Kubernetes集群中,通常不只包含一種規格的機器,針對不同的場景、不同的需求,機器的配置、容量可能會有非常大的差異,那么集群伸縮時的百分比就具備非常大的迷惑性。假設我們的集群中存在4C8G的機器與16C32G的機器兩種不同規格,對於10%的資源預留,這兩種規格是所代表的意義是完全不同的。

 

特別是在縮容的場景下,通常為了保證縮容后的集群不處在震盪狀態,我們會一個節點一個節點或者二分法來縮容節點,那么如何根據百分比來判斷當前節點是處在縮容狀態就尤為重要,此時如果大規格機器有較低的利用率被判斷縮容,那么很有可能會造成節點縮容后,容器重新調度后的爭搶飢餓。如果添加判斷條件,優先縮容小配置的節點,則有可能造成縮容后資源的大量冗余,最終集群中可能會只剩下所有的巨石節點。

  1. 容量的規划炸彈

還記得在沒有使用容器前,是如何做容量規划的嗎?一般會按照應用來進行機器的分配,例如,應用A需要2台4C8G的機器,應用B需要4台8C16G的機器,應用A的機器與應用B的機器是獨立的,相互不干擾。到了容器的場景中,大部分的開發者無需關心底層的資源了,那么這個時候容量規划哪里去了呢?

在Kubernetes中是通過RequestLimit的方式進行設置,Request表示資源的申請值,Limit表示資源的限制值。既然RequestLimit才是容量規划的對等概念,那么這就代表着資源的實際計算規則要根據RequestLimit才更加准確。而對於每個節點預留資源閾值而言,很有可能會造成小節點的預留無法滿足調度,大節點的預留又調度不完的場景。

  1. 資源利用率困境

集群的資源利用率是否可以真的代表當前的集群狀態呢?當一個Pod的資源利用率很低的時候,不代表就可以侵占他所申請的資源。在大部分的生產集群中,資源利用率都不會保持在一個非常高的水位,但從調度來講,資源的調度水位應該保持在一個比較高的水位。這樣才能既保證集群的穩定可用,又不過於浪費資源。

如果沒有設置RequestLimit,而集群的整體資源利用率很高這意味着什么?這表示所有的Pod都在被以真實負載為單元進行調度,相互之間存在非常嚴重的爭搶,而且簡單的加入節點也絲毫無法解決問題,因為對於一個已調度的Pod而言,除了手動調度與驅逐沒有任何方式可以將這個Pod從高負載的節點中移走。那如果我們設置了RequestLimit而節點的資源利用率又非常高的時候說明了什么呢?很可惜這在大部分的場景下都是不可能的,因為不同的應用不同的負載在不同的時刻資源的利用率也會有所差異,大概率的情況是集群還沒有觸發設置的閾值就已經無法調度Pod了。

彈性伸縮概念的延伸

既然基於資源利用率的彈性伸縮有上述已知的三個問題,有什么辦法可以來解決呢?隨着應用類型的多樣性發展,不同類型的應用的資源要求也存在越來越大的差異。彈性伸縮的概念和意義也在變化,傳統理解上彈性伸縮是為了解決容量規划和在線負載的矛盾,而現在是資源成本與可用性之間的博弈。如果將常見的應用進行規約分類,可以分為如下四種不同類型:

  • 在線任務類型

比較常見的是網站、API服務、微服務等常見的互聯網業務型應用,這種應用的特點是對常規資源消耗較高,比如CPU、內存、網絡IO、磁盤IO等,對於業務中斷容忍性差。

  • 離線任務類型

例如大數據離線計算、邊緣計算等,這種應用的特點是對可靠性的要求較低,也沒有明確的時效性要求,更多的關注點是成本如何降低。

  • 定時任務類型

定時運行一些批量計算任務是這種應用的比較常見形態,成本節約與調度能力是重點關注的部分。

  • 特殊任務類型

例如閑時計算的場景、IOT類業務、網格計算、超算等,這類場景對於資源利用率都有比較高的要求。

單純的基於資源利用率的彈性伸縮大部分是用來解決第一種類型的應用而產生的,對於其他三種類型的應用並不是很合適,那么Kubernetes是如何解決這個問題的呢?

kubernetes的彈性伸縮布局

Kubernetes將彈性伸縮的本質進行了抽象,如果拋開實現的方式,對於不同應用的彈性伸縮而言,該如何統一模型呢?Kubernetes的設計思路是將彈性伸縮划分為保障應用負載處在容量規划之內與保障資源池大小滿足整體容量規划兩個層面。簡單理解,當需要彈性伸縮時,優先變化的應該是負載的容量規划,當集群的資源池無法滿足負載的容量規划時,再調整資源池的水位保證可用性。而兩者相結合的方式是無法調度的Pod來實現的,這樣開發者就可以在集群資源水位較低的時候使用HPA、VPA等處理容量規划的組件實現實時極致的彈性,資源不足的時候通過Cluster-Autoscaler進行集群資源水位的調整,重新調度,實現伸縮的補償。兩者相互解耦又相互結合,實現極致的彈性。

在Kubernetes的生態中,在多個維度、多個層次提供了不同的組件來滿足不同的伸縮場景。如果我們從伸縮對象與伸縮方向兩個方面來解讀Kubernetes的彈性伸縮的話,可以得到如下的彈性伸縮矩陣。

 

  • cluster-autoscaler:kubernetes社區中負責節點水平伸縮的組件,目前處在GA階段(General Availability,即正式發布的版本)。
  • HPA:kubernetes社區中負責Pod水平伸縮的組件,是所有伸縮組件中歷史最悠久的,目前支持autoscaling/v1autoscaling/v2beta1autoscaling/v2beta2,其中autoscaling/v1只支持CPU一種伸縮指標,在autoscaling/v2beta1中增加支持custom metrics,在autoscaling/v2beta2中增加支持external metrics。
  • cluster-proportional-autoscaler:根據集群的節點數目,水平調整Pod數目的組件,目前處在GA階段。
  • vetical-pod-autoscaler:根據Pod的資源利用率、歷史數據、異常事件,來動態調整負載的Request值的組件,主要關注在有狀態服務、單體應用的資源伸縮場景,目前處在beta階段。
  • addon-resizer:根據集群中節點的數目,縱向調整負載的Request的組件,目前處在beta階段。

在這五個組件中,cluster-autoscaler、HPA、cluster-proportional-autoscaler是目前比較穩定的組件,建議有相關需求的開發者進行選用。

對於百分之八十以上的場景,我們建議客戶通過HPA結合cluster-autoscaler的方式進行集群的彈性伸縮管理,HPA負責負載的容量規划管理而cluster-autoscaler負責資源池的擴容與縮容。

最后

在本文中,和大家主要討論的是在雲原生時代下彈性伸縮概念的延伸,以及Kubernetes社區是如何通過解耦的方式通過多個轉職的組件實現了兩個維度的彈性伸縮,在本系列后面的文章中會為一一解析每個彈性伸縮組件的相關原理與用法。


原文鏈接
本文為雲棲社區原創內容,未經允許不得轉載。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM