title: “K8s 系列 | 第 17 天:HPA 水平自动扩缩:基于 CPU/内存/自定义指标的弹性伸缩”
tags:
– Kubernetes
– K8s系列
– DevOps
– HPA
– 自动扩缩
– 弹性伸缩
– 云原生
– 第3周
第 17/30 天
引言
在 Kubernetes 集群中,应用的负载总是在动态变化的:白天流量高峰、夜间低谷、大促期间的突发流量……传统运维模式下需要人工扩容或提前预留大量资源,不仅成本高昂,而且响应不够及时。
Horizontal Pod Autoscaler(HPA) 是 Kubernetes 内置的自动扩缩组件,它能够根据 CPU 使用率、内存使用率或自定义监控指标(如 QPS、连接数)自动调整 Pod 的副本数量,让应用始终以合适的规模运行。本文将深入解析 HPA 的工作原理、配置方式、高级用法以及生产实践中的关键注意事项。
核心概念
什么是 HPA?
HPA 是 Kubernetes 的一个控制器,它会周期性地检查目标资源(如 Deployment 或 StatefulSet)的监控指标,根据指标值与目标值的比率计算出期望的副本数,然后更新资源的 replicas 字段。
期望副本数 = ceil(当前副本数 × (当前指标值 / 目标指标值))
例如:当前有 2 个 Pod,平均 CPU 使用率为 80%,目标设置为 50%,则:
期望副本数 = ceil(2 × (80% / 50%)) = ceil(3.2) = 4
HPA 版本演进
| 版本 | API 路径 | 说明 |
|---|---|---|
| v1 | autoscaling/v1 | 仅支持 CPU 指标 |
| v2beta2 | autoscaling/v2beta2 | 支持 CPU、内存、自定义指标、多指标 |
| v2 | autoscaling/v2 | 稳定版,GA 于 K8s 1.23+ |
生产环境推荐使用 autoscaling/v2,支持更丰富的指标来源。
核心组件
┌─────────────────────────────────────────────────┐
│ HPA Controller │
│ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
│ │指标采集器 │──▶│ 计算引擎 │──▶│ 更新控制器 │ │
│ └──────────┘ └──────────┘ └──────┬────────┘ │
│ │ │ │
└────────┼───────────────────────────────┼──────────┘
▼ ▼
┌────────────┐ ┌───────────────┐
│ Metrics │ │ Deployment / │
│ Server / │ │ StatefulSet │
│Prometheus │ │ .spec.replicas│
└────────────┘ └───────────────┘
实战步骤
1. 部署测试应用
首先创建一个简单的 Deployment 和 Service 用于测试 HPA:
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-apache
namespace: hpa-demo
spec:
selector:
matchLabels:
run: php-apache
replicas: 1
template:
metadata:
labels:
run: php-apache
spec:
containers:
- name: php-apache
image: registry.k8s.io/hpa-example
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
---
apiVersion: v1
kind: Service
metadata:
name: php-apache
namespace: hpa-demo
spec:
ports:
- port: 80
selector:
run: php-apache
2. 创建基于 CPU 的 HPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: php-apache-hpa
namespace: hpa-demo
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
使用 kubectl 创建:
# 创建命名空间
kubectl create namespace hpa-demo
# 部署应用
kubectl apply -f php-apache-deploy.yaml -n hpa-demo
# 创建 HPA
kubectl apply -f php-apache-hpa.yaml -n hpa-demo
# 查看 HPA 状态
kubectl get hpa -n hpa-demo
# 实时监控 HPA 变化
kubectl get hpa -n hpa-demo -w
3. 验证自动扩缩:模拟负载
# 启动一个临时 Pod 用来发送压力请求
kubectl run -i --tty load-generator --rm
--image=busybox:1.28
--restart=Never
-n hpa-demo
-- /bin/sh -c "while sleep 0.01; do wget -q -O- http://php-apache.hpa-demo.svc.cluster.local; done"
在另一个终端观察 HPA 变化:
# 观察副本数自动增长
kubectl get hpa php-apache-hpa -n hpa-demo -w
当 CPU 使用率持续超过 50%,HPA 会增加 Pod 副本数。停止负载后几分钟,副本数会逐步降回最小值。
4. 配置基于内存的 HPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: memory-based-hpa
namespace: hpa-demo
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70
5. 配置基于自定义指标的 HPA(Prometheus + KEDA)
生产环境中往往需要根据每秒请求数(RPS)、队列长度、连接数等业务指标进行扩缩。这里推荐使用 KEDA(Kubernetes Event-driven Autoscaling):
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: prometheus-scaledobject
namespace: hpa-demo
spec:
scaleTargetRef:
name: php-apache
minReplicaCount: 1
maxReplicaCount: 20
triggers:
- type: prometheus
metadata:
serverAddress: http://prometheus.monitoring.svc.cluster.local:9090
metricName: http_requests_per_second
query: |
sum(rate(http_requests_total{namespace="hpa-demo"}[2m]))
threshold: "100"
6. 多指标组合 HPA
同时指定多个指标,HPA 会选择所有指标中计算出的最大副本数:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: multi-metric-hpa
namespace: hpa-demo
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
- type: Pods
pods:
metric:
name: requests_per_second
target:
type: AverageValue
averageValue: "1000"
常见问题
❓ HPA 扩缩为什么有延迟?
HPA 默认每 15 秒采集一次指标,但指标本身也有延迟(metrics-server 默认 60 秒更新一次)。从负载突增到完成扩容,通常需要 1-3 分钟。对于延迟敏感的场景,可以考虑:
- 使用 KEDA 支持的事件驱动扩缩(基于 Kafka 队列深度、RabbitMQ 消息数等)
- 配置 cluster-proportional-autoscaler 进行提前扩容
- 结合 VPA 和 Cluster Autoscaler 做协同扩缩
❓ 为什么 Pod 数没有降下来?
HPA 有冷却机制(--horizontal-pod-autoscaler-downscale-stabilization,默认 5 分钟),防止指标抖动导致频繁扩缩。可以通过 HPA 的 behavior 字段自定义:
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # 冷却窗口
policies:
- type: Percent
value: 10
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Pods
value: 4
periodSeconds: 60
- type: Percent
value: 100
periodSeconds: 60
selectPolicy: Max
❓ Pod 必须有 resource requests 吗?
是的! HPA 基于 CPU/内存的指标要求目标 Pod 必须设置了 resources.requests.cpu 或 resources.requests.memory,否则 metrics-server 无法采集 Pod 的资源使用率。
生产最佳实践
- 始终设置 requests 和 limits:没有 resource 限制的 Pod 无法被 HPA 有效管理
- 冷却时间配置:根据业务波动特征调整
behavior.scaleDown窗口,避免扩缩震荡 - 最小副本数 ≥ 2:防止单点故障,保障滚动更新时仍有可用副本
- 多指标组合:不要只依赖 CPU,加入内存或业务指标以获得更准确的扩缩决策
- 容量规划兜底:HPA 的最大副本数受集群资源限制,提前预留 Node 资源或启用 Cluster Autoscaler
- 监控与告警:对 HPA 自身行为进行监控,设置副本达到上限时的告警通知
- 预配置 vs 响应式:对于已知的流量高峰(如秒杀、促销),提前扩容比 HPA 响应更可靠
总结
HPA 是实现 Kubernetes 应用弹性伸缩的核心工具。从简单的 CPU 指标到复杂的多指标组合,再到基于 Prometheus 和 KEDA 的事件驱动扩缩,HPA 体系提供了从开发到生产的完整解决方案。
关键要点:
– HPA 通过指标比率计算目标副本数,支持 CPU、内存、自定义指标
– 使用 autoscaling/v2 API 获取最丰富的功能集
– 自定义指标需配合 metrics-server 或 Prometheus Adapter
– 通过 behavior 字段自定义扩缩策略以适应业务特点
– 结合 PodDisruptionBudget、Cluster Autoscaler 构建完整的弹性体系
下期预告
第 18 天:VPA 与 Cluster Autoscaler:资源与集群层的自动扩缩——如果说 HPA 解决的是”横向加机器”的问题,那 VPA 解决的是”给机器加资源”的问题,而 Cluster Autoscaler 则负责”整个集群加节点”。三剑合璧,打造真正的全栈自动弹性伸缩体系!
📚 系列目录
– 第 1 天:Kubernetes 是什么?核心概念与架构全景解析
– 第 2 天:手把手搭建你的第一个 K8s 集群(kubeadm 实战)
– 第 3 天:Pod 详解
– 第 4 天:Deployment 与 ReplicaSet
– 第 5 天:Service 与网络基础
– 第 6 天:Namespace 与资源配额
– 第 7 天:ConfigMap 与 Secret
– 第 8 天:Volume 与 PersistentVolume
– 第 9 天:StorageClass 与动态存储供给实战
– 第 10 天:StatefulSet:有状态应用的部署与管理
– 第 11 天:Ingress 与 Ingress Controller
– 第 12 天:NetworkPolicy
– 第 13 天:Headless Service 与服务发现
– 第 14 天:CSI 存储插件与生产存储选型指南
– 第 15 天:污点与容忍度:掌控 Pod 调度
– 第 16 天:Node Affinity 与 Pod Affinity
– ▶ 第 17 天:HPA 水平自动扩缩(本篇)
– [第 18 天:VPA 与 Cluster Autoscaler(待发布)]
– [第 19 天:Job 与 CronJob(待发布)]
– [第 20 天:PriorityClass 与抢占式调度(待发布)]
– [第 21 天:资源配额与 LimitRange(待发布)]
– … 后续更多精彩内容,敬请期待!















暂无评论内容