K8s基础回顾:Pod、Deployment、Service、Ingress核心概念

说实话,很多做AI推理的朋友一上来就问我:「vLLM怎么部署到K8s上?」

我的回答通常是——先别急。你得先把K8s这几个核心概念搞明白。不然出了问题,你连日志都不知道去哪看。

我在项目中见过太多次了:Pod挂了,Service没配好,流量全丢了。嗯,咱们今天就把这几个东西彻底捋清楚。

1. Pod:最小调度单元

Pod是K8s里最小的部署单元。说白了,就是一个或多个容器的「合租屋」。

  • 一个Pod里可以跑一个容器(最常见),也可以跑多个容器(比如sidecar模式)
  • Pod内的容器共享网络命名空间和存储卷
  • Pod是「临时」的——它随时可能被销毁、重建

重要提醒:vLLM服务通常一个Pod只跑一个推理容器。我建议你别把多个推理进程塞进同一个Pod,资源隔离会出问题。

2. Deployment:声明式更新

Deployment是管理Pod的「指挥官」。你告诉它「我要3个vLLM实例」,它就会帮你维持3个Pod一直运行。

我个人习惯用Deployment来管理无状态服务。vLLM推理服务正好是无状态的——模型加载到显存里,Pod挂了就重新拉起来。

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

我的经验:Deployment的滚动更新策略一定要配好。我曾经因为没配maxSurge,导致更新时所有Pod同时重启,服务完全中断了5分钟。

3. Service:稳定的访问入口

Pod的IP是动态的。今天这个Pod在,明天可能就没了。Service就是给这些「飘忽不定」的Pod一个固定的入口。

你想想看,客户端不可能每次去查Pod的IP吧?Service帮你做了负载均衡和DNS解析。

apiVersion: v1
kind: Service
metadata:
  name: vllm-service
spec:
  selector:
    app: vllm
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8000
  type: ClusterIP
Service类型 适用场景 我踩过的坑
ClusterIP 集群内部访问 默认类型,够用就别改
NodePort 外部调试用 端口范围有限,别用于生产
LoadBalancer 云上对外暴露 成本高,小项目慎用

4. Ingress:七层路由

Service解决了「谁能访问」的问题,但没解决「怎么路由」的问题。Ingress就是那个「看门人」——根据域名、路径把请求转发到不同的Service。

举个例子:api.mydomain.com/v1/completions 转到vLLM服务,api.mydomain.com/v1/chat 转到另一个服务。Ingress一把搞定。

注意:Ingress需要安装Ingress Controller才能工作。我见过有人配了Ingress资源但没装Controller,折腾了半天才发现。

vLLM服务在K8s上的典型部署架构

好了,概念讲完了。咱们看看vLLM在K8s上到底怎么搭。

我参与过好几个大模型推理平台的搭建,下面这个架构是我觉得最稳的。

vLLM服务K8s部署架构图 用户/客户端 Ingress (nginx-controller) Service (ClusterIP) vLLM Pod 1 GPU: A100 80G vLLM Pod 2 GPU: A100 80G 用户 Ingress Service vLLM Pod

部署要点总结

  • GPU资源:每个vLLM Pod申请1张GPU,别共享。我见过有人试图让两个推理进程共享一张卡,结果OOM了。
  • 模型加载:建议用InitContainer先下载模型到本地卷,再启动vLLM。不然每次Pod重启都要重新下载,慢得离谱。
  • 健康检查:一定要配liveness和readiness探针。vLLM启动慢(加载模型可能要几分钟),readiness探针能避免流量打到还没准备好的Pod上。
  • HPA自动扩缩:根据GPU利用率或请求QPS做自动扩缩。我习惯用QPS,因为GPU利用率有时候不准。

一个小技巧:vLLM的--max-model-len参数别设太大。设大了显存浪费,设小了长文本请求会失败。我一般根据业务场景算一下,留20%余量。

嗯,K8s基础就回顾到这里。这几个概念你吃透了,后面讲故障转移的时候才能跟上节奏。

一句话总结:Pod是车,Deployment是司机,Service是导航,Ingress是收费站。vLLM就是那个乘客,坐稳了就行。

专注资料整理