3. HPA高级配置:自定义指标、多指标伸缩、行为策略(behavior)
好,咱们继续深入。基础HPA配置,说白了就是根据CPU或内存来扩缩容。但实际生产环境里,哪有这么简单?我见过太多团队,业务高峰期CPU才30%,但请求延迟已经飙到天上去了。这时候,你就得用上HPA的高级玩法了。
3.1 自定义指标:让HPA听懂你的业务语言
默认的CPU和内存指标,其实挺粗糙的。你想想看,一个Web应用,用户排队等响应,CPU可能并不高,但队列长度已经爆炸了。这时候扩缩容的依据,应该是“队列深度”或者“每秒请求数”,而不是CPU。
Kubernetes支持自定义指标,通过 external.metrics 或 pods.metrics 来引用。我习惯用Prometheus Adapter来桥接,把Prometheus里的业务指标暴露给HPA。
举个例子,假设你的应用暴露了一个 http_requests_per_second 指标。配置起来大概是这样的:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: webapp-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: webapp
minReplicas: 2
maxReplicas: 10
metrics:
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: 100
这里的关键是 type: Pods,它会从每个Pod上拉取指标,然后算平均值。目标值是每个Pod处理100 QPS。超过这个值,HPA就会加Pod。
--horizontal-pod-autoscaler-sync-period 也调到10秒。
3.2 多指标伸缩:别让单一指标骗了你
单一指标伸缩,容易误判。比如只看CPU,内存爆了它不管。只看QPS,后端数据库连接池满了它也不知道。所以,生产环境我强烈建议用多指标。
HPA支持同时配置多个指标,它会取所有指标中 最激进的那个 作为最终决策。什么意思呢?就是哪个指标要求扩的Pod多,就听谁的。
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: multi-metric-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
- type: Pods
pods:
metric:
name: request_latency_seconds
target:
type: AverageValue
averageValue: 0.5
这个配置同时监控CPU、内存和请求延迟。只要有一个指标超标,就会触发扩容。我曾经遇到过内存泄漏的应用,CPU一直正常,但内存悄悄涨到90%。多亏了内存指标,HPA及时扩容,没让服务挂掉。
3.3 行为策略(behavior):给HPA装上“阻尼器”
默认的HPA行为,其实挺“愣”的。指标一波动,它就跟着动。结果呢?Pod刚启动起来,指标又降了,它又把Pod缩掉。这种“抖动”在线上是非常危险的。
Kubernetes v1.18之后引入了 behavior 字段,让你可以精细控制扩缩容的行为。说白了,就是给HPA装上“阻尼器”和“加速器”。
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: behavior-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
- type: Pods
value: 2
periodSeconds: 60
selectPolicy: Min
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
- type: Pods
value: 4
periodSeconds: 15
selectPolicy: Max
这段配置,我拆开来讲。
3.3.1 缩容策略:慢一点,稳一点
stabilizationWindowSeconds: 300 是“冷静期”。意思是,指标降到目标值以下后,HPA会等300秒再决定是否缩容。这能有效避免因为瞬时波动导致的误缩。
缩容策略我用了两条:
- 每分钟最多缩容10%的Pod
- 每分钟最多缩容2个Pod
selectPolicy: Min 表示取这两个策略中 更保守 的那个。也就是每分钟最多缩2个Pod。这样即使指标降得很快,Pod也不会一下子全没了。
3.3.2 扩容策略:快刀斩乱麻
扩容的 stabilizationWindowSeconds: 0,不等待,立即响应。因为流量突增时,每一秒都很宝贵。
扩容策略:
- 每15秒最多扩容100%的Pod(翻倍扩容)
- 每15秒最多扩容4个Pod
selectPolicy: Max 取更激进的策略。如果当前有3个Pod,100%就是加3个,但上限是4个,所以取4个。如果当前有10个Pod,100%是加10个,远超4个,那就取10个。这样在Pod少的时候能快速翻倍,Pod多的时候也能线性增长。
我曾经在一个电商大促项目中,就是因为没配behavior,结果流量突增时HPA反应太慢,导致服务雪崩。后来配上了这个策略,扩容速度提升了3倍,再也没出过问题。
3.4 综合配置示例:一个生产级的HPA
最后,我给你一个我常用的生产级配置模板。它结合了自定义指标、多指标和行为策略:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: production-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: production-app
minReplicas: 3
maxReplicas: 50
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
- type: Pods
pods:
metric:
name: requests_per_second
target:
type: AverageValue
averageValue: 500
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 5
periodSeconds: 60
- type: Pods
value: 1
periodSeconds: 60
selectPolicy: Min
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 200
periodSeconds: 15
- type: Pods
value: 6
periodSeconds: 15
selectPolicy: Max
这个配置里,缩容非常保守——每分钟最多缩5%或1个Pod。扩容则非常激进——每15秒最多翻两倍或加6个Pod。嗯,这里要注意,minReplicas: 3 保证了即使业务低谷,也有3个Pod兜底。
minReplicas 设成1,结果那个Pod所在的节点挂了,业务直接中断。后来我养成了习惯,关键服务至少2个副本起步。另外,maxReplicas 不要设太大,要考虑后端资源(数据库连接池、缓存等)的承受能力。
好了,HPA高级配置就讲到这里。记住,弹性伸缩不是“自动挡”就完事了,你得根据业务特点调参。多观察、多调整,才能找到最适合你的那一组参数。