本文分享自華為雲社群《HPA各關聯元件扭轉關係以及建議》,作者:可以交個朋友。
應用程式的使用存在波峰波谷現象,在應用流量處於低谷期間,可以釋放因過多的Pod而浪費的硬體資源。在應用流量高峰期提供彈性足夠的Pod處理流量。
kubernetes使用者通過建立一個hpa資源(horizontalpodautoscaler)用於定義對某個負載比如deployment的彈性策略,策略中說明基於什麼指標、指標的閾值以及彈性的最大值、最小值。hpa資源建立後,kube-controller-manager中的hpa-controller協程開始工作,大致工作步驟如下:
呼叫kube-apiserver,獲取HPA 資源關聯負載的指標
用負載當前的指標和HPA中規定的閾值比較,結合邏輯判斷是增加、減少或者不修改負載的範例數
根據步驟2的計算結果,呼叫kube-apiserver修改負載的範例數
需要理解的關鍵卡點問題是
指標是從哪裡來的?
kube-apiserver本身程式碼裡面不提供指標的API,為啥呼叫kube-apiserver介面能獲取到指標?
指標均由業務API提供,一般業界指標標準URL為/metrics。kubernetes生態中,主要通過Metrics server和Prometheus獲取指標:
metrics server:metrics-server作為叢集元件,用於收集和聚合從每個kubelet中提取的資源指標。本質上只是做了資料的中轉和聚合,通過呼叫kubelet的api介面獲取資料。kubelet 作為用於管理容器資源的節點代理,可以使用 /metrics/resource 介面存取資源指標。
Prometheus:在某些場景下,prometheus採集的指標可能需要重新命名或者重新計算,由Prometheus-adapter元件提供轉換能力。
在kubernetes中指標分為core metric(核心指標)和custom metric(自定義指標):
Core metrics(核心指標):Metrics server通過呼叫各個節點kubelet 10250埠,由kubelet內部cAdvisor模組獲取度量指標,對應指標實現由kubelet提供,使用者無法修改,然後返回給HPA。
Custom Metrics(自定義指標):通過Prometheus獲取對應的業務指標,具體指標內容有業務自己實現。
API Aggregation 允許在不修改 Kubernetes 核心程式碼的同時擴充套件 Kubernetes API,即將第三方服務註冊到 Kubernetes API 中,這樣就可以通過 Kubernetes API 來存取外部服務。
如下圖範例,通過APIService資源新增 /apis/metrics.k8s.io/v1beta1 和 /apis/custom.metrics.k8s.io/v1beta1。當kube-apiserver收到對應URL請求後,會將請求轉發給APIService資源中spec.service指定的服務,URL為 /apis/metrics.k8s.io/v1beta1的請求轉發給metrics-server服務處理,URL為/apis/custom.metrics.k8s.io/v1beta1的請求轉發給custom-metrics-apiserver服務(本質上就是Prometheus-adapter,服務名稱為custom-metrics-apiserver而已)。如此,便可以通過直接存取kube-apiserver埠,獲取對應的指標資料。
# 比如獲取核心指標 kubectl get --raw "/apis/metrics.k8s.io/v1beta1/namespaces/${yourNamespace}/pods" # 獲取自定義指標: kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/${yourNamespace}/x"
如此,kube-controller-manager就可以通過呼叫kube-apiserver介面獲取相關業務的指標了。
HorizontalPodAutoscaler 是 Kubernetes autoscaling
API 組中的 API 資源。 當前的穩定版本可以在 autoscaling/v2
API 版本中找到,其中包括對基於記憶體和自定義指標執行擴縮的支援。 在使用 autoscaling/v1
時,autoscaling/v2
中引入的新欄位作為註釋保留。可設定的擴縮行為(behavior)在之前的 autoscaling/v2beta2
API 版本將此功能作為 beta 功能提供。1.23 kubernetes及以上可參考yaml:
apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: php-apache 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 behavior: scaleDown: policies: - type: Pods value: 4 periodSeconds: 60 - type: Percent value: 10 periodSeconds: 60
核心指標彈性,一般建議採用cpu指標進行彈性,memory因為不太敏感而且跟開發語言相關,大多數語言都有記憶體池以及內建GC機制導致程序記憶體監控不準確
快速擴容,主要防止流量瓶頸;緩慢縮容,主要防止另一個流量高峰。
快速擴容策略設定
behavior: #通過behavior單獨設定擴縮行為 scaleUp: stabilizationWindowSeconds: 0 # 擴容沒有穩定視窗,滿足條件 立刻擴容 policies: - type: Percent #以下策略表示在15s內,最多擴容當前範例數的9倍 value: 900 periodSeconds: 15
快速擴容,緩慢縮容;業務在流量高峰期後,並行量驟降的場景中,如果使用預設的縮容策略,幾分鐘後Pod的數量也會隨著驟降,此時如果又迎來流量高峰,擴容過程需要一段時間,這段時間內造成業務後端處理能力達到瓶頸,將導致部分請求失敗。可以為HPA設定behavior縮容策略,快速縮容之後緩慢縮容。
behavior: # 通過該欄位單獨設定擴縮行為 scaleDown: policies: - type: Pods #表示每600s刪除一個pod value: 1 periodSeconds: 600 scaleUp: policies: - type: Percent #表示在15s之內,擴容當前範例數的9倍 value: 900 periodSeconds: 15
禁止自動縮容。對於擴容後需要禁止自動縮容的關鍵業務應用,需要人工干預或者其他方式進行縮容,可以使用如下策略禁止縮容
behavior: #通過該欄位單獨設定擴縮行為
scaleDown:
selectPolicy: Disabled #selectPolicy 的值 Disabled 會關閉對給定方向的縮容,使用該策略,將會阻止縮容
延長縮容時間窗。縮容的穩定視窗預設是5分鐘,如果需要延長時間視窗以避免一些流量毛刺,可以設定以下策略
behavior: #通過該欄位可單獨設定擴縮行為 scaleDown: stabilizationWindowSeconds: 600 #等待600s後 在開始縮容 policies: - type: Pods value: 5 # 每次只縮容5個Pod
HorizontalPodAutoscaler API 也支援容器指標源,這時 HPA 可以跟蹤記錄一組 Pod 中各個容器的資源用量,進而觸發擴縮目標物件的操作。 特性狀態: Kubernetes v1.27 [beta]
如果你有一個 Web 應用和一個執行紀錄檔操作的邊車容器,你可以基於 Web 應 用的資源用量來執行擴縮,忽略邊車容器的存在及其資源用量。
type: ContainerResource containerResource: name: cpu container: application target: type: Utilization averageUtilization: 60
HPA 控制器會對目標物件執行擴縮操作以確保所有 Pod 中 application
容器的平均 CPU 用量為 60%。