Horizontal Pod Autoscaler 根據觀察到的CPU利用率(或在支持自定義指標的狀況下,根據其餘一些應用程序提供的指標)自動伸縮 replication controller, deployment, replica set, stateful set 中的pod數量。注意,Horizontal Pod Autoscaling不適用於沒法伸縮的對象,例如DaemonSets。java
Horizontal Pod Autoscaler 被實現做爲Kubernetes API資源和控制器。該資源決定控制器的行爲。控制器會按期調整副本控制器或部署中副本的數量,以使觀察到的平均CPU利用率與用戶指定的目標相匹配。算法
1. Horizontal Pod Autoscaler 是如何工做的api
Horizontal Pod Autoscaler 實現爲一個控制循環,其週期由--horizontal-pod-autoscaler-sync-period選項指定(默認15秒)。app
在每一個週期內,controller manager都會根據每一個HorizontalPodAutoscaler定義的指定的指標去查詢資源利用率。 controller manager從資源指標API(針對每一個pod資源指標)或自定義指標API(針對全部其餘指標)獲取指標。編輯器
對於每一個Pod資源指標(好比:CPU),控制器會從資源指標API中獲取相應的指標。而後,若是設置了目標利用率值,則控制器計算利用率值做爲容器上等效的資源請求百分比。若是設置了目標原始值,則直接使用原始指標值。而後,控制器將全部目標容器的利用率或原始值(取決於指定的目標類型)取平均值,併產生一個用於縮放所需副本數量的比率。工具
若是某些Pod的容器未設置相關資源請求,則不會定義Pod的CPU使用率,而且自動縮放器不會對該指標採起任何措施。spa
2. 算法細節orm
desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]
直譯爲:(當前指標值 ➗ 指望指標值) ✖️ 當前副本數 ,結果再向上取整,最終結果就是指望的副本數量對象
例如,假設當前指標值是200m ,指望指標值是100m,指望的副本數量就是雙倍。由於,200.0 / 100.0 == 2.0 blog
若是當前值是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