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 nodeskubectl 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核心逻辑

说了这么多,我画了一张流程图,帮你把整个链路串起来:

用户请求流量 vLLM Pod 运行 Metrics Server 采集 HPA 计算期望副本数 调整 Deployment 副本数 反馈循环 核心流程: 1. 流量增加 → Pod负载上升 2. Metrics Server采集到指标变化 3. HPA对比阈值,计算新副本数 4. 调整副本数,完成扩缩

这张图把HPA的闭环流程画得很清楚。从用户请求进来,到Pod负载变化,再到Metrics Server采集、HPA计算、最终调整副本数,形成一个完整的反馈回路。你把这个逻辑记牢了,后面配任何HPA都不会慌。


好了,这一章的内容就到这里。HPA的基础你已经掌握了:工作原理、Metrics Server的安装、以及基于CPU/内存的配置。下一章我们会深入更高级的用法——基于自定义指标的HPA,那才是vLLM推理场景下的重头戏。