在 Kubernetes 上部署 vLLM

在 Kubernetes 上部署 vLLM,可以高效、可扩展地提供机器学习模型服务。本指南使用原生 Kubernetes 完成部署。

此外,也可以借助 Helm、NVIDIA Dynamo、InftyAI/llmaz、llm-d、KAITO、KServe、Kthena、KubeRay、kubernetes-sigs/lws、meta-llama/llama-stack、substratusai/kubeai、vllm-project/AIBrix 或 vllm-project/production-stack。

使用 CPU 部署

注意:这里的 CPU 部署仅用于演示和测试,性能不能与 GPU 相比。

先创建 Kubernetes PVC 和 Secret,用于下载、保存 Hugging Face 模型:

cat <<EOF |kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: vllm-models
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 50Gi
---
apiVersion: v1
kind: Secret
metadata:
  name: hf-token-secret
type: Opaque
stringData:
  token: "REPLACE_WITH_TOKEN"
EOF

token 保存 Hugging Face 访问令牌。生成方法见 Hugging Face 文档。

接着,通过 Deployment 与 Service 启动 vLLM。根据处理器架构选择镜像:

VLLM_IMAGE=public.ecr.aws/q9t5s3a7/vllm-cpu-release-repo:latest       # use this for x86_64
VLLM_IMAGE=public.ecr.aws/q9t5s3a7/vllm-arm64-cpu-release-repo:latest # use this for arm64
cat <<EOF |kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: vllm
  template:
    metadata:
      labels:
        app.kubernetes.io/name: vllm
    spec:
      containers:
      - name: vllm
        image: $VLLM_IMAGE
        command: ["/bin/sh", "-c"]
        args: [
          "vllm serve meta-llama/Llama-3.2-1B-Instruct"
        ]
        env:
        - name: HF_TOKEN
          valueFrom:
            secretKeyRef:
              name: hf-token-secret
              key: token
        ports:
          - containerPort: 8000
        volumeMounts:
          - name: llama-storage
            mountPath: /root/.cache/huggingface
      volumes:
      - name: llama-storage
        persistentVolumeClaim:
          claimName: vllm-models
---
apiVersion: v1
kind: Service
metadata:
  name: vllm-server
spec:
  selector:
    app.kubernetes.io/name: vllm
  ports:
  - protocol: TCP
    port: 8000
    targetPort: 8000
  type: ClusterIP
EOF

通过日志确认服务器成功启动。下载模型可能需要几分钟:

kubectl logs -l app.kubernetes.io/name=vllm
...
INFO:     Started server process [1]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)

使用 GPU 部署

前提是已有带 GPU 的正常运行 Kubernetes 集群。

创建 PVC、Secret 与 Deployment

PVC 保存模型缓存,是可选的,也可以改用 hostPath 或其他存储:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mistral-7b
  namespace: default
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 50Gi
  storageClassName: default
  volumeMode: Filesystem

Secret 也是可选的,仅访问受限模型时需要。不使用受限模型可以跳过:

apiVersion: v1
kind: Secret
metadata:
  name: hf-token-secret
  namespace: default
type: Opaque
stringData:
  token: "REPLACE_WITH_TOKEN"

随后创建运行模型服务器的 Deployment。以下示例部署 Mistral-7B-Instruct-v0.3,分别给出 NVIDIA 与 AMD GPU 方案。

NVIDIA GPU:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mistral-7b
  namespace: default
  labels:
    app: mistral-7b
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mistral-7b
  template:
    metadata:
      labels:
        app: mistral-7b
    spec:
      volumes:
      - name: cache-volume
        persistentVolumeClaim:
          claimName: mistral-7b
      # vLLM needs to access the host's shared memory for tensor parallel inference.
      - name: shm
        emptyDir:
          medium: Memory
          sizeLimit: "2Gi"
      containers:
      - name: mistral-7b
        image: vllm/vllm-openai:latest
        command: ["/bin/sh", "-c"]
        args: [
          "vllm serve mistralai/Mistral-7B-Instruct-v0.3 --trust-remote-code --enable-chunked-prefill --max-num-batched-tokens 1024"
        ]
        env:
        - name: HF_TOKEN
          valueFrom:
            secretKeyRef:
              name: hf-token-secret
              key: token
        ports:
        - containerPort: 8000
        resources:
          limits:
            cpu: "10"
            memory: 20G
            nvidia.com/gpu: "1"
          requests:
            cpu: "2"
            memory: 6G
            nvidia.com/gpu: "1"
        volumeMounts:
        - mountPath: /root/.cache/huggingface
          name: cache-volume
        - name: shm
          mountPath: /dev/shm
        livenessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 60
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 60
          periodSeconds: 5

AMD GPU,例如 MI300X 等 ROCm 设备,可参考:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mistral-7b
  namespace: default
  labels:
    app: mistral-7b
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mistral-7b
  template:
    metadata:
      labels:
        app: mistral-7b
    spec:
      volumes:
      # PVC
      - name: cache-volume
        persistentVolumeClaim:
          claimName: mistral-7b
      # vLLM needs to access the host's shared memory for tensor parallel inference.
      - name: shm
        emptyDir:
          medium: Memory
          sizeLimit: "8Gi"
      hostNetwork: true
      hostIPC: true
      containers:
      - name: mistral-7b
        image: rocm/vllm:rocm6.2_mi300_ubuntu20.04_py3.9_vllm_0.6.4
        securityContext:
          seccompProfile:
            type: Unconfined
          runAsGroup: 44
          capabilities:
            add:
            - SYS_PTRACE
        command: ["/bin/sh", "-c"]
        args: [
          "vllm serve mistralai/Mistral-7B-v0.3 --port 8000 --trust-remote-code --enable-chunked-prefill --max-num-batched-tokens 1024"
        ]
        env:
        - name: HF_TOKEN
          valueFrom:
            secretKeyRef:
              name: hf-token-secret
              key: token
        ports:
        - containerPort: 8000
        resources:
          limits:
            cpu: "10"
            memory: 20G
            amd.com/gpu: "1"
          requests:
            cpu: "6"
            memory: 6G
            amd.com/gpu: "1"
        volumeMounts:
        - name: cache-volume
          mountPath: /root/.cache/huggingface
        - name: shm
          mountPath: /dev/shm

完整步骤与示例 YAML 见 ROCm vLLM serve 示例。

创建 Kubernetes Service

创建 Service,暴露 mistral-7b 部署:

apiVersion: v1
kind: Service
metadata:
  name: mistral-7b
  namespace: default
spec:
  ports:
  - name: http-mistral-7b
    port: 80
    protocol: TCP
    targetPort: 8000
  # The label selector should match the deployment labels & it is useful for prefix caching feature
  selector:
    app: mistral-7b
  sessionAffinity: None
  type: ClusterIP

部署与测试

使用 kubectl apply -f <filename> 应用配置:

kubectl apply -f deployment.yaml
kubectl apply -f service.yaml

通过以下 curl 请求测试部署:

curl http://mistral-7b.default.svc.cluster.local/v1/completions \
  -H "Content-Type: application/json" \
  -d '{
        "model": "mistralai/Mistral-7B-Instruct-v0.3",
        "prompt": "San Francisco is a",
        "max_tokens": 7,
        "temperature": 0
      }'

正确部署后,应收到 vLLM 模型响应。

使用 gRPC 提供服务

传入 --grpc 可以用 gRPC 代替 HTTP。需要先安装可选依赖:

pip install vllm[grpc]

启用后,服务器提供标准 gRPC Health Checking Protocol,即 grpc.health.v1.Health,可与 Kubernetes 1.24 起提供的原生 gRPC 探针集成。

部署时,在 vllm serve 加入 --grpc,并将 httpGet 探针替换为 grpc:

containers:
- name: mistral-7b
  image: vllm/vllm-openai:latest
  command: ["/bin/sh", "-c"]
  args: [
    "pip install vllm[grpc] && vllm serve mistralai/Mistral-7B-Instruct-v0.3 --grpc --port 50051 --trust-remote-code"
  ]
  ports:
  - containerPort: 50051
  livenessProbe:
    grpc:
      port: 50051
    initialDelaySeconds: 120
    periodSeconds: 10
  readinessProbe:
    grpc:
      port: 50051
    initialDelaySeconds: 120
    periodSeconds: 5

注意:健康服务每次探测都会检查引擎状态。引擎不健康或服务器正在关闭时,返回 NOT_SERVING。

也可以使用 grpcurl 手动检查:

grpcurl -plaintext localhost:50051 grpc.health.v1.Health/Check

故障排查

启动或就绪探针失败,日志出现 KeyboardInterrupt: terminated

如果 startup 或 readiness 探针的 failureThreshold 相对于服务器所需启动时间过低,Kubernetes 可能终止容器。迹象包括:

  • 容器日志包含 KeyboardInterrupt: terminated。
  • kubectl get events 显示 Container $NAME failed startup probe, will be restarted。

可以提高 failureThreshold,让模型服务器有更多时间就绪。为选择合理值,可以暂时从清单移除探针,测量服务器达到可服务状态所需时间。

结语

借助 Kubernetes,vLLM 能利用 GPU 资源高效扩展并管理模型。按以上步骤可以部署和测试服务。遇到问题或有改进建议,也欢迎贡献文档。

原文日期:2026 年 7 月 16 日。


原文:vLLM:Using Kubernetes。作者/维护方:vLLM 文档维护者。本文为中文翻译,代码及命令保留原文。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容