4、第一个Pod:编写YAML文件部署vLLM Pod、Pod的生命周期管理、查看Pod日志与状态

好,咱们今天来点真格的。前面聊了那么多概念,什么容器、镜像、Pod,都是纸上谈兵。今天,我带你亲手把第一个vLLM推理服务跑起来。你想想看,一个能真正处理请求的Pod,从无到有,就在你眼前诞生——这种感觉,比看一百篇文档都来得实在。

我个人习惯,学K8s的第一步,就是先写一个Pod的YAML文件。别急着上什么Deployment、StatefulSet,先把最基础的Pod玩明白。Pod是K8s世界里最小的调度单元,说白了,它就是一组容器的集合。咱们的vLLM推理服务,就住在这个Pod里。

4.1 编写第一个Pod的YAML文件

YAML文件,就是K8s的“配置文件”。你告诉它你想跑什么镜像、开几个端口、需要多少资源,它就去帮你搞定。我刚开始接触YAML时,总觉得缩进很烦人,一个空格不对,整个Pod就起不来。嗯,这里要注意,YAML对缩进极其敏感,必须用空格,不能用Tab。

下面这个YAML,是我在生产环境中常用的一个简化版。它定义了一个名为 vllm-pod 的Pod,里面跑了一个vLLM容器。

apiVersion: v1
kind: Pod
metadata:
  name: vllm-pod
  labels:
    app: vllm
    tier: inference
spec:
  containers:
  - name: vllm-container
    image: vllm/vllm-openai:latest
    ports:
    - containerPort: 8000
      name: http
    env:
    - name: MODEL_NAME
      value: "Qwen/Qwen2.5-7B-Instruct"
    - name: MAX_MODEL_LEN
      value: "4096"
    resources:
      requests:
        memory: "8Gi"
        cpu: "2"
      limits:
        memory: "16Gi"
        cpu: "4"
    command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
    args: ["--model", "$(MODEL_NAME)", "--port", "8000", "--max-model-len", "$(MAX_MODEL_LEN)"]
  restartPolicy: Always

我来拆解一下这个文件里的关键字段:

  • apiVersion:K8s API的版本。对于Pod,v1是最稳定的版本,放心用。
  • kind:资源类型。这里就是Pod。
  • metadata:元数据。name是Pod的名字,labels是标签,后面做服务发现、筛选全靠它。
  • spec.containers:核心部分。定义容器镜像、端口、环境变量、资源限制。
  • resources:requests是“最低保障”,limits是“上限”。我在项目中遇到过,如果不设limits,某个Pod可能会把节点上的内存吃光,导致其他Pod被驱逐。所以,一定要设limits。
  • command & args:覆盖镜像的默认启动命令。这里我直接调用了vLLM的OpenAI兼容API服务器。
  • restartPolicy:Pod挂了怎么办?Always表示总是重启。对于推理服务,这很合理。
小技巧: 我个人习惯把环境变量单独抽出来,而不是硬编码在args里。这样方便后续用ConfigMap或Secret来管理,不改YAML就能换模型。

4.2 部署Pod:从YAML到运行

YAML写好了,怎么让它跑起来?很简单,用 kubectl apply 命令。这是K8s里最常用的命令之一,没有之一。

# 部署Pod
kubectl apply -f vllm-pod.yaml

# 查看Pod状态
kubectl get pods -o wide

# 查看更详细的信息
kubectl describe pod vllm-pod

执行 kubectl apply 后,K8s会做几件事:

  1. API Server校验YAML的合法性。
  2. Scheduler找一个合适的节点来运行这个Pod。
  3. Kubelet在节点上拉取镜像、启动容器。

整个过程,快则几秒,慢则几分钟(取决于镜像大小和网络速度)。我记得第一次部署vLLM时,镜像有十几个G,等了快十分钟。当时我还以为Pod卡住了,后来发现是镜像在后台慢慢拉。所以,建议你先用个小模型测试,比如Qwen2.5-0.5B,镜像小很多。

注意: 如果Pod一直处于 Pending 状态,别慌。用 kubectl describe pod 看看Events部分,通常会有提示。最常见的原因是资源不足(CPU/内存不够)或镜像拉取失败。

4.3 Pod的生命周期管理

Pod不是一成不变的。它有自己的一套生命周期。理解这个,你才能知道Pod现在在干嘛,以及接下来会干嘛。

Pod的生命周期,大致分为这几个阶段:

阶段 状态 说明
Pending 等待中 Pod已被K8s接受,但容器还没启动。可能是在拉镜像,或等待调度。
Running 运行中 至少有一个容器正在运行,或者正在启动/重启。
Succeeded 成功 Pod里的所有容器都正常退出,不会再重启。通常用于一次性任务。
Failed 失败 至少有一个容器以非0状态退出。
Unknown 未知 K8s无法获取Pod的状态,通常是节点通信出了问题。

除了这些阶段,Pod内部还有更细粒度的容器状态

  • Waiting:容器正在等待,比如拉镜像、等待卷挂载。
  • Running:容器正常运行。
  • Terminated:容器已结束运行,可能是正常退出或异常退出。

为什么会这样设计?说白了,Pod是一个“容器组”,组里每个容器都有自己的状态。K8s把Pod的状态和容器的状态分开管理,这样更灵活。比如,一个Pod里有三个容器,其中一个挂了,Pod可能还是Running状态(因为其他容器还在跑),但那个挂了的容器会显示Terminated。

核心要点: 你平时最关心的,其实是Pod的 READY 列。比如 1/1 表示Pod里定义了一个容器,且这个容器已经就绪。如果是 0/1,说明容器还没准备好,服务不可用。

4.4 查看Pod日志与状态

Pod跑起来了,怎么知道它里面发生了什么?怎么排查问题?这时候,日志和状态信息就是你的眼睛。

4.4.1 查看Pod日志

kubectl logs 命令,可以实时查看Pod里容器的标准输出。

# 查看Pod日志
kubectl logs vllm-pod

# 如果Pod里有多个容器,需要指定容器名
kubectl logs vllm-pod -c vllm-container

# 实时跟踪日志(类似 tail -f)
kubectl logs -f vllm-pod

# 查看最近100行日志
kubectl logs --tail=100 vllm-pod

我曾经遇到过一个情况:vLLM Pod启动后,一直报 CUDA out of memory。我第一反应是资源限制设小了。但看了日志才发现,原来是模型加载时默认用了float32,显存占用翻倍。后来我在环境变量里加了 --dtype half,问题就解决了。你看,日志就是最好的老师。

4.4.2 查看Pod状态

除了日志,你还需要了解Pod的“体检报告”。kubectl describe pod 是最强大的诊断工具。

kubectl describe pod vllm-pod

这个命令会输出一大堆信息,我重点看这几个部分:

  • Conditions:Pod的运行时条件,比如 PodScheduled(是否已调度)、Initialized(初始化容器是否完成)、Ready(Pod是否就绪)。
  • Events:这是最关键的。Pod从创建到现在的所有事件,按时间倒序排列。如果Pod启动失败,这里会告诉你原因,比如 Failed to pull imageBack-off restarting failed container
  • Containers:每个容器的状态、镜像、资源限制、挂载点等。
我的习惯: 每次部署新Pod,我都会先跑一次 kubectl describe pod,看看Events里有没有Warning。很多潜在问题,在Pod还没完全失败时,Events里就已经有提示了。别等到服务挂了才去看。

4.5 本章知识体系图

下面这张图,帮你把本章的核心逻辑串起来。从编写YAML,到部署Pod,再到监控生命周期和排查问题,每一步都环环相扣。

Pod 生命周期与运维核心流程 1. 编写 YAML apiVersion / kind metadata / spec 2. 部署 Pod kubectl apply -f kubectl get pods 3. 生命周期 Pending → Running Succeeded / Failed 4. 查看日志与状态 kubectl logs -f vllm-pod kubectl describe pod vllm-pod 排查 Events Conditions 核心原则:先写YAML → 再部署 → 看状态 → 查日志 → 循环优化 Pod 是 K8s 的基石,玩透它,后面的一切都顺理成章

好了,第一个Pod的完整流程,咱们就走了一遍。从写YAML到部署,从看生命周期到查日志,每一步都是实战中必须掌握的。你想想看,以后不管遇到什么复杂的K8s问题,追根溯源,最后都会落到Pod上。把Pod玩明白,你就已经入门了。

嗯,我个人建议,你现在就去自己的集群上,亲手跑一遍这个vLLM Pod。哪怕只是跑起来再删掉,也比看十遍文档强。遇到问题别怕,用 describelogs 这两个命令,大部分坑都能自己填上。


专注资料整理