一、前置说明

本文主要从以下几个方面介绍一下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如何工作

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