3. vLLM 服务部署:用 Deployment 把模型跑起来

好,到了真正动手的环节了。

前面我们聊了 Ingress 的基本概念,也讲了 vLLM 是什么。但光说不练假把式,得先把 vLLM 服务本身部署到 K8s 里,后面才能谈怎么暴露它。

这一章,我们就用 Deployment 来部署 vLLM。说白了,就是写一个 YAML 文件,告诉 K8s:「嘿,帮我跑一个 vLLM 的容器,资源给够,环境变量配好。」

3.1 为什么用 Deployment,而不是 Pod?

你可能会想,直接跑个 Pod 不就行了?嗯,理论上可以。但我个人习惯,生产环境从来不用裸 Pod

为什么?因为 Pod 挂了就真的挂了,没人管它。Deployment 不一样,它自带「自愈」能力——Pod 挂了,ReplicaSet 会重新拉一个起来。我在项目中遇到过,有一次节点宕机,裸 Pod 直接消失,业务中断了半小时。换成 Deployment 后,同样的故障,十几秒就恢复了。

所以,记住一句话:用 Deployment,别用裸 Pod

3.2 编写 vLLM 的 Deployment YAML

直接上代码。这是我常用的一个模板,你拿过去改改就能用。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-server
  namespace: default
  labels:
    app: vllm
spec:
  replicas: 1
  selector:
    matchLabels:
      app: vllm
  template:
    metadata:
      labels:
        app: vllm
    spec:
      containers:
      - name: vllm
        image: vllm/vllm-openai:latest
        ports:
        - containerPort: 8000
          name: http
        env:
        - name: MODEL_NAME
          value: "Qwen/Qwen2.5-7B-Instruct"
        - name: HF_TOKEN
          valueFrom:
            secretKeyRef:
              name: hf-secret
              key: token
        - name: CUDA_VISIBLE_DEVICES
          value: "0"
        resources:
          requests:
            memory: "16Gi"
            cpu: "4"
            nvidia.com/gpu: 1
          limits:
            memory: "32Gi"
            cpu: "8"
            nvidia.com/gpu: 1
        command:
        - python3
        - -m
        - vllm.entrypoints.openai.api_server
        args:
        - --model
        - $(MODEL_NAME)
        - --port
        - "8000"
        - --max-model-len
        - "8192"
        - --gpu-memory-utilization
        - "0.9"
        - --trust-remote-code
        livenessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 60
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 30
          periodSeconds: 5

核心要点:

  • 镜像:我用的是 vllm/vllm-openai:latest,建议你固定版本号,比如 v0.6.0,避免意外升级。
  • 端口:vLLM 默认监听 8000 端口,对外提供 OpenAI 兼容的 API。
  • 启动命令:直接调用了 vLLM 的入口模块,参数通过环境变量传入。

3.3 配置资源限制:别让模型把集群吃垮

大模型推理是出了名的「吃资源」。我曾经见过有人没配资源限制,一个 Pod 把整台机器的显存占满,导致其他服务全部 OOM。嗯,那场面,挺尴尬的。

资源限制怎么配?

  • GPU:必须配。vLLM 依赖 GPU 做推理,不配的话调度器不会给你分配 GPU。
  • 内存:7B 模型建议至少 16Gi,13B 模型建议 32Gi 起步。我一般把 requests 设低一点,limits 设高一点,给点缓冲。
  • CPU:其实推理主要靠 GPU,CPU 用来做预处理和后处理。4 核起步,8 核比较稳。

⚠️ 注意:

如果你用的是 NVIDIA GPU,别忘了安装 nvidia-device-plugin。否则你配了 nvidia.com/gpu: 1 也没用,调度器根本不认。

3.4 配置环境变量:灵活一点,别写死

环境变量是 Deployment 的「灵魂」。我习惯把模型名称、Hugging Face Token 这些可变的东西都放到环境变量里,而不是硬编码在启动命令中。

环境变量 说明 示例值
MODEL_NAME 模型名称,从 Hugging Face 拉取 Qwen/Qwen2.5-7B-Instruct
HF_TOKEN Hugging Face 的访问令牌,用于下载私有模型 从 Secret 中引用
CUDA_VISIBLE_DEVICES 指定使用哪块 GPU 00,1
MAX_MODEL_LEN 最大输入长度,影响显存占用 8192
GPU_MEMORY_UTILIZATION GPU 显存利用率,0.9 表示用 90% 0.9

💡 我的小技巧:

敏感信息(比如 HF_TOKEN)千万别直接写在 YAML 里。用 Secret 资源存起来,然后通过 valueFrom.secretKeyRef 引用。这样既安全,又方便换 Token。

3.5 健康检查:让 K8s 知道你的服务还活着

Deployment 配了健康检查,K8s 才能自动帮你处理故障。

  • livenessProbe:探测 Pod 是否还活着。如果挂了,K8s 会重启它。
  • readinessProbe:探测 Pod 是否准备好接收流量。如果没准备好,Service 不会把流量转发过来。

vLLM 自带了 /health 端点,直接拿来用就行。注意 initialDelaySeconds 要设大一点,因为模型加载需要时间。7B 模型大概 30-60 秒,13B 模型可能要 2-3 分钟。

3.6 本章核心逻辑图

下面这张图,帮你理清 Deployment 部署 vLLM 的整体流程:

vLLM Deployment 部署流程 用户 / CI 系统 kubectl apply -f deploy.yaml K8s API Server Scheduler 调度 Pod: vllm-server GPU + 16Gi 内存 + 环境变量

流程很简单:你写好 YAML → 提交给 K8s → Scheduler 找个合适的节点 → 拉起 Pod,加载模型,开始提供服务。

3.7 部署验证

YAML 写好了,怎么验证它能不能跑?

  1. 检查 Pod 状态kubectl get pods -l app=vllm,看到 Running 就对了。
  2. 看日志kubectl logs -f <pod-name>,如果看到 Uvicorn running on http://0.0.0.0:8000,说明模型加载成功。
  3. 测试 APIkubectl port-forward pod/<pod-name> 8000:8000,然后本地 curl 一下 /v1/models 端点,看能不能返回模型列表。

常见坑:

  • Pod 一直 Pending:大概率是 GPU 资源不够,或者没装 nvidia-device-plugin。
  • Pod 反复 CrashLoopBackOff:可能是显存不够,模型加载到一半就 OOM 了。试试调小 --max-model-len--gpu-memory-utilization
  • 健康检查失败:模型加载慢,initialDelaySeconds 设得太短。我一般设 120 秒起步。

好了,Deployment 部署 vLLM 就这些内容。说白了,就是配好镜像、资源、环境变量,再加个健康检查。你照着上面的 YAML 改一改,应该就能跑起来。

下一章,我们会给这个 Deployment 配上 Service,让集群内部能访问它。嗯,到时候再聊。


公众号:蓝海资料掘金营,微信 deep3321