天天看點

k8s多元度自動彈性伸縮

一、背景

1.1 什麼是彈性伸縮

根據使用者的業務需求和政策,自動調整其彈性計算資源的管理服務,其優勢有:

  • 從應用開發者的角度:能夠讓應用程式開發者專注實作業務功能,無需過多考慮系統層資源
  • 從系統運維者的角度:極大的降低運維負擔, 如果系統設計合理可以實作“零運維”
  • 從管理者角度:極大降低成本
  • 是實作 Serverless 架構的基石,也是 Serverless 的主要特性之一

1.2 k8s 自動彈性伸縮功能包括

  • Pod 水準自動伸縮,HPA,Horizontal Pod Autoscaler
  • Pod 垂直自動伸縮,VPA,Vertical Pod Autoscaler
  • 叢集自動伸縮,CA,Cluster Autoscaler。後續會針對CA做源碼分析。

1.3 HPA

  • 負責調整 pod 的副本數量來實作。是最常用的彈性伸縮元件
  • 解決的是業務負載波動較大的問題
  • 依賴 metrics-server 元件收集 pod 上的 metrics,然後根據預先設定的伸縮政策決定擴縮容 pod
  • metrics-server 預設隻支援基于 cpu、memory 監控名額伸縮政策
  • 如果要使用自定義名額(比如 QPS)作為伸縮政策,需要額外安裝 prometheus-adapter,将自定義名額轉換為 k8s apiserver可以識别的名額
  • HPA-Controller 在k8s預設的 controller-manager 中已經安裝

1.4 VPA

  • 負責調整單個 pod 的資源限額 request、limit 實作
  • 解決的是資源配額評估不準的問題
  • 依賴曆史負載名額,自動計算或調整資源配額
  • VPA-Controller 需要額外安裝,參考

1.5 CA

  • 負責調整 k8s node 節點數量實作叢集級别的擴縮容
  • 依賴底層 IaaS 層的彈性伸縮能力
  • CA-Controller 需要額外安裝,參考

1.6 三者使用場景

  • VPA 用的比較少
  • HPA 用的比較多,流量變化觸發 HPA,新增或減少 pod
  • Pod變化如果觸發 pending或資源不足,會觸發 CA的自動擴縮容

二、HPA

2.1 架構

參考

  • k8s 提供了一種标準 metrics 接口
  • HPA Controller 通過這個統一 metrics 接口可以查下到任意一個 HPA對象關聯的 metrics 資料
  • 查詢 metrics 的接口是通過 apiserver 的聚合層轉發到後端真實的 metric-server 和 prometheus-adapter
k8s多元度自動彈性伸縮

2.2 原生名額

  • 最早 metrics 資料由 metric-server 提供,隻支援 cpu 和 memory 作為名額
  • 通過采集 Node、kubelet 資料彙總到本地
  • 沒有持久化,儲存在記憶體

2.4 自定義名額

  • 為了适應更靈活的需求,metrics APi 開始支援擴充使用者自定義名額 custom metrics
  • 需要自行開發 custom metrics server,社群提供開發架構 custom-metrics-apiserver
  • 社群還提供了更通用的 promethus adapter 适配自定義名額已經存在 prometheus 中的情況
  • prometheus 幾乎是監控标準,是以 prometheus-adapter幾乎可以滿足所有自定義名額需求

2.5 原理

  • 使用者在 HPA 裡設定 metrics 類型和期望的目标 metrics 數值
  • HPA Controller 定期(預設15s)reconcile 每個 HPA 對象
  • reconcile 裡通過 metrics 的 API 擷取該 HPA 的 metrics 實時最新數值,并與目标值比較,确定擴縮容方向
  • 計算出 Deployment 的目标副本數,最後調用 Deployment 的 scale 接口調整副本數
  • 存在多個名額時,最終會選擇擴縮容幅度最大的那個為最終副本數
  • 擴容有一定門檻值
  • 縮容要超過一定冷卻器(預設5min)

2.6 metrics 的分類

最新版 HPA:autoscaling/v2beta1,有四種類型的 metrics

  • Resource:支援k8s所有系統資源,包括cpu、memory。一般隻用cpu,memory不準确。
  • Pods:由 pod 自身提供的自定義 metrics 資料
  • Object:監控名額部署由 pod 本身的服務提供,比如 Ingress
  • External:來自外部系統的自定義名額

2.7 使用示例

  • scaleTargetRef:針對哪個負載進行HPA,幾乎隻會用于 Deployment 對象
  • minReplicas:縮容的最小值
  • maxReplicas:擴容的最大值
  • type:前面介紹的4中之一,這裡使用 Resource
  • resource.target.type:
    • Utilization:百分比
    • AveragetValue:平均值
    • Value:精确值
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: hpa-test
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50           

複制

2.8 缺點

使用 HPA 能滿足一些場景,但是也存在一些缺點:

  • 彈性不夠及時:pod啟動、預熱需要一定時間
  • 如何配置 HPA不好把控
  • 不支援 Dryrun,一點修改就會實際修改執行個體數量

可以參考騰訊開源的 EHPA,實作智能 HPA。

三、VPA

3.1 架構

參考

VPA 包含以下元件:

  • History Storage:通過 metrics api采集和存儲監控資料
  • Recommender:根據監控名額(History Storage)結合内置機制給出資源建議值
  • Updater:實時更新 pod resource requests,監聽 VPA API,根據建議值動态修改 pod 資源
  • VPA Admission Controller:用于 pod 建立時修改 request、limit
k8s多元度自動彈性伸縮

3.2 流程說明

  • vpa 連接配接檢查 pod 在運作過程中占用的資源,預設間隔為10s一次
  • 當發現 pod 資源占用到達門檻值時,vpa會嘗試更改配置設定的記憶體或cpu
  • vpa嘗試更新部署元件中的pod資源定義
  • pod重新開機,新資源将應用于建立出來的執行個體

3.3 運作模式

vpa 支援4中更新政策:

  • Initial:僅在 pod 建立時修改,以後都不再修改
  • Auto:預設政策,pod建立時、pod更改時都會修改
  • Recreate:類似 Auto,在 Pod 的建立和更新時都會修改資源請求,不同的是,隻要Pod 中的請求值與新的推薦值不同,VPA 都會驅逐該 Pod,然後使用新的推薦值重新啟一個。是以,一般不使用該政策,而是使用 Auto,除非你真的需要保證請求值是最新的推薦值。
  • Off:不改變 Pod 的資源請求,不過仍然會在 VPA 中設定資源的推薦值

3.4 使用注意

  • 同一個 deployment,不能同時使用 hpa 和 vpa
  • vpa 更新資源會導緻 pod 重建、重新開機、甚至重新排程
  • vpa 使用 admission webhook ,需要確定與其他 webhook 不沖突
  • vpa的性能沒有在大型叢集中測試過
  • vap建議值可能超過實際資源上限,進而導緻pod處于pending無法被排程
  • 多個 vpa 同時配置同一個pod會造成未定義的行為
  • vpa不支援擴充控制器

3.5 總結

  • 使用的場景太少,重新開機 pod業務不可接受
  • 沒有大規模場景驗證,一般不太會用這個功能

四、CA

4.1 架構

參考

CA由一下幾個子產品組成:

  • autoscaler:核心子產品,負責整體擴縮容功能
  • Estimator:負責評估計算擴容節點
  • Simulator:負責模拟排程,計算縮容節點
  • Cloud Provider:與雲上 IaaS 層互動,負責增删改查節點。雲廠商需要實作相關接口。
k8s多元度自動彈性伸縮

4.2 擴縮容的時機

參考ca官方說明

  • pod 因資源不足 pending,觸發擴容。不可排程後最多 10s 可以觸發擴容
  • node 資源使用率低,且 node 上所有 pod 都能排程到其他 node 上。節點不可用後 10min 開始縮容
  • 可以在啟動時關閉縮容功能

4.3 哪些pod會阻止CA縮容Node

  • 節點上有pod被PodDisruptionBudget控制器限制。
  • 節點上有命名空間是kube-system的pods。
  • 節點上的pod不是被控制器建立,例如不是被deployment, replica set, job, stateful set建立。
  • 節點上有pod使用了本地存儲
  • 節點上pod驅逐後無處可去,即沒有其他node能排程這個pod
  • 節點有注解:"cluster-autoscaler.kubernetes.io/safe-to-evict": "false"

4.4 配置某些Node禁止縮容

為節點添加特殊标簽: "cluster-autoscaler.kubernetes.io/scale-down-disabled": "true"

kubectl annotate node <nodename> cluster-autoscaler.kubernetes.io/scale-down-disabled=true           

複制

五、HPA + CA結合有多快

5.1 影響因素

當 CA 和 HPA 結合使用時,從負載增加到新 pod 運作的總時間主要由三個因素決定:

  • HPA 反應時間
  • CA 反應時間
  • 節點建立時間

5.2 時間分析

具體每一環節的預設時間:

  • kubelet 每隔 10s 對 pod 的 cpu 使用率名額進行抓取
  • Metric server 每隔 1min 從 kubelet 擷取資料
  • HPA 每隔 30s 檢查一次 Metric server 中的 CPU 負載名額
  • CA 檢查到 pod pending 最多 10s 觸發擴容

5.3 具體數值

擴容最終時間:

  • 做出擴容決定:預計大多數情況不到 30s
  • 開出機器并且 pod 排程成功:取決于雲廠商,GCE一般是3~4min

縮容最終時間:

  • 僅縮容pod:取決于 HPA 的縮容冷卻時間,預設好像是5min
  • 縮容Node:CA的冷卻時間是10min

六、總結

本文針對 k8s 叢集擴容的背景、價值、實作做了大概的介紹,HPA 預設就可以使用,CA需要額外安裝元件使用,而VPA使用較少。我司正是使用了 HPA + CA的組合來實作關聯擴縮容,後續會做源碼級分析,敬請期待。