vLLM推理服务滚动更新指南

本文说明如何先校验集群的图形处理器资源、容器共享内存以及启动、就绪和存活探针,再通过 Kubernetes Deployment 分批切换实例,以同条件在线基准检查回归,并保留旧修订版本回退路径,避免把发布完成误判为服务稳定。

vLLM 推理服务的滚动更新应具体落到 Kubernetes Deployment:先校验 GPU 资源、共享内存和镜像参数,再分批替换 Pod,用探针控制新旧实例交接,并以同条件基准决定继续还是回退。Deployment 完成更新不等于业务不中断或性能合格,副本、探针、容量和流量条件必须一起判断。健康检查路径应按当前版本文档确认,不要套用未经确认的 URL。

更新前先检查 GPU 资源

安装厂商 device plugin 后,集群会暴露可调度的自定义 GPU 资源;Kubernetes 的 GPU 调度说明给出的 NVIDIA 示例是 nvidia.com/gpu。GPU 只写在 limits 中时,Kubernetes 默认把限制值用作请求值;如果 requests 与 limits 同时出现,值必须相同,而只有请求值、没有限制值的配置不被允许。

limits:
  nvidia.com/gpu: YOUR_VALUE

把 YOUR_VALUE 换成当前实例方案使用的数量,并确认节点仍有可调度资源。这个片段只负责 GPU 资源声明;模型参数、共享内存和探针仍需分别检查,不能用“Pod 已创建”代替完整校验。

准备镜像、令牌与共享内存

按 Docker 部署文档,官方镜像是 Docker Hub 上的 vllm/vllm-openai,可运行 OpenAI 兼容服务器;引擎参数放在镜像标签后,容器需用 --ipc=host 或 --shm-size 访问主机共享内存,因为 PyTorch 会在进程间共享数据,tensor parallel 尤其如此。可选依赖因许可原因未包含在镜像中,需要时应在自定义 Dockerfile 中补齐。

DOCKER_BUILDKIT=1 docker build . \
  --target vllm-openai \
  --tag vllm/vllm-openai \
  --file docker/Dockerfile

文档中的启动模板如下,可用于核对镜像、端口、缓存目录、令牌和引擎参数:

docker run --runtime nvidia --gpus all \
  -v ~/.cache/huggingface:/root/.cache/huggingface \
  --env "HF_TOKEN=$HF_TOKEN" \
  -p 8000:8000 \
  --ipc=host \
  vllm/vllm-openai:latest \
  --model Qwen/Qwen3-0.6B

这条命令只启动单个容器,不代替 Deployment 的滚动更新。在 Kubernetes 部署文档中,Hugging Face 令牌保存在 Secret 并以 HF_TOKEN 注入;该 Secret 只在访问受限模型时需要。tensor parallel 所需的共享内存则使用内存型 emptyDir,挂载位置为 /dev/shm。

env:
  - name: HF_TOKEN
    valueFrom:
      secretKeyRef:
        name: hf-token-secret
        key: token
- name: shm
  emptyDir:
    medium: Memory

用探针控制新旧实例交接

按 Kubernetes 的探针说明,就绪探针决定容器何时可以接收流量;判定失败时,Pod 会停止接收匹配 Service 的流量,但容器不会被终止。启动探针适合进入服务前耗时较长的应用,判定失败后 kubelet 会终止容器并执行重启策略;存活探针则用于判断何时重启容器,例如应用已经发生死锁。

因此,模型加载阶段由启动探针保护,服务真正可接流量后再由就绪探针放行,存活探针只处理无法继续推进的进程。检查命令或路径应依据当前版本文档填写,不要自行假定健康检查 URL。

分批切换并保留回退

按 Deployment 文档,默认滚动更新保证至少 75% 的期望 Pod 处于运行状态,maxUnavailable 为 25%,总数最多达到期望值的 125%,即 maxSurge 为 25%。maxUnavailable 可以是绝对数量或期望 Pod 数的百分比,百分比换算出的绝对数量会向下取整;maxUnavailable 为 0 时,maxSurge 不能为 0。

maxUnavailable: YOUR_VALUE
maxSurge: YOUR_VALUE

把这两个值放在现有 Deployment 的滚动更新配置中,并根据容量方案填写,同时确认新增 Pod 获得的 GPU 数量。随后通过现有清单提交流程更新镜像引用和引擎参数,发布前记录当前可用的旧修订版本。

需要撤销时,可以回到上一修订版本,也可以指定已记录的版本:

kubectl rollout undo deployment/YOUR_VALUE
kubectl rollout undo deployment/YOUR_VALUE --to-revision=YOUR_VALUE

用 vLLM 在线基准验证每次切换

按 在线基准文档,vllm bench 用于功能评估和回归测试,vllm bench serve 面向运行中的服务器:

vllm bench serve \
  --backend vllm \
  --model NousResearch/Hermes-3-Llama-3.1-8B \
  --endpoint /v1/completions \
  --dataset-name sharegpt

先为当前版本记录基线,再在更新后使用相同数据集和负载参数复测。--request-rate 控制每秒目标请求数,inf 表示最大吞吐测试,默认值会立即发送全部请求;--max-concurrency 限制尚未完成的并发请求,不设置时并发数不受限制。回归比较应显式固定这些条件,而不是直接比较负载不同的运行结果。

报告包含请求吞吐量、输出 token 吞吐量和总 token 吞吐量。TTFT 从客户端发出请求算到收到首个流式输出;ITL 汇总成功请求中连续流式输出之间的间隔;TPOT 按请求计算并排除首个 token。启用 speculative decoding 后,一个流式输出可能包含多个 token,因此 ITL 与 TPOT 可能出现差异。

对同一服务器重复运行基准时,前缀缓存可能复用已有提示词并抬高吞吐量;这类重复结果不能直接当作独立的回归证据。

常见失败点

  • Pod 长时间处于 Pending:检查 device plugin 状态、GPU 资源名,以及 requests 与 limits 是否符合前述约束。
  • 进程已经启动却没有流量:按启动、就绪、存活探针的职责逐项检查,不要把“进程存在”当成“可以接流量”。
  • 错误指向共享内存:核对 /dev/shm 的 Memory emptyDir,以及 Docker 的共享内存参数。
  • 可选依赖报错:使用前述自定义 Dockerfile 构建路径,不要假定官方镜像已经包含这些依赖。
  • 重复基准结果异常偏高:先检查前缀缓存和负载参数,再判断是否存在回归。

这些步骤依据正文所链接的官方文档整理,使用前应按当前版本复核。

资料来源