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

傳統彈性伸縮的困境

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

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

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

這種方式表面上看是沒有什麼問題的,確實在不少的解決方案或者開源組件中也是按照這種方式進行實現的,可是當咱們深刻的思考這種實現方案的時候會發現,這種方式存在以下三個經典問題。大數據

1. 百分比碎片難題網站

在一個Kubernetes集羣中,一般不僅包含一種規格的機器,針對不一樣的場景、不一樣的需求,機器的配置、容量可能會有很是大的差別,那麼集羣伸縮時的百分比就具有很是大的迷惑性。假設咱們的集羣中存在4C8G的機器與16C32G的機器兩種不一樣規格,對於10%的資源預留,這兩種規格是所表明的意義是徹底不一樣的。spa

特別是在縮容的場景下,一般爲了保證縮容後的集羣不處在震盪狀態,咱們會一個節點一個節點或者二分法來縮容節點,那麼如何根據百分比來判斷當前節點是處在縮容狀態就尤其重要,此時若是大規格機器有較低的利用率被判斷縮容,那麼頗有可能會形成節點縮容後,容器從新調度後的爭搶飢餓。若是添加判斷條件,優先縮容小配置的節點,則有可能形成縮容後資源的大量冗餘,最終集羣中可能會只剩下全部的巨石節點。設計

2. 容量的規劃炸彈code

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

在Kubernetes中是經過RequestLimit的方式進行設置,Request表示資源的申請值,Limit表示資源的限制值。既然RequestLimit纔是容量規劃的對等概念,那麼這就表明着資源的實際計算規則要根據RequestLimit才更加準確。而對於每一個節點預留資源閾值而言,頗有可能會形成小節點的預留沒法知足調度,大節點的預留又調度不完的場景。事件

3. 資源利用率困境

集羣的資源利用率是否能夠真的表明當前的集羣狀態呢?當一個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社區是如何經過解耦的方式經過多個轉職的組件實現了兩個維度的彈性伸縮,在本系列後面的文章中會爲一一解析每一個彈性伸縮組件的相關原理與用法。



本文做者:莫源

閱讀原文

本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索