第二章 核心部署:把 vLLM 跑成 K8s 服务


文档摘要

第二章 核心部署:把 vLLM 跑成 K8s 服务 导读:第一章我们把地基和选型定下来了。这一章是整本教程的「主干」——你要亲手把 vLLM 变成一个能被集群内外部调用的推理服务。很多教程到「能 curl 通」就结束了,但生产环境要求的是:模型权重怎么存、GPU 怎么申请、副本怎么扩、请求怎么路由。本章三节,分别对应「模型从哪来」「服务怎么起」「流量怎么进」。读完你应能独立交付一个可对外提供 OpenAI 兼容接口的 GLM-5.2 服务。 2.1 模型权重从哪来:存储与镜像策略 GLM-5.2 权重遵循 MIT 协议,已在 Hugging Face 与 ModelScope 开源。第一个现实问题是:Pod 是临时性的,每次重启都重新从网上下 几十 GB 权重?显然不行。

第二章 核心部署:把 vLLM 跑成 K8s 服务

导读:第一章我们把地基和选型定下来了。这一章是整本教程的「主干」——你要亲手把 vLLM 变成一个能被集群内外部调用的推理服务。很多教程到「能 curl 通」就结束了,但生产环境要求的是:模型权重怎么存、GPU 怎么申请、副本怎么扩、请求怎么路由。本章三节,分别对应「模型从哪来」「服务怎么起」「流量怎么进」。读完你应能独立交付一个可对外提供 OpenAI 兼容接口的 GLM-5.2 服务。

2.1 模型权重从哪来:存储与镜像策略

GLM-5.2 权重遵循 MIT 协议,已在 Hugging Face 与 ModelScope 开源。第一个现实问题是:Pod 是临时性的,每次重启都重新从网上下 几十 GB 权重?显然不行。正确做法是 把权重放到持久化存储,让 vLLM 挂载后直接加载

在 K8s 里有三种常见路径:

  1. PVC(持久卷):申请一块 ReadWriteOnce 的存储,第一次把权重下载进去,之后 Pod 挂载这块盘直接读。优点是简单,缺点是单节点独占、不能多副本同时写。适合单副本或手动管理轮换。
  2. hostPath / 节点本地盘:把权重直接放 GPU 节点的本地 NVMe 上,Pod 用 hostPath 挂进去。读取速度最快(本地 NVMe 远快于网络盘),但耦合了节点,Pod 被调度到没放权重的节点就会失败——需要用 nodeAffinity 把 Pod 钉在固定节点,或用 DaemonSet 预分发。
  3. 共享文件系统(如 NFS/EFS):多副本可读、便于横向扩展,但网络带宽可能成为加载瓶颈,冷启动时拉权重较慢。

我的建议:生产首选 PVC 或节点本地盘 + 亲和性。原因很简单——推理对「加载延迟」和「读取带宽」极敏感,本地盘体验最好;PVC 次之且更通用。共享盘适合多副本且权重不太大的场景。无论哪种,都不要在 Pod 里写死下载逻辑,而是用 Init Container 或独立 Job 把权重准备好,主容器只负责读。

镜像方面,vLLM 官方提供带 CUDA 的镜像(如 vllm/vllm-openai)。务必让镜像的 CUDA 版本与集群驱动兼容,否则会出现「镜像起不来 / 找不到 libcuda」的玄学报错。一个常被忽视的细节:镜像体积大,节点拉取慢,建议在 GPU 节点上预先 docker pull 或配置镜像预热,避免首次调度卡在 ImagePull 上十几分钟。

2.2 用 Deployment 把 vLLM 跑起来

权重就位后,核心是一个 Deployment

apiVersion: apps/v1 kind: Deployment metadata: name: glm52-vllm spec: replicas: 1 selector: matchLabels: app: glm52-vllm template: metadata: labels: app: glm52-vllm spec: containers: - name: vllm image: vllm/vllm-openai:latest args: - "--model" - "THUDM/glm-5.2" # 实际请以官方模型卡公布的 repo 为准 - "--tensor-parallel-size" - "1" - "--max-model-len" - "1048576" # 对应 1M 上下文,按显存量力而行 resources: limits: nvidia.com/gpu: 1 ports: - containerPort: 8000 readinessProbe: httpGet: path: /health port: 8000 initialDelaySeconds: 300 # 大模型加载慢,别设太短

几个真人踩过的坑,必须强调:

  • initialDelaySeconds 别照抄 10 秒。GLM-5.2 权重大,从盘加载到就绪可能要几分钟。探针太激进会一直杀掉还没加载完的 Pod,陷入「启动—被杀—重启」死循环。
  • --tensor-parallel-size 要和申请的 GPU 数一致。单机单卡就写 1;如果一张卡显存放不下整个模型,要跨多卡张量并行,就必须申请对应张数并写对应值,否则要么起不来要么浪费卡。
  • --max-model-len 受显存硬约束。1M 上下文很诱人,但每多一倍上下文,KV Cache 显存开销指数级增长。新手务必先用较短长度(如 32k)跑通,再按显存余量逐步放开,别一上来就拉满导致 OOM。
  • 模型 repo 名称请以智谱官方模型卡公布为准;本教程示例中的 THUDM/glm-5.2 仅为占位示意,实际部署前请核实官方 HF/ModelScope 路径,避免拉到错误仓库。

2.3 暴露服务:Service、Ingress 与路由

Deployment 起了,但集群外还访问不到。需要一层 Service 把 Pod 的 8000 端口暴露出来:

apiVersion: v1 kind: Service metadata: name: glm52-vllm-svc spec: selector: app: glm52-vllm ports: - port: 80 targetPort: 8000

Service 默认只在集群内可达。若要让外部调用,常见两种方式:Ingress(走 HTTP 网关,便于加鉴权、限流、HTTPS)或 LoadBalancer 类型的 Service(云厂商直接给个外部 IP)。生产环境强烈建议走 Ingress + 认证中间件,不要裸奔暴露 8000 端口。

vLLM 暴露的是 OpenAI 兼容 API/v1/chat/completions 等),这意味着你现有的 OpenAI SDK 代码几乎零改动就能切到 GLM-5.2,这是它最大的工程红利。当你有多副本时,需要在前面加一层路由(vLLM Production Stack 自带的 router,或独立网关)把请求分发给多个 vLLM Pod,并按 session / prefix 做亲和,避免同一个长对话被 dispersion 到不同实例导致上下文丢失。

讲到这里,一个完整的「单机单副本」推理服务就立起来了。但生产要的是多副本、高可用、可观测——这部分留到第三章(进阶原理)和第四章(实战案例)展开,包括 KV 缓存卸载、GPU 共享、灰度与压测。

本章小结

  • 权重放持久化存储(PVC / 本地盘 + 亲和),绝不在 Pod 内实时下载。
  • Deployment 三处易错点:探针延时、张量并行数与 GPU 数匹配、上下文长度受显存约束。
  • 用 Service 暴露、Ingress 加鉴权;多副本需 router 做会话亲和。

发布者: 作者: 转发
评论区 (0)
U