4、HPA基础:HPA工作原理、Metrics Server安装、基于CPU/内存的HPA配置
聊到vLLM的自动扩缩,HPA(Horizontal Pod Autoscaler)是绕不开的基础设施。说白了,它就是Kubernetes里那个能帮你自动加Pod或减Pod的管家。今天这一章,我们就把它掰开揉碎了讲清楚。
4.1 HPA到底是怎么工作的?
HPA的核心逻辑其实不复杂。它定期去问Metrics Server:“嘿,现在这个Deployment的Pod们CPU/内存用得怎么样?” 然后根据拿到的数据和预设的阈值做比较,算出需要跑多少个Pod。
举个例子。你设了CPU目标利用率是50%。现在有2个Pod,每个Pod的CPU用了60%。那平均值就是60%,超过了50%。HPA一算:2 * (60/50) = 2.4,向上取整,得跑3个Pod。于是它就帮你把副本数从2改成3。
我个人习惯把HPA的工作拆成三步:
- 采集:从Metrics Server拉取Pod的实时资源指标
- 计算:根据公式算出期望副本数
- 执行:调整Deployment/StatefulSet的replicas字段
这里有个细节要注意。HPA默认的采集间隔是15秒,但Metrics Server本身也有刷新周期(通常是30秒到1分钟)。所以从指标变化到HPA真正做出反应,中间会有几十秒的延迟。我在项目中遇到过,流量突然暴涨时,HPA反应慢了半拍,导致部分请求超时。后来我们加了自定义指标和提前扩容策略才解决。
核心公式:期望副本数 = 当前副本数 × (当前指标值 / 目标指标值)
结果向上取整,且受最小/最大副本数限制。
4.2 装好Metrics Server,HPA才有饭吃
HPA自己不会采集指标。它得靠Metrics Server提供数据。你可以把Metrics Server理解成Kubernetes的“监控探头”,专门负责收集每个Pod和Node的CPU、内存使用量。
安装方式很简单。我一般用YAML直接部署:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
但这里有个坑。默认配置下,Metrics Server会验证kubelet的证书。如果你的集群是自签证书(比如用kubeadm搭的),它会报错连不上。我曾经在这个问题上卡了半小时。
避坑指南:如果你用的是自签证书,记得在Metrics Server的Deployment里加启动参数 --kubelet-insecure-tls。或者把证书配好,别偷懒。
装完之后,跑一下 kubectl top nodes 和 kubectl top pods,能看到数据就说明成功了。看不到?检查Metrics Server的Pod日志,多半是网络或证书问题。
4.3 基于CPU/内存的HPA配置实战
好,Metrics Server装好了,我们来写一个真正的HPA配置。假设我有一个vLLM推理服务,Deployment叫 vllm-server,我想让它的CPU平均利用率维持在60%左右。
YAML长这样:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: vllm-hpa-cpu
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: vllm-server
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
这里我用了 autoscaling/v2 版本,因为它支持多种指标类型。v1版本已经过时了,不建议再用。
你想想看,如果只配CPU,遇到内存密集型任务怎么办?比如vLLM在处理长序列时,显存和内存消耗很大,CPU反而可能不高。所以生产环境我一般CPU和内存都配:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: vllm-hpa-both
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: vllm-server
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70
注意,HPA会取这两个指标中算出来的较大副本数。比如CPU算出来要3个Pod,内存算出来要5个,那HPA就取5个。嗯,这里要记住,它是取最大值,不是平均值。
我的经验:对于vLLM这类推理服务,内存利用率阈值建议设得比CPU低一些。因为内存一旦接近极限,很容易触发OOM Kill,导致推理中断。我一般设CPU 60%-70%,内存 50%-60%。
4.4 验证HPA是否生效
配置写好了,apply上去之后,怎么知道它有没有在干活?
我最常用的命令是:
kubectl get hpa vllm-hpa-both -w
这个 -w 参数会持续监听HPA的状态变化。你会看到类似这样的输出:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
vllm-hpa-both Deployment/vllm-server 45%/60%, 55%/70% 2 10 2 5m
TARGETS 列显示的是当前值/目标值。如果当前值超过了目标值,REPLICAS 就会开始增加。如果一直没变化,检查一下Metrics Server的数据是否正常,或者看看HPA的事件:
kubectl describe hpa vllm-hpa-both
Events里会告诉你HPA为什么没扩缩,比如“missing request for cpu”之类的。这个错误很常见——你的Pod没写resources.requests。HPA需要requests作为基准来计算利用率。
重要提醒:HPA必须配合Pod的resources.requests才能正常工作。没有requests,HPA算不出利用率,直接罢工。我见过有人配了半天HPA没反应,最后发现是Pod没写requests。
4.5 一张图看懂HPA核心逻辑
说了这么多,我画了一张流程图,帮你把整个链路串起来:
这张图把HPA的闭环流程画得很清楚。从用户请求进来,到Pod负载变化,再到Metrics Server采集、HPA计算、最终调整副本数,形成一个完整的反馈回路。你把这个逻辑记牢了,后面配任何HPA都不会慌。
好了,这一章的内容就到这里。HPA的基础你已经掌握了:工作原理、Metrics Server的安装、以及基于CPU/内存的配置。下一章我们会深入更高级的用法——基于自定义指标的HPA,那才是vLLM推理场景下的重头戏。