Kubernetes 彈性伸縮全場景解讀(二)- HPA 的原理與演進

 

前言

在上一篇文章 Kubernetes 彈性伸縮全場景解析 (一):概念延伸與組件佈局中,咱們介紹了在 Kubernetes 在處理彈性伸縮時的設計理念以及相關組件的佈局,在今天這篇文章中,會爲你們介紹在 Kubernetes 中彈性伸縮最經常使用的組件 HPA(Horizontal Pod Autoscaler)。HPA 是經過計算 Pod 的實際工做負載進行從新容量規劃的組件,在資源池符合知足條件的前提下,HPA 能夠很好的實現彈性伸縮的模型。HPA 到目前爲止,已經演進了三個大版本,本文將會爲你們詳細解析 HPA 底層的原理以及在 Kubernetes 中彈性伸縮概念的演變歷程。php

HPA 基本原理

HPA 是根據實際工做負載水平伸縮容器數目的組件,從中能夠提煉出兩個很是重要的關鍵字:負載數目。咱們能夠用一個很是簡單的數學公式進行概括:apache

下面舉一個實際例子進行上述公式的闡述。api

假設存在一個叫 A 的 Deployment,包含3個 Pod,每一個副本的 Request 值是 1 核,當前 3 個 Pod 的 CPU 利用率分別是 60%、70% 與 80%,此時咱們設置 HPA 閾值爲 50%,最小副本爲 3,最大副本爲 10。接下來咱們將上述的數據帶入公式中:架構

 

  • 總的 Pod 的利用率是 60%+70%+80% = 210%;
  • 當前的 Target 是 3;
  • 算式的結果是 70%,大於50%閾值,所以當前的 Target 數目太小,須要進行擴容;
  • 從新設置 Target 值爲 5,此時算式的結果爲 42% 低於 50%,判斷還須要擴容兩個容器;
  • 此時 HPA 設置 Replicas 爲 5,進行 Pod 的水平擴容。

 

通過上面的推演,能夠協助開發者快速理解 HPA 最核心的原理,不過上面的推演結果和實際狀況下是有所出入的,若是開發者進行試驗的話,會發現 Replicas 最終的結果是 6 而不是 5。這是因爲 HPA 中一些細節的處理致使的,主要包含以下三個主要的方面:app

 

  1. 噪聲處理

經過上面的公式能夠發現,Target 的數目很大程度上會影響最終的結果,而在 Kubernetes 中,不管是變動或者升級,都更傾向於使用 Recreate 而不是 Restart 的方式進行處理。這就致使了在 Deployment 的生命週期中,可能會出現某一個時間,Target 會因爲計算了 Starting 或者 Stopping 的 Pod 而變得很大。這就會給 HPA 的計算帶來很是大的噪聲,在 HPA Controller 的計算中,若是發現當前的對象存在 Starting 或者 Stopping 的 Pod 會直接跳過當前的計算週期,等待狀態都變爲 Running 再進行計算。佈局

 

  1. 冷卻週期

在彈性伸縮中,冷卻週期是不能逃避的一個話題,不少時候咱們指望快速彈出與快速回收,而另外一方面,咱們又不但願集羣震盪,因此一個彈性伸縮活動冷卻週期的具體數值是多少,一直被開發者所挑戰。在 HPA 中,默認的擴容冷卻週期是 3 分鐘,縮容冷卻週期是 5 分鐘。url

 

  1. 邊界值計算

咱們回到剛纔的計算公式,第一次咱們算出須要彈出的容器數目是 5,此時擴容後總體的負載是 42%,可是咱們彷佛忽略了一個問題:一個全新的 Pod 啓動會不會本身就佔用了部分資源?此外,8% 的緩衝區是否就可以緩解總體的負載狀況?要知道當一次彈性擴容完成後,下一次擴容要最少等待 3 分鐘才能夠繼續擴容。爲了解決這些問題,HPA 引入了邊界值 △,目前在計算邊界條件時,會自動加入 10% 的緩衝,這也是爲何在剛纔的例子中最終的計算結果爲 6 的緣由。spa

HPA 的演進歷程

在瞭解了 HPA 的基本原理後,咱們來聊一下 HPA 的演進歷程,目前 HPA 已經支持了 autoscaling/v1autoscaling/v1beta1 和 autoscaling/v1beta2 三個大版本。大部分的開發者目前比較熟悉的是autoscaling/v1 的版本,這個版本的特色是隻支持 CPU 一個指標的彈性伸縮,大體的 yaml 內容以下:設計

 

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: php-apache
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: php-apache
  minReplicas: 1
  maxReplicas: 10
  targetCPUUtilizationPercentage: 50

 

 

接下來咱們再來看一下 v2beta1 與 v2beta2 的 yaml,會發現裏面支持的 metrics 類型增長了不少,結構也複雜了不少。3d

 

apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: php-apache
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: php-apache
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        kind: AverageUtilization
        averageUtilization: 50
  - type: Pods
    pods:
      metric:
        name: packets-per-second
      targetAverageValue: 1k
  - type: Object
    object:
      metric:
        name: requests-per-second
      describedObject:
        apiVersion: extensions/v1beta1
        kind: Ingress
        name: main-route
      target:
        kind: Value
        value: 10k
---
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: php-apache
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: php-apache
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50

 

 

而這些變化的產生不得不提的是 Kubernetes 社區中對監控與監控指標的認識與轉變。在 Kubernetes 中,有兩個核心的監控組件 Heapster 與 Metrics Server。Heapster 是早期 Kubernetes 社區中惟一的監控組件,它所包含的功能很強大,經過採集 kubelet 提供的 metrics 接口,並支持監控數據的離線與歸檔。

 

 

大體的架構圖如上:source 的部分是不一樣的數據來源,主要是 kubelet 的 common api 與後來提供的 summary api;processor 的做用是將採集的數據進行處理,分別在 namespace 級別、cluster 級別進行聚合,並建立新的聚合類型的監控數據;sink 的做用是數據離線與歸檔,常見的歸檔方式包括 influxdb、kafka 等等。Heapster 組件在至關長時間成爲了 Kubernetes 社區中監控數據的惟一來源,也所以有很是多的和監控相關的組件經過 Heapster 的鏈路進行監控數據的消費。可是後來,Kubernetes 社區發現了 Heapster 存在很是嚴重的幾個問題:

 

  • 強大繁多的 Sink 由不一樣的 Maintainer 進行維護,50% 以上的 Heapster Issues 都是關於 Sink 沒法使用的,而因爲 Maintainer 的活躍度不一樣形成 Heapster 社區有大量的 issues 沒法解決;
  • 對於開發者而言,監控數據的類型已經再也不是 CPU、Memory 這麼簡單的幾個指標項了,愈來愈多的開發者須要應用內或者接入層的監控指標,例如 ingress 的 QPS、應用的在線活躍人數等等。而這些指標的獲取是 Heapster 沒法實現的;
  • Prometheus 的成熟讓 Heapster 的生存空間不斷被擠壓,自從 Prometheus 被 CNCF 收錄爲孵化項目,Heapster 的不可替代地位被正式移除。

 

社區通過反思後,決定將監控的指標邊界進行劃分,分爲 Resource、Custom 和 External 三種不一樣的 Metrics,而 Heapster(Metrics Server) 的定位就只關心 Resource 這一種指標類型。爲了解決代碼維護性的問題,Metrics Server 對 Heapster 進行了裁剪,裁剪後的架構以下:

 

 

去掉了 Sink 的機制,並將調用方式改成標準的 API 註冊的方式,這樣的好處是既精簡了核心代碼的邏輯又提供了替代的可能,也就是說此時 Metrics Server 也是能夠替代的,只要實現了相同的 API 接口,並註冊到 API Server 上,就能夠替代 Metrics Server。

 

接下來咱們解析一下三種不一樣的 Metrics 與使用的場景:

  API 註釋
Resource metrics.k8s.io Pod的資源指標,計算的時要除以Pod數目再對比閾值進行判斷
Custom custom.metrics.k8s.io Object: CRD等對象的監控指標,直接計算指標比對閾值
Pods : 每一個Pod的自定義指標,計算時要除以Pods的數目
External external.metrics.k8s.io External:集羣指標的監控指標,一般由雲廠商實現

其中 autoscaling/v2beta1 支持 Resource 與 Custom 兩種指標,而 autoscaling/v2beta2 中增長了 External 的指標的支持。

最後

HPA 目前已經進入了 GA 階段,在大致的功能上面不會進行過多的變化,目前社區的主要發力點在如何配置化的調整細節參數、豐富監控 adapter 的實現等等。在本文中,咱們在概念上給你們介紹了 HPA 的一些原理以及發展的趨勢,在下一篇文章中,咱們會爲你們講解如何開啓 v2beta1 與 v2beta2 的。

相關文章
相關標籤/搜索