4. K8s核心概念:Pod、Deployment、Service、ConfigMap、Secret、Namespace

好,咱们进入正题。Kubernetes 的概念很多,但真正跟 vLLM 部署强相关的,其实就这几个。我刚开始接触 K8s 的时候,也被一堆术语搞得头大。后来发现,你只要把 Pod、Deployment、Service、ConfigMap、Secret、Namespace 这六个东西搞明白,80% 的日常运维场景你都能应付。

说白了,这六个概念就是 K8s 世界的“基本零件”。咱们一个一个拆开看。

4.1 Pod:最小的部署单元

Pod 是 K8s 里你能创建和管理的最小计算单元。一个 Pod 可以包含一个或多个容器。但在 vLLM 的场景下,我强烈建议一个 Pod 只跑一个 vLLM 容器。为什么?

  • 资源隔离更干净:每个 vLLM 实例独占 GPU 显存,互不干扰。
  • 故障域最小:一个 Pod 挂了,只影响它自己,不会拖累其他推理任务。
  • 扩缩容更灵活:你可以针对单个 Pod 做精细化的扩缩容策略。

核心要点:Pod 是“临时”的。它可能会因为节点故障、资源不足、OOM(内存溢出)等原因被 K8s 杀掉并重建。所以,永远不要依赖 Pod 的 IP 地址,那是会变的。

我在项目中遇到过一个问题:有个同事把 vLLM 的推理结果直接缓存在 Pod 的本地磁盘上。结果 Pod 一重启,缓存全丢了,用户反馈说模型回答变慢了。嗯,这就是典型的“把 Pod 当宠物养”的思维。Pod 是“牲口”,不是“宠物”。

4.2 Deployment:声明式的 Pod 管理器

Deployment 是干嘛的?它帮你管理 Pod 的期望状态。你告诉它:“我要跑 3 个 vLLM 实例。” Deployment 就会一直盯着,确保集群里始终有 3 个 Pod 在运行。

我个人习惯用 Deployment 来管理无状态的推理服务。比如 vLLM 这种,每个 Pod 都是等价的,谁处理请求都一样。

一个典型的 vLLM Deployment YAML 长这样:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: vllm
  template:
    metadata:
      labels:
        app: vllm
    spec:
      containers:
      - name: vllm
        image: vllm/vllm-openai:latest
        args: ["--model", "meta-llama/Llama-2-7b-chat-hf"]
        resources:
          limits:
            nvidia.com/gpu: 1
        ports:
        - containerPort: 8000

这里有几个关键点:

  • replicas: 3:告诉 K8s,我要 3 个副本。
  • resources.limits.nvidia.com/gpu: 1:每个 Pod 申请 1 块 GPU。这是 vLLM 部署的标配。
  • args:vLLM 的启动参数,指定模型路径。

避坑指南:我曾经把 replicas 设成 5,但集群里只有 4 块 GPU。结果有 1 个 Pod 一直处于 Pending 状态。K8s 不会主动告诉你“资源不够”,它只会默默等着。所以,部署前先算好 GPU 总量

4.3 Service:稳定的网络入口

Pod 的 IP 会变,那客户端怎么访问 vLLM 呢?Service 就是来解决这个问题的。它提供一个固定的虚拟 IP 和 DNS 名称,然后把请求转发给后端的 Pod。

对于 vLLM 推理服务,我们通常用 ClusterIP 类型的 Service。这样集群内部的其他服务(比如你的前端应用)可以通过服务名来访问 vLLM。

apiVersion: v1
kind: Service
metadata:
  name: vllm-service
spec:
  selector:
    app: vllm
  ports:
  - protocol: TCP
    port: 8000
    targetPort: 8000
  type: ClusterIP

你想想看,有了 Service,你的前端应用只需要记住 vllm-service:8000 这个地址就行了。不管后端 Pod 怎么重启、怎么漂移,客户端都不受影响。

重要:Service 的 selector 必须和 Deployment 的 matchLabels 保持一致。否则 Service 找不到后端 Pod,请求就会超时。我见过有人把 label 拼写错了,排查了半天才发现。

4.4 ConfigMap:配置与代码分离

vLLM 有很多配置参数,比如模型路径、最大输入长度、量化方式等。把这些参数硬编码在 YAML 里?不优雅。ConfigMap 就是用来存这些非敏感配置的。

举个例子,你可以把 vLLM 的启动参数抽出来:

apiVersion: v1
kind: ConfigMap
metadata:
  name: vllm-config
data:
  model-name: "meta-llama/Llama-2-7b-chat-hf"
  max-model-len: "4096"
  dtype: "auto"

然后在 Deployment 里通过环境变量引用:

env:
  - name: MODEL_NAME
    valueFrom:
      configMapKeyRef:
        name: vllm-config
        key: model-name

这样做的好处是:改配置不需要重新构建镜像。你只需要更新 ConfigMap,然后重启 Pod 就行了。我在生产环境里经常用这招来快速切换模型版本。

4.5 Secret:敏感信息的保险箱

ConfigMap 存的是明文,那 API Key、数据库密码、Hugging Face Token 这些敏感信息怎么办?用 Secret。

Secret 和 ConfigMap 很像,但它的值会被 Base64 编码(注意,这只是编码,不是加密)。K8s 会尽量保证 Secret 的数据不被泄露到日志或环境变量里。

对于 vLLM,如果你需要从 Hugging Face 下载私有模型,就需要用到 Secret:

apiVersion: v1
kind: Secret
metadata:
  name: hf-token
type: Opaque
data:
  token: aGZfxxxxxxxxxxxxxxxxxxxxx  # 你的 Base64 编码后的 Token

然后在 Pod 里挂载成环境变量:

env:
  - name: HUGGING_FACE_HUB_TOKEN
    valueFrom:
      secretKeyRef:
        name: hf-token
        key: token

警告:千万不要把 Secret 的原始值提交到 Git 仓库里。我曾经见过有人把生产环境的数据库密码直接写在 YAML 文件里,然后 push 到了公开仓库。那场面,简直是灾难。建议用 sealed-secretsexternal-secrets 这类工具来管理。

4.6 Namespace:虚拟集群的隔离墙

Namespace 是 K8s 用来逻辑隔离资源的机制。你可以把它理解成“虚拟集群”。不同的团队、不同的环境(开发、测试、生产)可以用不同的 Namespace 来隔开。

对于 vLLM 部署,我建议这样划分:

Namespace 用途 示例
vllm-dev 开发测试环境 跑小模型,调试参数
vllm-prod 生产环境 跑大模型,对外提供服务
vllm-monitoring 监控和日志 部署 Prometheus、Grafana

这样做的好处是:你在 vllm-dev 里随便折腾,不会影响到 vllm-prod 里的服务。而且,你可以给每个 Namespace 设置不同的资源配额(ResourceQuota),防止某个团队把集群资源吃光。

知识体系总览

下面这张图,是我自己总结的 vLLM 在 K8s 上的核心概念关系图。你看一眼,基本就明白这几个东西是怎么配合的了。

Namespace(虚拟集群) ConfigMap 非敏感配置 模型名、参数、路径 Secret 敏感信息 Token、密码、Key Deployment 声明式管理 Pod 副本数 replicas: 3 → 始终维持 3 个 Pod Pod(vLLM 实例) 每个 Pod 独占 1 块 GPU Service(稳定入口) 图例: 配置注入 管理/创建 网络代理

从这张图你可以看到:

  • ConfigMap 和 Secret 把配置注入到 Deployment 里。
  • Deployment 负责创建和管理 Pod。
  • Pod 是真正跑 vLLM 模型的地方。
  • Service 给 Pod 提供一个稳定的网络入口。
  • 所有这些资源,都跑在同一个 Namespace 里,实现逻辑隔离。

嗯,这六个概念你掌握了,K8s 的大门就算正式打开了。后面咱们会基于这些概念,一步步把 vLLM 部署到生产环境里。

我的建议:别急着背 YAML 语法。先理解每个概念是干什么的,它们之间怎么配合。语法忘了可以查文档,但架构思维一旦建立,你就能举一反三。


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