K8S Pod 水平自动扩缩容 HPA

介绍

HPA(Horizontal Pod Autoscaler)水平扩缩意味着可根据观察到的CPU、内存使用率或自定义度量标准来自动扩展或缩容Pod的数量(Deployment、StatefulSet 或其他类似资源)。与"垂直"扩缩不同,对于 K8S, 垂直扩缩意味着将更多资源(例如:内存或 CPU)分配给已经为工作负载运行的 Pod。HPA不适用于无法缩放的对象。(例如:DaemonSet)

安装Metrics Server

要实现HPA自动扩缩容需要安装Metrics Server插件

Metrics Server 官网,根据自己K8S版本安装合适的插件。

bash 复制代码
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

安装好以后测试如下

bash 复制代码
[root@master01 ~]# kubectl top po -n kube-system 
NAME                                       CPU(cores)   MEMORY(bytes)   
calico-kube-controllers-54cbfb689f-stf9f   3m           44Mi            
calico-node-2v2pk                          20m          178Mi           
calico-node-djvsw                          23m          201Mi           
calico-node-gfjw9                          26m          182Mi           
calico-node-hhsnx                          24m          176Mi           
calico-node-z9mrv                          28m          170Mi           
coredns-65599ffb58-jx78h                   2m           23Mi            
metrics-server-6b7745d9f-dfk7f             5m           36Mi 

部署 php-apache 服务

为了演示 HPA,首先启动一个 Deployment 用 hpa-example 镜像运行一个容器

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: php-apache
spec:
  selector:
    matchLabels:
      run: php-apache
  template:
    metadata:
      labels:
        run: php-apache
    spec:
      containers:
      - name: php-apache
        image: deis/hpa-example
        ports:
        - containerPort: 80
        resources:
          limits:
            cpu: 500m
          requests:
            cpu: 200m
---
apiVersion: v1
kind: Service
metadata:
  name: php-apache
  labels:
    run: php-apache
spec:
  ports:
  - port: 80
  selector:
    run: php-apache

创建 HPA

使用 kubectl 创建自动扩缩器。 kubectl autoscale 创建 HPA 的命令, 该 HPA 维护由你在这些说明的第一步中创建的 php-apache Deployment 控制的 Pod 存在 1 到 20 个副本。

创建HPA:

目前支持的资源度量指标为CPU和内存,并且基本都是用CPU,内存在有一些java项目上面会有问题,比如Java项目访问量激增以后内存使用率上去了,但是访问量下来以后内存使用率并不会下来。

bash 复制代码
# 基于CPU使用率扩容的
kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=20

查看创建的HPA

bash 复制代码
[root@master01 ~]# kubectl get hpa
NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   0%/50%    1         20        1          24s

注意当前的 CPU 利用率是 0%,这是由于我们尚未发送任何请求到服务器 (TARGET 列显示了相应 Deployment 所控制的所有 Pod 的平均 CPU 利用率)。

增加负载

启动一个不同的 Pod 作为客户端。 客户端 Pod 中的容器在无限循环中运行,向 php-apache 服务发送查询。

bash 复制代码
# 在单独的终端中运行它
# 以便负载生成继续,你可以继续执行其余步骤
kubectl run -i --tty load-generator --rm --image=busybox:1.28 --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://php-apache; done"

测试完以后按 Ctrl+C 结束

bash 复制代码
kubectl get hpa php-apache -w

负载升高HPA自动扩容

bash 复制代码
[root@master01 ~]# kubectl get hpa -w
NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   49%/50%    1         20        1          6m22s
php-apache   Deployment/php-apache   250%/50%   1         20        1          6m30s
php-apache   Deployment/php-apache   250%/50%   1         20        4          6m45s
php-apache   Deployment/php-apache   250%/50%   1         20        5          7m
php-apache   Deployment/php-apache   251%/50%   1         20        5          7m15s
php-apache   Deployment/php-apache   249%/50%   1         20        5          7m30s

结束请求以后自动缩容

一旦 CPU 利用率降至 0,HPA 会自动将副本数缩减为 1。自动扩缩完成副本数量的改变可能需要几分钟的时间。

bash 复制代码
[root@master01 ~]# kubectl get hpa -n apps -w
NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   49%/50%    1         20        1          6m22s
php-apache   Deployment/php-apache   250%/50%   1         20        1          6m30s
php-apache   Deployment/php-apache   250%/50%   1         20        4          6m45s
php-apache   Deployment/php-apache   250%/50%   1         20        5          7m
php-apache   Deployment/php-apache   251%/50%   1         20        5          7m15s
php-apache   Deployment/php-apache   249%/50%   1         20        5          7m30s
php-apache   Deployment/php-apache   124%/50%   1         20        5          7m45s
php-apache   Deployment/php-apache   0%/50%     1         20        4          8m15s
php-apache   Deployment/php-apache   0%/50%     1         20        4          12m
php-apache   Deployment/php-apache   0%/50%     1         20        2          12m
php-apache   Deployment/php-apache   1%/50%     1         20        1          13m

查看生成的HPA yaml文件

查看命令

bash 复制代码
kubectl get hpa php-apache -oyaml

HPA yaml 文件

yaml 复制代码
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler   # 资源类型
metadata:
  name: php-apache    # HPA对象的名称是"php-apache
spec:
  maxReplicas: 20     # 指定了可以扩展到的最大Pod数量,这里是20个
  metrics:
  - resource:
      name: cpu       # 度量标准的名称是CPU 
      target:
        averageUtilization: 50  # 目标CPU利用率是50%
        type: Utilization     # 度量标准的类型是利用率
    type: Resource
  minReplicas: 1    # 这指定了可以扩展到的最小Pod数量,这里是1个
  scaleTargetRef:
    apiVersion: apps/v1 # Deployment对象的API版本
    kind: Deployment    # 目标资源的类型是Deployment
    name: php-apache    # 目标资源的名称是"php-apache

基于多项度量指标和自定义度量指标自动扩缩

Pod 度量指标

这些指标从某一方面描述了 Pod, 在不同 Pod 之间进行平均,并通过与一个目标值比对来确定副本的数量。 它们的工作方式与资源度量指标非常相像,只是它们仅支持 target 类型为 AverageValue。

yaml 复制代码
type: Pods
pods:
  metric:
    name: packets-per-second
  target:
    type: AverageValue
    averageValue: 1k

Object 度量指标

这些度量指标用于描述在相同名字空间中的别的对象,而非 Pod。 注意这些度量指标不一定来自某对象,它们仅用于描述这些对象。 对象度量指标支持的 target 类型包括 Value 和 AverageValue。 如果是 Value 类型,target 值将直接与 API 返回的度量指标比较, 而对于 AverageValue 类型,API 返回的度量值将按照 Pod 数量拆分, 然后再与 target 值比较。 下面的 YAML 文件展示了一个表示 requests-per-second 的度量指标。

yaml 复制代码
type: Object
object:
  metric:
    name: requests-per-second
  describedObject:
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    name: main-route
  target:
    type: Value
    value: 2k

基于Ingress的请求速率这样的度量标准,您可能需要实现一个自定义metrics API,该API能够监控Ingress对象的请求速率,并将这些数据暴露给Kubernetes的metrics server或HPA。然后,您可以在HPA的配置中引用这个自定义度量标准,以便根据Ingress的请求速率来自动扩展Pod。

示例:

如果你指定了多个上述类型的度量指标,HorizontalPodAutoscaler 将会依次考量各个指标。 HorizontalPodAutoscaler 将会计算每一个指标所提议的副本数量,然后最终选择一个最高值。

比如,如果你的监控系统能够提供网络流量数据,你可以通过 kubectl edit 命令将上述 Horizontal Pod Autoscaler 的定义更改为:

yaml 复制代码
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: php-apache
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 # CPU使用率
  - type: Pods
    pods:
      metric:
        name: packets-per-second
      target:
        type: AverageValue
        averageValue: 1k  # 每秒请求1000个数据包
  - type: Object
    object:
      metric:
        name: requests-per-second
      describedObject:
        apiVersion: networking.k8s.io/v1
        kind: Ingress
        name: main-route
      target:
        type: Value
        value: 10k  # 请求服务总数达到每秒10000次

这样,你的 HorizontalPodAutoscaler 将会尝试确保每个 Pod 的 CPU 利用率在 50% 以内, 每秒能够服务 1000 个数据包请求, 并确保所有在 Ingress 后的 Pod 每秒能够服务的请求总数达到 10000 个。

基于与 K8S 对象无关的度量指标

例如,如果你的应用程序处理来自主机上消息队列的任务, 为了让每 30 个任务有 1 个工作者实例,你可以将下面的内容添加到 HorizontalPodAutoscaler 的配置中。

yaml 复制代码
- type: External
  external:
    metric:
      name: queue_messages_ready
      selector:
        matchLabels:
          queue: "worker_tasks"
    target:
      type: AverageValue
      averageValue: 30

推荐使用定制度量指标而不是外部度量指标,因为这便于让系统管理员加固定制度量指标 API。 而外部度量指标 API 可以允许访问所有的度量指标。 当暴露这些服务时,系统管理员需要仔细考虑这个问题。

相关推荐
ZHOU西口1 小时前
微服务实战系列之玩转Docker(十八)
分布式·docker·云原生·架构·数据安全·etcd·rbac
牛角上的男孩2 小时前
Istio Gateway发布服务
云原生·gateway·istio
JuiceFS3 小时前
好未来:多云环境下基于 JuiceFS 建设低运维模型仓库
运维·云原生
景天科技苑4 小时前
【云原生开发】K8S多集群资源管理平台架构设计
云原生·容器·kubernetes·k8s·云原生开发·k8s管理系统
wclass-zhengge5 小时前
K8S篇(基本介绍)
云原生·容器·kubernetes
颜淡慕潇5 小时前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
川石课堂软件测试7 小时前
性能测试|docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台
运维·javascript·深度学习·jmeter·docker·容器·grafana
昌sit!13 小时前
K8S node节点没有相应的pod镜像运行故障处理办法
云原生·容器·kubernetes
A ?Charis16 小时前
Gitlab-runner running on Kubernetes - hostAliases
容器·kubernetes·gitlab
wclass-zhengge16 小时前
Docker篇(Docker Compose)
运维·docker·容器