Agent服务承担着模型推理、任务调度、消息消费这类工作,负载波动往往非常剧烈,白天高峰期的请求量可能是凌晨的十倍以上。如果副本数写死在Deployment里,高峰期队列堆积、接口超时,低谷期又在白白占用资源。HPA(Horizontal Pod Autoscaler)是Kubernetes原生的横向伸缩组件,它定期采集Pod的CPU利用率、内存用量等指标,动态调整副本数量,让Agent集群的容量始终贴合真实负载。这篇文章把指标链路、YAML写法和调优细节一次性讲透。

HPA的伸缩原理与指标链路
HPA本质上是一个跑在kube-controller-manager里的控制循环,默认每15秒执行一次:读取目标工作负载下所有Pod的实时指标,对比目标值,算出期望副本数,再通过修改Deployment的replicas字段完成扩缩容。整个过程对应用代码完全透明,不需要Agent做任何改造。计算公式并不复杂:
期望副本数 = 向上取整(当前副本数 × 当前指标平均值 ÷ 目标值)
举个例子:Agent集群当前有6个副本,CPU平均利用率90%,目标值设为65%,那么期望副本数就是ceil(6 × 90 ÷ 65) = 9,HPA会一次性把副本扩到9个。理解这个公式很关键,它意味着指标越接近目标值,单次扩容的幅度越小,集群不会出现失控式的副本暴涨。
有一个前提经常被忽略:CPU利用率的分母是容器在resources.requests里声明的值,而不是节点总核数。比如一个Agent Pod申请了2核,目标利用率70%,那么实际用量逼近1.4核时就会触发扩容。如果Deployment里忘了写资源声明,HPA会直接报错,提示missing request for cpu。所以配置HPA的第一步,是给Agent容器补上合理的requests:
resources:
requests:
cpu: "2"
memory: 4Gi
limits:
cpu: "4"
memory: 6Gi指标数据本身依赖metrics-server。它通过Kubelet的Summary API采集各节点上容器级别的CPU和内存数据,再以Metrics API的形式暴露给HPA查询。部署Agent之前,先用几条命令确认链路是否通畅:
kubectl get pods -n kube-system | grep metrics-server kubectl top nodes kubectl top pods -n agent-system
如果kubectl top能正常返回数值,说明指标链路已经就绪;如果报the server could not find the requested resource,就要先装metrics-server,否则HPA会一直停留在unknown状态,永远不执行任何伸缩动作。
基于CPU指标的HPA配置实战
CPU是Agent这类推理型服务最可靠的伸缩信号,因为推理负载上升时CPU消耗几乎同步上涨,信号延迟极低。下面是一份可以直接使用的配置:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: agent-hpa
namespace: agent-system
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: agent-deploy
minReplicas: 3
maxReplicas: 30
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 65几个字段的取值需要结合Agent的实际形态来定。minReplicas建议至少保留2到3个副本,Agent往往持有长连接,副本缩到1就是单点,滚动发布时的风险也会被放大。maxReplicas的设定要参考下游依赖的承受能力,比如模型服务的QPS上限、数据库连接池大小、消息队列的分区数,盲目放大副本数只会把瓶颈转移到别处。averageUtilization设为65是个比较均衡的起点,留出约三分之一的余量应对突发流量,同时避免指标轻微抖动就触发伸缩。
提交之后用kubectl get hpa agent-hpa -n agent-system观察状态,输出里的TARGETS列会显示实际利用率与目标值的对比,例如22%/65%,说明当前负载健康。再用kubectl describe hpa可以看到最近一次扩缩容事件和指标采集详情,排查问题时这两条命令基本够用。
还有一个细节值得注意:如果给Agent容器设置了很紧的CPU limit,内核CFS限流会让Pod在利用率还不高时就出现延迟劣化,HPA却感知不到。对延迟敏感的推理服务,建议不设CPU limit或者设得足够宽裕,把资源约束的主战场放在requests和HPA目标值上。
内存指标的价值与多指标组合策略
只看CPU对Agent并不够。Agent经常要缓存长对话上下文、维护向量检索缓冲区、加载embedding结果,这些行为会让内存持续增长而CPU几乎不动。等到内存逼近容器limit触发OOMKill,Pod被直接杀死,正在处理的请求全部失败。把内存纳入伸缩指标,可以在问题发生前扩容分摊压力。完整的双指标配置如下:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: agent-hpa
namespace: agent-system
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: agent-deploy
minReplicas: 3
maxReplicas: 30
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 65
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 75多指标的语义是取最大值:HPA会分别按CPU和内存算出两个期望副本数,取较大的那个执行。任何一个指标超标都会触发扩容,而缩容则要求所有指标都回落到安全区间,这天然是一种保守策略,对不希望频繁缩容的Agent服务反而是好事。内存指标还支持另一种写法,把target的type换成AverageValue并给出绝对量,比如每个Pod平均不超过3Gi,适合内存request不好估算的场景。
两类指标的脾气差异很大,配置时要区别对待:
| 对比维度 | CPU指标 | 内存指标 |
|---|---|---|
| 响应速度 | 快,随负载同步波动 | 慢,受GC和缓存释放影响明显滞后 |
| 适用场景 | 推理、计算密集型任务 | 长上下文缓存、向量检索、大缓冲区 |
| 缩容安全性 | 负载回落后指标迅速下降 | 负载回落后内存未必立刻释放 |
| 典型目标值 | 60%到70% | 70%到80% |
特别注意容器内存统计包含了页缓存,Python进程用mmap加载模型文件时,这部分缓存会把读数抬高,造成内存虚高引发不必要的扩容。遇到这种情况,可以适当调高内存目标值,或者干脆只依赖CPU做常规伸缩,把内存指标当作兜底保护。
behavior调优与Agent场景的常见坑
默认的伸缩行为对Agent并不友好:扩容不够快,缩容又太干脆。autoscaling/v2提供的behavior字段可以精细控制节奏,推荐配置如下:
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 25
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 30
- type: Pods
value: 4
periodSeconds: 30
selectPolicy: Max思路是扩容要快、缩容要慢。scaleUp的稳定窗口设为0,每30秒最多翻倍或新增4个Pod,两者取大,保证流量突增时容量能迅速跟上;scaleDown的稳定窗口拉到300秒,且每分钟最多缩掉25%的副本,避免流量锯齿状波动导致集群反复横跳。Agent的推理冷启动可能要加载模型、预热缓存,新Pod就绪需要几分钟,缩容过快很容易刚扩上来又缩下去,白白消耗启动成本。
缩容还有一个必须处理的隐患:被删掉的Pod上可能还挂着没处理完的长连接。如果不做优雅退出,客户端会遭遇一波连接重置。给Agent容器加上preStop钩子和足够的宽限期,让Pod先从网关注销、排空存量请求再退出:
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 10"]
terminationGracePeriodSeconds: 60最后汇总几个高频问题。第一,HPA一直显示unknown,多半是metrics-server没装、RBAC权限缺失,或者Pod还没就绪,HPA计算平均值时会排除未就绪的Pod,所以readinessProbe一定要配置准确,别让还在加载模型的Pod被算进低利用率里。第二,副本数来回震荡,通常是目标值设得太贴近实际水位,可以调低目标值拉开差距,控制器默认还有10%的容忍区间,指标在目标值上下小幅波动不会触发动作。第三,不要在HPA管理的同时手动修改Deployment的replicas,两边会互相打架,手动扩容应通过临时上调minReplicas实现。第四,如果后续想基于消息队列堆积长度、在线会话数这类业务指标伸缩,可以接入Prometheus Adapter暴露自定义指标,HPA的metrics里把type换成Pods或External即可,配置思路与本文完全一致。
总的来说,CPU指标负责快速响应计算负载,内存指标负责兜住上下文和缓存的增长,behavior负责控制节奏,优雅退出负责守住缩容的最后一道防线。把这几块配置到位,Agent服务就能在流量洪峰和低谷之间平稳地自动调节容量,既不浪费资源,也不让用户等待。
HPA配置Kubernetes自动伸缩Agent弹性伸缩修改时间:2026-09-27 17:21:45