一文读懂HPA弹性扩展自定义指标和缩放策略
目录
- 1 概念
- 1.1 什么是HPA
- 1.2 HPA 的自定义指标(Custom Metrics)与扩展
- 1.3 基于多指标的 HPA
- 1.3.1 工作原理
- 1.3.2 例子:基于 CPU、内存和 QPS 的 HPA 配置
- 1.4 HPA 的扩缩容行为(Behavior)
- 1.4.1 扩缩容行为配置示例:
- 1.4.2 指定多个策略(policies)
- 2 实验:使用自定义和多指标配置 HPA
- 2.1 实验目的:
- 2.2 实验环境准备:
- 2.3 部署 Web 应用
- 2.4 配置 HPA 使用多指标和行为配置
- 2.5 生成负载测试
- 2.6 观察 HPA 行为
- 3 总结
- 4 参考资料
❤️ 摘要: 随着业务需求的多样化发展,HPA单纯依赖 CPU 和内存来控制扩缩容已经无法满足应用场景需求。因此,Kubernetes 引入了 自定义指标(Custom Metrics) 和 多指标(Multiple Metrics) 支持,以便开发者能够更灵活地定义扩缩容策略。通过这些机制,HPA 可以根据业务相关的指标(如请求数、队列长度等)来动态扩缩容。本文将详细介绍 HPA 的自定义指标、基于多指标的 HPA 配置,以及扩缩容行为的概念,并通过实验展示如何使用这些机制来优化 Kubernetes 应用的弹性扩展。
💯 本文关联以往文章:
- 《一文读懂HPA弹性扩展以及实践攻略》
- 《【Kubernetes知识点】HPA如何控制不同的资源实现自动缩放?》
- 《一文读懂Deployment以及实践攻略》
1 概念
1.1 什么是HPA
如果想更深入了解HPA弹性扩展的原理, 请先看《一文读懂HPA弹性扩展以及实践攻略》
Horizontal Pod Autoscaler (HPA) 是 Kubernetes 的一项重要功能,允许用户根据 Pod 的 CPU、内存利用率,或者其他资源使用情况,自动扩展或缩减 Pod 副本数。这使得应用在高负载下可以自动扩展来增加处理能力,而在低负载时则可以缩减以节省资源。
Horizontal Pod Autoscaler (HPA) 是 Kubernetes autoscaling
API 组中的 API 资源。Kubernetes v1.23.0版本后autoscaling/v2
API 版本转为稳定版本,其中包括对自定义指标、基于多指标方式、扩缩行为策略的支持。
1.2 HPA 的自定义指标(Custom Metrics)与扩展
传统的 HPA 使用的主要是 CPU 和内存 这两种资源利用率作为指标,但这些资源指标无法完全代表所有业务场景的需求。为此,Kubernetes 引入了 自定义指标 和 多指标 的支持。通过自定义指标,HPA 允许用户根据业务相关的指标(例如请求数、队列长度、数据库连接数等)来定义扩缩容策略。这些指标往往来自于应用的性能监控或外部监控系统(如 Prometheus)。
典型场景:
- 按照 Web 应用的 每秒请求数(QPS) 进行扩缩容。
- 根据消息队列中的 未处理消息数 扩容消费实例。
如何实现自定义指标?
为了支持自定义指标,可以使用 Prometheus Adapter 或其他监控系统来将 Prometheus 中的监控数据暴露为 Kubernetes 自定义指标, HPA 配置中引用这些自定义指标,触发扩缩容策略的执行。
1.3 基于多指标的 HPA
在许多场景中,应用的负载不仅依赖单一的资源或指标。Kubernetes 的 HPA 支持基于 多指标(Multiple Metrics) 的扩缩容。你可以为 HPA 配置多个指标,HPA 将根据所有配置的指标来决定是否进行扩缩容。
1.3.1 工作原理
- HPA 控制器会对每个指标进行独立的评估和计算。具体来说,HPA 会分别计算每个指标所推荐的扩缩容副本数(
desiredReplicas
)。 - 例如,如果你同时监控 CPU 和内存,HPA 会分别根据这两个指标计算出它们各自推荐的副本数量。假设 CPU 建议扩展到 8 个副本,而内存建议扩展到 5 个副本。
- 当多个指标计算得出的扩缩容建议不同,HPA 会选择所有建议中的 最大值 来调整副本数量。这个策略保证了即使某个资源(如 CPU 或内存)出现瓶颈,应用也能够及时扩容,以应对潜在的负载压力。
- 同时,扩容的副本数不会超过用户配置的最大副本数限制(
maxReplicas
)。
1.3.2 例子:基于 CPU、内存和 QPS 的 HPA 配置
你可以配置 HPA 同时根据 CPU、内存和 QPS 进行扩缩容。当任一指标超出阈值时,HPA 会触发扩容;当所有指标都低于阈值时,HPA 会触发缩容。
示例 YAML 配置:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:name: multi-metric-hpa
spec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: web-appminReplicas: 2maxReplicas: 10metrics:- type: Resourceresource:name: cputarget:type: UtilizationaverageUtilization: 70- type: Resourceresource:name: memorytarget:type: UtilizationaverageUtilization: 70- type: Podspods:metric:name: requests_per_secondtarget:type: AverageValueaverageValue: 100
❔说明:
- CPU 和内存:配置了 CPU 和内存的目标利用率,当任一指标超过设定的目标时如70%,将触发扩容。
- QPS 指标:使用自定义指标
requests_per_second
监控每秒的请求数,如果 QPS 超过 100,HPA 也会触发扩容。
1.4 HPA 的扩缩容行为(Behavior)
Kubernetes 中的 HPA 除了监控资源利用率,还可以通过 Behavior 配置来控制扩缩容的行为,包括:
- 扩稳定性窗口(Stabilization Window):用于避免负载短期内上升引发的频繁扩容。
- 缩容的延迟(Downscale Delay):缩容时的最小等待时间,避免短期内负载下降时立即缩容。
- 控制缩放速率: 在扩缩容过程,可以按数量和比例进行副本数调整并周期性监测执行情况。
1.4.1 扩缩容行为配置示例:
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:name: app-hpa
spec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: appminReplicas: 2maxReplicas: 15behavior:scaleUp:stabilizationWindowSeconds: 60 # 等待 60 秒再进行扩容policies:- type: Percentvalue: 100 # 每次扩容最多增加 100% 的副本数periodSeconds: 30 # 每 30 秒检查一次扩容scaleDown:stabilizationWindowSeconds: 300 # 缩容的稳定窗口为 300 秒policies:- type: Percentvalue: 50 # 每次缩容最多减少 50% 的副本数periodSeconds: 60 # 每 60 秒检查一次缩容
❔ 参数说明:
- scaleUp:每次扩容最多增加 100% 的副本数量,并有 60 秒的稳定性窗口,防止过快扩容。
- scaleDown:缩容时有 5 分钟的延迟,每次缩容最多减少 50% 的副本数量,避免因短暂的负载下降而过早缩容。
1.4.2 指定多个策略(policies)
在 behavior
字段下,可以为扩容或缩容指定多个 策略(policies)。每个策略都定义了如何在一定时间内调整 Pod 副本数量。
- Pod 数量策略:以固定数量的 Pod 来扩容或缩容。例如,配置每分钟最多减少 4 个 Pod。
- 百分比策略:以当前 Pod 副本的百分比进行扩缩容(都会向上取整)。例如,配置每分钟最多减少 10% 的副本数,即扩缩容7.2个pod,都会向上取整,就是8个。
当多个策略被指定时,默认选择 允许最大变动的策略。比如,在以下配置中:
behavior:scaleDown:policies:- type: Podsvalue: 4periodSeconds: 60- type: Percentvalue: 10periodSeconds: 60selectPolicy: Max
❔ 参数说明:
- 第一个策略表示在 60 秒内最多缩容 4 个 Pod。
- 第二个策略表示在 60 秒内最多缩容当前副本数的 10%。
selectPolicy
** 字段**可以控制选择哪种策略:Max
:选择允许副本数变动最大的策略(默认值)。Min
:选择允许副本数变动最小的策略。Disabled
:完全禁用扩容或缩容。
⚠️ 注意:
periodSeconds
设置的最大值为 1800(半小时)。
2 实验:使用自定义和多指标配置 HPA
2.1 实验目的:
通过自定义指标和多指标配置,结合扩缩容行为,观察 HPA 在不同负载下的扩缩容反应,并有效减少 Thrashing 现象。
2.2 实验环境准备:
- Kubernetes 集群
- 已安装 Prometheus 和 Prometheus Adapter
- 一个 Web 应用 Deployment(如 Nginx)
2.3 部署 Web 应用
创建一个简单的 Deployment,限制 CPU 和内存:
apiVersion: apps/v1
kind: Deployment
metadata:name: php-apache
spec:replicas: 1selector:matchLabels:run: php-apachetemplate:metadata:labels:run: php-apachespec:containers:- name: php-apacheimage: harbor.zx/hcie/hpa-exampleports:- containerPort: 80resources:requests:cpu: "100m" # CPU 请求值memory: "128Mi" # 设置内存请求值limits:cpu: "200m" # CPU 限制值memory: "256Mi" # 设置内存限制值
---
apiVersion: v1
kind: Service
metadata:name: php-apachelabels:run: php-apache
spec:ports:- port: 80selector:run: php-apache
创建Deployment
kubectl apply -f php-apache-deployment
查看deployment详细信息
[root@k8s-master1 hcie]# kubectl describe deploy php-apache
Name: php-apache
Namespace: default
CreationTimestamp: Mon, 23 Sep 2024 12:04:36 +0800
Labels: <none>
Annotations: deployment.kubernetes.io/revision: 1
Selector: run=php-apache
Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:Labels: run=php-apacheContainers:php-apache:Image: harbor.zx/hcie/hpa-examplePort: 80/TCPHost Port: 0/TCPLimits:cpu: 200mmemory: 256MiRequests:cpu: 100mmemory: 128Mi
2.4 配置 HPA 使用多指标和行为配置
编辑 HPA YAML,使用多指标(CPU、内存和 QPS)并配置扩缩容行为:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:name: php-apache-hpa
spec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: php-apacheminReplicas: 2maxReplicas: 10metrics:- type: Resourceresource:name: cputarget:type: UtilizationaverageUtilization: 50- type: Resourceresource:name: memorytarget:type: UtilizationaverageUtilization: 50- type: Podspods:metric:name: requests_per_secondtarget:type: AverageValueaverageValue: 100behavior:scaleUp:stabilizationWindowSeconds: 60policies:- type: Percentvalue: 100periodSeconds: 30scaleDown:stabilizationWindowSeconds: 300policies:- type: Percentvalue: 50periodSeconds: 60
创建HPA
kubectl apply -f php-apache-hpa.yaml
查看hpa详细信息
Name: php-apache-hpa
Namespace: default
Labels: <none>
Annotations: <none>
CreationTimestamp: Sat, 21 Sep 2024 23:20:13 +0800
Reference: Deployment/php-apache
Metrics: ( current / target )resource cpu on pods (as a percentage of request): 1% (1m) / 50%resource memory on pods (as a percentage of request): 7% (9715712) / 50%"requests_per_second" on pods: 0 / 100
Min replicas: 2
Max replicas: 10
Behavior:Scale Up:Stabilization Window: 60 secondsSelect Policy: MaxPolicies:- Type: Percent Value: 100 Period: 30 secondsScale Down:Stabilization Window: 300 secondsSelect Policy: MaxPolicies:- Type: Percent Value: 50 Period: 60 seconds
2.5 生成负载测试
使用 kubectl run
创建 BusyBox 容器,并生成负载:
kubectl run -i --tty load-generator --image=harbor.zx/hcie/busybox:1.29-2 /bin/sh
生成负载
while sleep 0.01; do wget -q -O- http://php-apache; done
2.6 观察 HPA 行为
使用以下命令观察 HPA 的扩缩容情况:
kubectl get hpa nginx-hpa --watch
观察 Pod 副本数量变化:
[root@k8s-master1 ~]# kubectl get hpa php-apache-hpa --watch
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache-hpa Deployment/php-apache 40%/50%, 8%/50% + 1 more... 2 10 2 2m
php-apache-hpa Deployment/php-apache 102%/50%, 9%/50% + 1 more... 2 10 2 2m
php-apache-hpa Deployment/php-apache 105%/50%, 9%/50% + 1 more... 2 10 2 2m
php-apache-hpa Deployment/php-apache 110%/50%, 9%/50% + 1 more... 2 10 2 2m
php-apache-hpa Deployment/php-apache 102%/50%, 9%/50% + 1 more... 2 10 2 3m
php-apache-hpa Deployment/php-apache 106%/50%, 9%/50% + 1 more... 2 10 4 3m
php-apache-hpa Deployment/php-apache 82%/50%, 9%/50% + 1 more... 2 10 4 3m
php-apache-hpa Deployment/php-apache 104%/50%, 9%/50% + 1 more... 2 10 4 3m
php-apache-hpa Deployment/php-apache 106%/50%, 9%/50% + 1 more... 2 10 4 3m
php-apache-hpa Deployment/php-apache 105%/50%, 9%/50% + 1 more... 2 10 4 4m
php-apache-hpa Deployment/php-apache 106%/50%, 9%/50% + 1 more... 2 10 5 5m
php-apache-hpa Deployment/php-apache 94%/50%, 9%/50% + 1 more... 2 10 8 6m
...
php-apache-hpa Deployment/php-apache 26%/50%, 9%/50% + 1 more... 2 10 4 11m
php-apache-hpa Deployment/php-apache 22%/50%, 9%/50% + 1 more... 2 10 4 12m
php-apache-hpa Deployment/php-apache 20%/50%, 9%/50% + 1 more... 2 10 2 13m
php-apache-hpa Deployment/php-apache 10%/50%, 9%/50% + 1 more... 2 10 2 13m
说明:
- hpa检查三项指标,当cpu负载先达到阈值, 触发扩容延迟1分钟开始执行,并且每次最多扩容100%的副本数;
- 当cpu负载下降到指标阈值时, 缩容行为延迟5分钟执行,并且每次缩容最多是当前50%的副本数。
3 总结
通过本文,我们深入探讨了 Kubernetes HPA 的自定义指标、多指标配置以及扩缩容行为策略。HPA 不再局限于简单的 CPU 和内存利用率,而是能够通过自定义指标和扩展配置更加灵活地处理复杂的业务场景。实验展示了如何使用自定义和多指标进行 HPA 配置,以及如何通过 Behavior 配置减少 Thrashing 现象。 那什么是Thrashing现象呢,预告下文:《解读HPA的 thrashing(抖动)问题》。
4 参考资料
[1] HorizontalPodAutoscalerSpec
[2]Horizontal Pod Autoscaling
[3]HorizontalPodAutoscaler Walkthrough