###前言
在kubernetes中,我們使用pod對外提供服務。這時候,我們需要以下兩種情形需要關注:
Pod因爲不明原因掛掉,導致服務不可用
Pod在高負荷的情況下,不能支撐我們的服務
如果我們人工監控pods,人工進行調整副本那麼這個工作量無疑是巨大的,但kubernetes已經有了相應的機制來應對了。
###HPA全稱Horizontal Pod Autoscaler控制器工作流程(V1版本)
更詳細的介紹參考官方文檔Horizontal Pod Autoscaler
-
流程
- 創建HPA資源對象,關聯對應資源例如Deployment,設定目標CPU使用率閾值,最大,最小replica數量。
前提:pod一定要設置資源限制,參數request,HPA纔會工作。 - HPA控制器每隔15秒鐘(可以通過設置controller manager的–horizontal-pod-autoscaler-sync-period參數設定,默認15s)通過觀測metrics值獲取資源使用信息
- HPA控制器將獲取資源使用信息與HPA設定值進行對比,計算出需要調整的副本數量
- 根據計算結果調整副本數量,使得單個POD的CPU使用率儘量逼近期望值,但不能照顧設定的最大,最小值。
- 以上2,3,4週期循環
- 創建HPA資源對象,關聯對應資源例如Deployment,設定目標CPU使用率閾值,最大,最小replica數量。
- 週期
- HPA控制器觀測資源使用率並作出決策是有周期的,執行是需要時間的,在執行自動伸縮過程中metrics不是靜止不變的,可能降低或者升高,如果執行太頻繁可能導致資源的使用快速抖動,因此控制器每次決策後的一段時間內不再進行新的決策。對於擴容這個時間是3分鐘,縮容則是5分鐘,對應調整參數
--horizontal-pod-autoscaler-downscale-delay --horizontal-pod-autoscaler-upscale-delay
- 自動伸縮不是一次到位的,而是逐漸逼近計算值,每次調整不超過當前副本數量的2倍或者1/2
本記錄是對kubernetes HPA功能的驗證,參考kubernetes官方文檔,使用的是官方文檔提供的鏡像php-apache進行測試。
- HPA控制器觀測資源使用率並作出決策是有周期的,執行是需要時間的,在執行自動伸縮過程中metrics不是靜止不變的,可能降低或者升高,如果執行太頻繁可能導致資源的使用快速抖動,因此控制器每次決策後的一段時間內不再進行新的決策。對於擴容這個時間是3分鐘,縮容則是5分鐘,對應調整參數
- metrics server
kubernetes集羣需要配置好metrics server,配置參考文檔Kubernetes部署metrics-server
###配置HPA實現應用橫向擴展
- 配置啓動deployment:php-apache
cat hpa-deployment.ymal
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-apache
labels:
app: hpa-test
spec:
replicas: 1
selector:
matchLabels:
name: php-apache
app: hpa-test
template:
metadata:
labels:
name: php-apache
app: hpa-test
spec:
containers:
- name: php-apache
image: mirrorgooglecontainers/hpa-example:latest
ports:- containerPort: 80
name: http
protocol: TCP
resources:
requests:
cpu: 0.005
memory: 64Mi
limits:
cpu: 0.05
memory: 128Mi2. 配置service: php-apache-svc
cat hpa-svc.yaml
- containerPort: 80
apiVersion: v1
kind: Service
metadata:
name: php-apache-svc
labels:
app: hpa-test
spec:
selector:
name: php-apache
app: hpa-test
ports:
- name: http
port: 80
protocol: TCP3. 配置hpa:php-apache-hpa
cat hpa-hpa.yaml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: php-apache-hpa
labels:
app: hpa-test
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 504. 啓動deployment,service,hpa,並驗證
kubectl apply -f ./
deployment.apps/php-apache configured
service/php-apache-svc unchanged
horizontalpodautoscaler.autoscaling/php-apache-hpa unchanged
kubectl get all
NAME READY STATUS RESTARTS AGE
pod/php-apache-6b9f498dc4-vwlfr 1/1 Running 0 3h14m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d20h
service/php-apache-svc ClusterIP 10.104.34.168 <none> 80/TCP 3h14m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/php-apache 1/1 1 1 3h14m
NAME DESIRED CURRENT READY AGE
replicaset.apps/php-apache-6b9f498dc4 1 1 1 3h14m
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
horizontalpodautoscaler.autoscaling/php-apache-hpa Deployment/php-apache 20%/50% 1 10 1 3h14m
###壓力測試,觀察HPA效果
>1.生成一個壓測客戶端,持續壓力測試
kubectl run --generator=run-pod/v1 -i --tty load-generator --image=busybox /bin/sh
while true; do wget -q -O- http://php-apache-svc.default.svc.cluster.local; done
OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!
>2.壓測一下,觀察結果
kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache-hpa Deployment/php-apache 800%/50% 1 10 1 27m
kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache-hpa Deployment/php-apache 1000%/50% 1 10 2 27m
kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache-hpa Deployment/php-apache 1000%/50% 1 10 4 27m
kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache-hpa Deployment/php-apache 1000%/50% 1 10 8 27m
kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache-hpa Deployment/php-apache 120%/50% 1 10 10 27m
kubectl get deployment php-apache
NAME READY UP-TO-DATE AVAILABLE AGE
php-apache 10/10 10 10 28m
#####結論:隨着壓力測試進行,deployment下pod的CPU使用率增加,超過HPA設定的百分比50%,之後逐次翻倍擴容replicaset。達到上限停止擴容。根據replicaset設置的request QoS逐漸穩定資源的使用率。
>3.停止壓測
while true; do wget -q -O- http://php-apache-svc.default.svc.cluster.local; done
OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!OK!wget: can't connect to remote host (10.104.63.73): Connection refused
OK!OK!OK!OK!OK!OK!........OK!OK!OK! ^C
/ # exit
/ # Session ended, resume using 'kubectl attach load-generator -c load-generator -i -t' command when the pod is running
#####CPU使用率恢復到最初值20%,controller會週期觀測,逐次縮容到最小值。
kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache-hpa Deployment/php-apache 20%/50% 1 10 10 36m
#等待幾分鐘之後(默認5分鐘),原因:
kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache-hpa Deployment/php-apache 20%/50% 1 10 4 41m
#再次等待幾分鐘後(默認5分鐘)
kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache-hpa Deployment/php-apache 20%/50% 1 10 2 46m
#再次等待幾分鐘後(默認5分鐘),穩定在最小副本數量
kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache-hpa Deployment/php-apache 20%/50% 1 10 1 53m
###其他
以上測試驗證了HPA功能,使用的API版本是autoscaling/v1。通過kubectl api-versions可以查看到存在3個版本。v1版本只支持CPU,v2beta2版本支持多metrics(CPU,memory)以及自定義metrics。基於autoscaling/v2beta2的hpa yaml文件寫法
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: php-apache-hpa
labels:
app: hpa-test
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