一、前置说明¶
本文主要从以下几个方面介绍一下Pod水平自动扩缩:
- Pod水平自动扩缩-HPA是什么
- Pod水平自动扩缩是如何工作的
- Pod水平自动扩缩注意事项
- Pod水平自动扩缩接口类型
- Pod水平自动扩缩示例说明
二、HPA学习重点¶
大家都知道HPA是通过持续监控Pod的资源使用指标(CPU利用率、内存利用率等)来判断是否扩缩容pod数量,但是这个Pod的资源使用指标是从哪儿获取的呢?
重点:Pod的资源使用指标是从Metric server中进行获取
三、HPA是什么¶
在 Kubernetes 中,HorizontalPodAutoscaler自动更新工作负载资源 (例如Deployment或者StatefulSet), 目的是自动扩缩工作负载以满足需求。
Pod水平自动扩缩相对于垂直扩缩所用资源相对较少。
如果负载减少,并且Pod的数量高于配置的最小值, HorizontalPodAutoscaler 会指示工作负载资(Deployment、StatefulSet 或其他类似资源)缩减。
由于DaemonSet会在每个节点上都会部署,不适用于水平Pod自动扩缩。
四、HPA如何工作¶

Kubernetes 将水平 Pod 自动扩缩实现为一个间歇运行的控制回路(它不是一个连续的过程)。间隔由 kube-controller-manager的 --horizontal-pod-autoscaler-sync-period 参数设置(默认间隔为15 秒)。
在每个时间段内,控制器管理器都会根据每个 HorizontalPodAutoscaler 定义中指定的指标查询资源利用率。 控制器管理器找到由 scaleTargetRef 定义的目标资源,然后根据目标资源的 .spec.selector 标签选择 Pod, 并从资源指标 API(针对每个 Pod 的资源指标)或自定义指标获取指标 API(适用于所有其他指标)。
五、HPA使用注意事项¶
Pod水平自动扩缩注意事项有以下方面:
- 必须安装metrics-server或其他自定义metrics-server
- 必须配置requests参数
- 不能扩容无法缩放的对象,比如DaemonSet
列出与监控指标相关的API资源
[root@k8s-master01 ~]# k api-resources | grep metrics
nodes metrics.k8s.io/v1beta1 false NodeMetrics
pods metrics.k8s.io/v1beta1 true PodMetrics
六、HPA接口类型¶
可以通过以下命令查看所有Pod水平自动扩缩接口类型:
$ k get apiservices | grep autoscal
v1.autoscaling Local True 8d
v2.autoscaling Local True 8d
v2beta1.autoscaling Local True 8d
v2beta2.autoscaling Local True 8d
其中主要分为v1和v2,v2又分为v2beta1和v2beta2:
- v1:稳定版自动水平伸缩,只支持CPU指标
- v2beta1:支持CPU、内存和自定义指标
- v2beta2:支持CPU、内存、自定义指标Custom和额外指标ExternalMetrics
七、HPA实战示例¶
下面进行演示Pod水平自动扩缩示例,示例步骤如下:
- 启动一个Deployment 并暴露服务
- 创建HPA
- 模拟压力测试
7.1 启动一个Deployment 并暴露服务¶
1.定义一个yaml文件
$ vim hap-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: hpa-nginx
name: hpa-nginx
spec:
replicas: 1
selector:
matchLabels:
app: hpa-nginx
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: hpa-nginx
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/zq-demo/nginx:1.14.2
name: nginx
resources:
requests:
cpu: 10m
status: {}
2.创建Deployment
$ k create -f hap-nginx.yaml
deployment.apps/hpa-nginx created
3.查看pod
$ k get po
hpa-nginx-6587cc8776-2wvpm 1/1 Running 0 4s
4.暴露出80端口
$ k expose deployment hpa-nginx --port=80
service/hpa-nginx exposed
5.验证服务暴露是否成功
(1)查看服务IP
$ k get svc hpa-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hpa-nginx ClusterIP 10.0.148.68 <none> 80/TCP 88s
(2)测试服务,观察到返回200
$ curl -I 10.0.148.68 2>/dev/null | head -1 | awk '{print $2}'
200
6.查看cpu指标
$ k top po
NAME CPU(cores) MEMORY(bytes)
hpa-nginx-6587cc8776-2wvpm 0m 4Mi
7.2 创建HPA¶
1.启动水平自动扩缩器
$ k autoscale deployment hpa-nginx --cpu-percent=10 --min=1 --max=10
horizontalpodautoscaler.autoscaling/hpa-nginx autoscaled
上面参数说明:
- --cpu-percent=10:指定 Deployment 的目标 CPU 利用率百分比。水平 Pod 自动缩放器将根据当前 CPU 利用率自动调整副本数量,以尝试维持此目标。
- --min=1:指定 Deployment 应具有的最小副本数。即使 CPU 利用率很低,水平 Pod 自动缩放器也不会将 Deployment 缩小到此数以下。
- --max=10:指定 Deployment 应具有的最大副本数。如果 CPU 利用率非常高,水平 Pod 自动缩放器也不会将 Deployment 扩展到此数以上。
2.检查新制作的HorizontalPodAutoscaler的当前状态
$ k get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
hpa-nginx Deployment/hpa-nginx 0%/10% 1 10 1 68s
7.3 模拟压力测试¶
1.设置死循环进行测试,这里的IP为svc显示的IP
$ while true; do wget -q -O- http://10.0.148.68 > /dev/null; done
2.查看pod状态,发现pod节点已经扩容
$ k get po
NAME READY STATUS RESTARTS AGE
hpa-nginx-6587cc8776-2wvpm 1/1 Running 0 24m
hpa-nginx-6587cc8776-48nnd 1/1 Running 0 32s
hpa-nginx-6587cc8776-b8psb 1/1 Running 0 32s
hpa-nginx-6587cc8776-bnjbx 1/1 Running 0 32s
hpa-nginx-6587cc8776-l2kgs 1/1 Running 0 47s
hpa-nginx-6587cc8776-l944j 1/1 Running 0 32s
hpa-nginx-6587cc8776-njnkl 1/1 Running 0 17s
hpa-nginx-6587cc8776-p82s6 1/1 Running 0 47s
hpa-nginx-6587cc8776-r6lgg 1/1 Running 0 47s
hpa-nginx-6587cc8776-rcnbs 1/1 Running 0 17s
3.按ctrl +c 停止死循环
4.查看hpa,观察已低于10%。等待pod节点缩容
$ k get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
hpa-nginx Deployment/hpa-nginx 0%/10% 1 10 10 10m
5.查看pod,观察pod节点已缩容
$ k get po
hpa-nginx-6587cc8776-2wvpm 1/1 Running 0 98m