天天看點

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

傳統彈性伸縮的困境

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

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

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

正常的彈性伸縮是基于門檻值的,通過設定一個資源緩沖水位來保障資源的充盈,通常

15%-30%

左右的資源預留是比較常見的選擇。換言之就是通過一個具備緩沖能力的資源池用資源的備援換取叢集的可用。

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

  1. 百分比碎片難題

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

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

特别是在縮容的場景下,通常為了保證縮容後的叢集不處在震蕩狀态,我們會一個節點一個節點或者二分法來縮容節點,那麼如何根據百分比來判斷目前節點是處在縮容狀态就尤為重要,此時如果大規格機器有較低的使用率被判斷縮容,那麼很有可能會造成節點縮容後,容器重新排程後的争搶饑餓。如果添加判斷條件,優先縮容小配置的節點,則有可能造成縮容後資源的大量備援,最終叢集中可能會隻剩下所有的

巨石

節點。

  1. 容量的規劃炸彈

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

在Kubernetes中是通過

Request

Limit

的方式進行設定,

Request

表示資源的申請值,

Limit

表示資源的限制值。既然

Request

Limit

才是容量規劃的對等概念,那麼這就代表着資源的實際計算規則要根據

Request

Limit

才更加準确。而對于每個節點預留資源門檻值而言,很有可能會造成小節點的預留無法滿足排程,大節點的預留又排程不完的場景。

  1. 資源使用率困境

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

如果沒有設定

Request

Limit

,而叢集的整體資源使用率很高這意味着什麼?這表示所有的Pod都在被以真實負載為單元進行排程,互相之間存在非常嚴重的争搶,而且簡單的加入節點也絲毫無法解決問題,因為對于一個已排程的Pod而言,除了手動排程與驅逐沒有任何方式可以将這個Pod從高負載的節點中移走。那如果我們設定了

Request

Limit

而節點的資源使用率又非常高的時候說明了什麼呢?很可惜這在大部分的場景下都是不可能的,因為不同的應用不同的負載在不同的時刻資源的使用率也會有所差異,大機率的情況是叢集還沒有觸發設定的門檻值就已經無法排程Pod了。

彈性伸縮概念的延伸

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

  • 線上任務類型

比較常見的是網站、API服務、微服務等常見的網際網路業務型應用,這種應用的特點是對正常資源消耗較高,比如CPU、記憶體、網絡IO、磁盤IO等,對于業務中斷容忍性差。

  • 離線任務類型

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

  • 定時任務類型

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

  • 特殊任務類型

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

單純的基于資源使用率的彈性伸縮大部分是用來解決第一種類型的應用而産生的,對于其他三種類型的應用并不是很合适,那麼Kubernetes是如何解決這個問題的呢?

kubernetes的彈性伸縮布局

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

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

Kubernetes 彈性伸縮全場景解析 (一)- 概念延伸與元件布局
  • cluster-autoscaler:kubernetes社群中負責節點水準伸縮的元件,目前處在GA階段(General Availability,即正式釋出的版本)。
  • HPA:kubernetes社群中負責Pod水準伸縮的元件,是所有伸縮元件中曆史最悠久的,目前支援

    autoscaling/v1

    autoscaling/v2beta1

    autoscaling/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社群是如何通過解耦的方式通過多個轉職的元件實作了兩個次元的彈性伸縮,在本系列後面的文章中會為一一解析每個彈性伸縮元件的相關原理與用法。

繼續閱讀