自动扩缩容HPA

1、HPA的介绍

HorizontalPodAutoscaler(简称 HPA ) 自动更新工作负载资源(例如 Deployment 或者StatefulSet), 目的是自动扩缩工作负载以满足需求。
水平扩缩意味着对增加的负载的响应是部署更多的 Pod。 这与“垂直(Vertical)”扩缩不同,对于Kubernetes, 垂直扩缩意味着将更多资源(例如:内存或 CPU)分配给已经为工作负载运行的 Pod。
如果负载减少,并且 Pod 的数量高于配置的最小值, HorizontalPodAutoscaler 会指示工作负载资源(Deployment、StatefulSet 或其他类似资源)缩减。
本文档将引导你完成启用 HorizontalPodAutoscaler 以自动管理示例 Web 应用程序的扩缩的示例。 此示例工作负载是运行一些 PHP 代码的 Apache httpd

总结:HPA可根据系统负载情况(CPU、内存、磁盘、平均负载),对控制器(Deployment、statefulset、ReplicaSet)进行操作,修改副本数量,达到扩缩容的目的>

2、Metrics Service介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
Metrics:指标的意思
什么情况下扩容量:负载高
缩容:Pod 的数量高于配置的最小值

#查看node资源的使用情况
[root@master01 ~]# kubectl top node
error: Metrics API not available


官方文档地址:https://kubernetes.io/zh-cn/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/

HPA怎么知道系统负载的情况?
需要有Metrics service服务

image-20240924084519004

image-20240924085953555

image-20240924141858256

1
2
Metrics Server是Kubernetes内置自动缩放管道的可扩展、高效的容器资源度量源。
Metrics Server从Kubelets收集资源度量,并通过Metrics API在Kubernetes apiserver中公开这些度量,供Horizontal Pod Autoscaler和Vertical Pod Autocaler使用。kubectl top还可以访问度量API,从而更容易地调试自动缩放管道

版本的选择:

Metrics Server Metrics APl group/version Supported Kubernetes version
0.7.x metrics.k8s.io/v1beta1 1.19+
0.6.x metrics.k8s.io/v1beta1 1.19+
0.5.x metrics.k8s.io/v1beta1 *1.8+
0.4.x metrics.k8s.io/v1beta1 *1.8+
0.3.x metrics.k8s.io/v1beta1 1.8-1.21

3、部署Metics Server

1、部署Metics Server

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
registry.k8s.io/metrics-server/metrics-server:v0.7.2是谷歌内部镜像站下载,但是无法下载,需要手段,可以从如下地址下载
http://test.driverzeng.com/HPA/metrics-server.tar,资源清单和镜像都有

1、查看当前k8s版本
[root@master01 service]# kubectl version | grep "GitVersion:"
GitVersion:"v1.19.3"

2、建议每个node都下载镜像
wget http://test.driverzeng.com/HPA/metrics-server.tar
wget http://test.driverzeng.com/HPA/components.yaml

3、每个node导入镜像
[root@node01 ~]# docker load < metrics-server.tar

4、修改资源清单

[root@node01 ~]# mv components.yaml.1 components.yaml
[root@node01 ~]# vim components.yaml
①、删除这几行
122 strategy:
123 rollingUpdate:
124 maxUnavailable: 0
②、修改控制器资源,为了保证每台起一个所以要修改
112 将kind: Deployment 改为kind: DaemonSet


5、启动,并查看
[root@master01 kubernetes]# kubectl apply -f components.yaml
[root@master01 kubernetes]# kubectl get pod -n kube-system -owide
NAME READY STATUS RE AGE
metrics-server-9kcvb 1/1 Running 0 5h40m 10.0.0.202 node02
metrics-server-nltkh 1/1 Running 0 5h40m 10.0.0.201 node01
metrics-server-v28cw 1/1 Running 0 5h40m 10.0.0.203 node03

6、查看node节点资源的占用情况
[root@master01 kubernetes]# kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
master01 167m 16% 1248Mi 71%
node01 70m 7% 507Mi 29%
node02 73m 7% 615Mi 35%
node03 110m 5% 688Mi 20%

7、查看pod资源的占用情况
[root@master01 kubernetes]# kubectl top pod
NAME CPU(cores) MEMORY(bytes)
c7-nginx 0m 1Mi
nginx-deploy-545f948568-4tgvd 0m 2Mi
nginx-deploy-545f948568-7jnbf 0m 2Mi
nginx-deploy-545f948568-v5v82 0m 2Mi
nginx-ds-7gpkh 0m 1Mi
nginx-ds-9r2hz 0m 1Mi
nginx-ds-vmjsj 0m 2Mi

HPA就是掉node的接口获取资源信息

2、生成测试镜像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1、每个node编写php代码,创建测试首页
cat > index.php << 'EOF'
<?php
$x = 0.0001;
for ($i = 0; $i <= 1000000; $i++) {
$x += sqrt($x);
}
echo "OK!";
?>
EOF

一般做计算是cpu计算,实际上就是在压你的cpu,计算100亿次

2、每个node创建Dockerfile
cat > dockerfile << 'EOF'
FROM php:5-apache
ADD index.php /var/www/html/index.php
RUN chmod a+rx index.php
EOF


3、每个node构建镜像
docker build -t php:v1 .

3、编写资源清单

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
1、编写资源清单    kubectl run php-apache --image=php:v1 --requests=cpu=200m --expose --port=80

[root@master01 kubernetes]# vim php-dp.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-apache
spec:
replicas: 1
selector:
matchLabels:
run: php-apache
template:
metadata:
labels:
run: php-apache
spec:
containers:
- image: php:v1
imagePullPolicy: IfNotPresent
name: php-apache
#现在CPU最多使用200毫核 0.2核
resources:
requests:
cpu: 200m

2、运行,并查看
[root@master01 kubernetes]# kubectl apply -f php-dp.yml
[root@master01 kubernetes]# kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE
php-apache-869dfddb74-qgffj 1/1 Running 0 53s 10.2.3.90 node03
[root@master01 kubernetes]# curl 10.2.3.90
OK!

3、目前还没有部署HPA,
[root@master01 kubernetes]# kubectl get hpa
No resources found in default namespace.

4、刚刚部署了Metics Server,hpa才是扩容的东西,所以现在编写资源清单
编写HPA监控资源扩容php的Deployment
kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10

[root@master01 kubernetes]# vim php-hpa.yml
apiVersion: "autoscaling/v1"
kind: "HorizontalPodAutoscaler"
metadata:
name: php-apache
namespace: default
spec:
#自动扩容最大扩到多少
maxReplicas: 8
#自动扩容最大扩到多少
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
targetCPUUtilizationPercentage: 50


5、启动hpa资源
[root@master01 kubernetes]# kubectl apply -f php-hpa.yml
[root@master01 kubernetes]# kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 0%/50% 1 8 1 16s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#你想让哪个Deployment控制器自动扩缩容,就要谁的HPA资源清单,wordpress自动扩缩容,就要写wordpress的HPA资源监控wordpress

apiVersion: "autoscaling/v1" #HPA接口
kind: "HorizontalPodAutoscaler" #HPA资源类型
metadata: #HPA元数据
name: php-apache #HPA资源名
namespace: default #名称空间
spec: #HPA控制信息
maxReplicas: 8 #最多扩容8个副本
minReplicas: 1 #最少扩容1个副本
scaleTargetRef: #HPA关联控制器
apiVersion: apps/v1 #控制器的接口
kind: Deployment #控制器类型
name: php-apache #控制器名字
targetCPUUtilizationPercentage: 50 #CPU使用率达到50%则扩容

4、压测

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
33
34
35
36
37
1、查看需要压测的pod的ip
[root@master01 kubernetes]# kubectl get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE
php-apache-869dfddb74-qgffj 1/1 Running 0 28m 10.2.3.90 node03

2、写循环脚本压测
打开2个窗口,执行如下命令,压测效果就比较明显
[root@master01 kubernetes]# while true ;do curl 10.2.3.90;sleep 0.2;done
OK!OK!OK!OK!OK!OK!OK!OK!OK

3、再开一个master窗口,查看cup的使用率,需要等待一下下,才可以看到cpu变化
[root@master01 ~]# kubectl get hpa -w
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 0%/50% 1 8 1 6m37s
php-apache Deployment/php-apache 386%/50% 1 8 1 8m38s
php-apache Deployment/php-apache 386%/50% 1 8 4 8m53s
php-apache Deployment/php-apache 386%/50% 1 8 8 9m9s
php-apache Deployment/php-apache 103%/50% 1 8 8 9m39s

4、再开一个窗口,查看pod的副本数量,可以看到,cpu使用率增加,pod的副本增加,此时已经增加到8个了
[root@master01 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
php-apache-869dfddb74-2x25m 1/1 Running 0 64s
php-apache-869dfddb74-884jw 1/1 Running 0 79s
php-apache-869dfddb74-m6vb7 1/1 Running 0 64s
php-apache-869dfddb74-mck7s 1/1 Running 0 64s
php-apache-869dfddb74-mg9pf 1/1 Running 0 79s
php-apache-869dfddb74-qgffj 1/1 Running 0 35m
php-apache-869dfddb74-t49wf 1/1 Running 0 64s
php-apache-869dfddb74-xdtv6 1/1 Running 0 79s

5、停止压测命令,稍等一会,查看pod的副本数量,可以看到,cpu使用率减少,pod数量减少,变成1个pod
[root@master01 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
php-apache-869dfddb74-884jw 1/1 Running 0 8m54s

压力减小没有立马缩容,就像搞大活动618,用户量有一部分买完产品了,如果突然又上了产品就不会缩容。这个设计很合理的,他会觉得没有什么大流量,就会缩容