环境说明
本文记录一次 AI 推理服务上 K8s 前的检查流程,示例以 vLLM 服务为主。
目标不是讲模型调参,而是解决上线前常见的运行环境问题:
text
Pod 长时间 Pending
ImagePullBackOff
ContainerCreating 卡住
探针失败导致容器重启
GPU 利用率不稳定
回滚路径不清楚
排查顺序:
text
镜像依赖 -> GPU 节点 -> 资源声明 -> 探针 -> 日志指标 -> 回滚
1. 先验证关键镜像
推理服务通常涉及多个镜像:vLLM、CUDA 基础环境、监控组件等。先单独验证镜像,避免把镜像问题和 GPU 调度问题混在一起。
bash
docker pull docker.1ms.run/vllm/vllm-openai:latest
docker pull docker.1ms.run/nvidia/cuda:12.4.1-runtime-ubuntu22.04
docker pull docker.1ms.run/prom/prometheus:latest
这一步只确认依赖能进入当前环境。镜像通过以后,再继续看 GPU 和 Pod 事件。
2. 创建 namespace
yaml
apiVersion: v1
kind: Namespace
metadata:
name: ai-infer
应用推理服务时:
bash
kubectl apply -f namespace.yaml
3. Deployment 示例
下面是一个最小化示例,真实环境需要替换模型目录、参数和资源限制。
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: llm-api
namespace: ai-infer
spec:
replicas: 1
selector:
matchLabels:
app: llm-api
template:
metadata:
labels:
app: llm-api
spec:
nodeSelector:
accelerator: nvidia
containers:
- name: vllm
image: docker.1ms.run/vllm/vllm-openai:latest
args:
- "--model"
- "/models/qwen"
- "--host"
- "0.0.0.0"
- "--port"
- "8000"
ports:
- containerPort: 8000
resources:
limits:
nvidia.com/gpu: "1"
startupProbe:
httpGet:
path: /health
port: 8000
failureThreshold: 60
periodSeconds: 5
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 20
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 120
periodSeconds: 20
volumeMounts:
- name: model-dir
mountPath: /models
volumes:
- name: model-dir
persistentVolumeClaim:
claimName: qwen-model-pvc
关键点:
nodeSelector约束到 GPU 节点。resources.limits明确申请 GPU。startupProbe给模型加载留时间。- 模型目录放在 PVC,不建议把大模型权重塞进应用镜像。
4. Pod Pending 排查
bash
kubectl -n ai-infer get pod -l app=llm-api
kubectl -n ai-infer describe pod -l app=llm-api
kubectl get node -L accelerator
常见事件:
| 事件 | 可能原因 | 处理方向 |
|---|---|---|
Insufficient nvidia.com/gpu |
GPU 资源不足 | 看节点资源和现有 Pod 占用 |
node(s) didn't match node selector |
标签不匹配 | 检查节点标签 |
ImagePullBackOff |
镜像拉取失败 | 检查镜像地址和网络 |
FailedMount |
模型 PVC 问题 | 检查 PVC/PV 和权限 |
5. 镜像问题排查
如果看到 ImagePullBackOff:
bash
kubectl -n ai-infer describe pod -l app=llm-api
docker pull docker.1ms.run/vllm/vllm-openai:latest
如果节点能拉,Pod 不能拉,再看 imagePullSecrets、运行时配置和节点网络。
6. 探针失败排查
如果容器反复重启:
bash
kubectl -n ai-infer logs deploy/llm-api --previous
kubectl -n ai-infer describe pod -l app=llm-api
大模型服务冷启动时间长,探针不能按普通 Web 服务配置。建议拆分:
| 探针 | 作用 |
|---|---|
| startupProbe | 给模型加载和 GPU 初始化留时间 |
| readinessProbe | 控制什么时候接流量 |
| livenessProbe | 判断服务是否需要重启 |
7. GPU 状态检查
节点上看 GPU:
bash
nvidia-smi
K8s 侧看资源:
bash
kubectl top pod -n ai-infer
kubectl -n ai-infer logs deploy/llm-api --tail=120
如果 GPU 利用率低,但请求延迟高,需要继续看:
- 请求是否排队。
- batch 参数是否合理。
- 模型是否真正加载到 GPU。
- 是否有 CPU fallback。
- 是否被 readiness 提前接流量。
8. 回滚检查
bash
kubectl -n ai-infer rollout status deploy/llm-api
kubectl -n ai-infer rollout history deploy/llm-api
kubectl -n ai-infer rollout undo deploy/llm-api
推理服务回滚要同时确认:
text
镜像版本
模型权重版本
启动参数
Service 路由
监控告警
只回滚 Deployment,不回滚模型目录,可能会留下隐藏问题。
9. 上线前检查清单
text
镜像能单独拉取
GPU 节点标签明确
Pod 明确申请 GPU
模型目录可挂载
startupProbe 留足冷启动时间
readinessProbe 不提前接流量
livenessProbe 不误杀服务
日志能看到模型加载和错误
GPU 利用率和请求延迟能对应
Deployment 回滚已验证
总结
AI 推理服务上 K8s,不能只看 Pod 是否 Running。GPU 是昂贵资源,模型服务启动慢、探针误杀、调度不清楚、回滚没验证,都会放大上线风险。
建议上线前先按"镜像依赖、GPU 节点、资源声明、探针、日志、回滚"做一次体检。镜像只是第一层,真正决定稳定性的,是后面这些工程边界。