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 可以允许访问所有的度量指标。 当暴露这些服务时,系统管理员需要仔细考虑这个问题。

相关推荐
putItInYourHand1 小时前
Docker Compose 部署 Mosquitto MQTT Broker 完整实战指南
运维·docker·容器
生活爱好者!10 小时前
哇!影视新玩法!docker部署NEOWATCH NAS
运维·docker·容器
cpolar技术支持13 小时前
Docker 容器启动失败怎么查?端口、日志、权限与网络排障完整教程
linux·docker·容器·cpolar·网络排障
Lsetea15 小时前
Kubernetes 1.37 Pod证书怎么签发:Signer与mTLS信任链排查
云原生·kubernetes·ssl证书·tls·mtls
新时代牛马16 小时前
docker run 起不来?从dockerd、containerd 到runc 一条线讲透
运维·docker·容器
努力努力再努力wz17 小时前
【Docker 入门系列】:从 Namespace、CGroup 到 LXC:理解容器运行时、rootfs 与 LXC 实战
运维·docker·容器
JavaPub-rodert18 小时前
Docker 多阶段构建:为什么生产环境镜像可以小 90%
运维·docker·容器
2601_9622184719 小时前
万象生鲜系统多账套隔离技术适配集团生鲜企业集团化数字化管控
大数据·运维·微服务·云原生·架构
@PHARAOH19 小时前
WHAT - 微服务统一入口配置原理
微服务·云原生·架构
PC2005-cloud20 小时前
Qdrant 连接失败排查:localhost 解析到 __1,而 Docker 只绑了 IPv4
运维·docker·容器