HPA简介

在前面的学习中我们使用用一个 kubectl scale 命令可以来实现 Pod 的扩缩容功能,但是这个毕竟是完全手动操作的,要应对线上的各种复杂情况,我们需要能够做到自动化去感知业务,来自动进行扩缩容。为此,Kubernetes 也为我们提供了这样的一个资源对象:Horizontal Pod Autoscaling(Pod 水平自动伸缩),简称HPA,HPA 通过监控分析一些控制器控制的所有 Pod 的负载变化情况来确定是否需要调整 Pod 的副本数量

我们可以简单的通过 kubectl autoscale 命令来创建一个 HPA 资源对象,HPA Controller默认30s轮询一次(可通过 kube-controller-manager--horizontal-pod-autoscaler-sync-period 参数进行设置),查询指定的资源中的 Pod 资源使用率,并且与创建时设定的值和指标做对比,从而实现自动伸缩的功能。

在配置HPA前,需要先部署Metrics-Server,需要Metrics-Server提供 资源信息;

部署Pod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[root@pool1 hpa-demo]# vi hpa-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hpa-demo
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: zx/nginx:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
resources: # 想要Pod实现HPA自动扩缩容,前提必须配置resources资源请求;
requests:
memory: 50Mi
cpu: 50m
limits:
memory: 100Mi
cpu: 100m

部署Deployment

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[root@pool1 hpa-demo]# kubectl apply -f hpa-demo.yaml 
deployment.apps/hpa-demo created
[root@pool1 hpa-demo]# kubectl get pod -l app=nginx
NAME READY STATUS RESTARTS AGE
hpa-demo-687f444c8c-sggmf 1/1 Running 0 5s
[root@pool1 hpa-demo]# kubectl autoscale deployment hpa-demo --cpu-percent=10 --min=1 --max=10
horizontalpodautoscaler.autoscaling/hpa-demo autoscaled
[root@pool1 hpa-demo]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
hpa-demo Deployment/hpa-demo <unknown>/10% 1 10 0 13s
[root@pool1 hpa-demo]# kubectl describe hpa hpa-demo
Name: hpa-demo
Namespace: default
Labels: <none>
Annotations: <none>
CreationTimestamp: Thu, 16 Dec 2021 16:50:42 +0800
Reference: Deployment/hpa-demo
Metrics: ( current / target )
resource cpu on pods (as a percentage of request): 0% (0) / 10%
Min replicas: 1
Max replicas: 10
Deployment pods: 1 current / 1 desired
Conditions:
Type Status Reason Message
---- ------ ------ -------
AbleToScale True ScaleDownStabilized recent recommendations were higher than current one, applying the highest recent recommendation
ScalingActive True ValidMetricFound the HPA was able to successfully calculate a replica count from cpu resource utilization (percentage of request)
ScalingLimited False DesiredWithinRange the desired count is within the acceptable range
Events: <none>

可以看到HPA资源对象已经正常启用了

Pod压力测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
[root@pool1 hpa-demo]# kubectl get pod -l app=nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
hpa-demo-687f444c8c-8b5p8 1/1 Running 0 89s 10.244.52.226 pool2 <none> <none>
[root@pool1 hpa-demo]# kubectl run -it centos-test --image centos:7
[root@centos-test /]# while true;do curl -I 10.244.206.20;done
HTTP/1.1 200 OK
Server: nginx/1.11.1
Date: Thu, 16 Dec 2021 09:05:40 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Fri, 22 May 2020 03:19:30 GMT
Connection: keep-alive
ETag: "5ec744c2-264"
Accept-Ranges: bytes
···
# 另开终端查看HPA效果
[root@pool1 ~]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
hpa-demo Deployment/hpa-demo 88%/10% 1 10 9 14m
[root@pool1 ~]# kubectl get pod -l app=nginx
NAME READY STATUS RESTARTS AGE
hpa-demo-687f444c8c-8b5p8 1/1 Running 0 33s
hpa-demo-687f444c8c-9xmpp 1/1 Running 0 48s
hpa-demo-687f444c8c-fx525 1/1 Running 0 48s
hpa-demo-687f444c8c-hkhpm 1/1 Running 0 64s
hpa-demo-687f444c8c-lvh5z 1/1 Running 0 64s
hpa-demo-687f444c8c-mnbx2 1/1 Running 0 48s
hpa-demo-687f444c8c-sggmf 1/1 Running 0 18m
hpa-demo-687f444c8c-shbpq 1/1 Running 0 48s
hpa-demo-687f444c8c-z2kk7 1/1 Running 0 64s
[root@pool1 ~]# kubectl get pod -l app=nginx | wc -l
10

从一个Pod自动扩容到9个Pod,成功实现HPA自动扩容

等待5分钟自动缩放

1
2
3
[root@pool1 ~]# kubectl get deployment hpa-demo
NAME READY UP-TO-DATE AVAILABLE AGE
hpa-demo 1/1 1 1 29m

成功从9个Pod缩放到1个Pod

缩放问题

从 Kubernetes v1.12 版本开始我们可以通过设置 kube-controller-manager 组件的--horizontal-pod-autoscaler-downscale-stabilization 参数来设置一个持续时间,用于指定在当前操作完成后,HPA 必须等待多长时间才能执行另一次缩放操作。默认为5分钟,也就是默认需要等待5分钟后才会开始自动缩放。