Horizontal Pod Autoscaler(Pod水平自動伸縮)
Horizontal Pod Autoscaler 根據觀察到的CPU利用率(或在支援自定義指標的情況下,根據其他一些應用程式提供的指標)自動伸縮 replication controller, deployment, replica set, stateful set 中的pod數量。注意,Horizontal Pod Autoscaling不適用於無法伸縮的物件,例如DaemonSets。
Horizontal Pod Autoscaler 被實現作為Kubernetes API資源和控制器。該資源決定控制器的行為。控制器會定期調整副本控制器或部署中副本的數量,以使觀察到的平均CPU利用率與使用者指定的目標相匹配。
1. Horizontal Pod Autoscaler 是如何工作的
Horizontal Pod Autoscaler 實現為一個控制迴圈,其週期由--horizontal-pod-autoscaler-sync-period選項指定(預設15秒)。
在每個週期內,controller manager都會根據每個HorizontalPodAutoscaler定義的指定的指標去查詢資源利用率。 controller manager從資源指標API(針對每個pod資源指標)或自定義指標API(針對所有其他指標)獲取指標。
對於每個Pod資源指標(比如:CPU),控制器會從資源指標API中獲取相應的指標。然後,如果設定了目標利用率值,則控制器計算利用率值作為容器上等效的資源請求百分比。如果設定了目標原始值,則直接使用原始指標值。然後,控制器將所有目標容器的利用率或原始值(取決於指定的目標型別)取平均值,併產生一個用於縮放所需副本數量的比率。
如果某些Pod的容器未設定相關資源請求,則不會定義Pod的CPU使用率,並且自動縮放器不會對該指標採取任何措施。
2. 演算法細節
desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]
直譯為:(當前指標值 ➗ 期望指標值) ✖️ 當前副本數 ,結果再向上取整,最終結果就是期望的副本數量
例如,假設當前指標值是200m ,期望指標值是100m,期望的副本數量就是雙倍。因為,200.0 / 100.0 == 2.0
如果當前值是50m,則根據50.0 / 100.0 == 0.5,那麼最終的副本數量就是當前副本數量的一半
如果該比率足夠接近1.0,則會跳過伸縮
當targetAverageValue或者targetAverageUtilization被指定的時候,currentMetricValue取HorizontalPodAutoscaler伸縮目標中所有Pod的給定指標的平均值。
所有失敗的和標記刪除的Pod將被丟棄,即不參與指標計算
當基於CPU利用率來進行伸縮時,如果有尚未準備好的Pod(即它仍在初始化),那麼該Pod將被放置到一邊,即將被保留。
kubectl 也支援Horizontal Pod Autoscaler
# 檢視autoscalers列表 kubectl get hpa # 檢視具體描述 kubectl describe hpa # 刪除autoscaler kubectl delete hpa # 示例:以下命名將會為副本集foo建立一個autoscaler,並設定目標CPU利用率為80%,副本數在2~5之間 kubectl autoscale rs foo --min=2 --max=5 --cpu-percent=80
3. 演示
Horizontal Pod Autoscaler automatically scales the number of pods in a replication controller, deployment, replica set or stateful set based on observed CPU utilization.
建立Dockerfile,並構建映象
FROM java:8 COPY ./hello-world-0.0.1-SNAPSHOT.jar hello-world.jar CMD java -jar hello-world.jar
在hello-world.jar中執行一些CPU密集型計算
執行映象並暴露為服務
kubectl run hello-world-example \ --image=registry.cn-hangzhou.aliyuncs.com/chengjs/hello-world:2.0 \ --requests='cpu=200m' \ --limits='cpu=500m' \ --expose \ --port=80 \ --generator=run-pod/v1
建立 Horizontal Pod Autoscaler
HPA將增加和減少副本數量,以將所有Pod的平均CPU利用率維持在50%
kubectl autoscale deployment hello-world-example --cpu-percent=50 --min=1 --max=10
檢查autoscaler的當前狀態
kubectl get hpa
增加負載
接下來,利用壓測工具持續請求,以增加負載,再檢視
kubectl get deployment hello-world-example
通過使用autoscaling/v2beta2版本,你可以定義更多的指標
首先,以autoscaling/v2beta2格式獲取HorizontalPodAutoscaler的YAML
kubectl get hpa.v2beta2.autoscaling -o yaml > /tmp/hpa-v2.yaml
在編輯器中開啟/tmp/hpa-v2.yaml檔案,接下來對其進行修改
第一個可以替換的指標型別是Pod指標。這些指標在各個容器中平均在一起,並且和目標值進行比較,已確定副本數。例如:
type: Pods pods: metric: name: packets-per-second target: type: AverageValue averageValue: 1k
第二個可以替換的指標型別是物件指標。顧名思義,它描述的是Object,而不是Pod。例如:
type: Object object: metric: name: requests-per-second describedObject: apiVersion: networking.k8s.io/v1beta1 kind: Ingress name: main-route target: type: Value value: 2k
修改後完整的/tmp/hpa-v2.yaml檔案如下:
apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler metadata: name:hello-world-example namespace:default spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: hello-world-example minReplicas: 1 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50 - type: Pods pods: metric: name: packets-per-second target: type: AverageValue averageValue: 1k - type: Object object: metric: name: requests-per-second describedObject: apiVersion: networking.k8s.io/v1beta1 kind: Ingress name: main-route target: type: Value value: 10k status: observedGeneration: 1 lastScaleTime: <some-time> currentReplicas: 1 desiredReplicas: 1 currentMetrics: - type: Resource resource: name: cpu current: averageUtilization: 0 averageValue: 0 - type: Object object: metric: name: requests-per-second describedObject: apiVersion: networking.k8s.io/v1beta1 kind: Ingress name: main-route current: value: 10k
4. Docs
https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/
https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/
https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands&n