九章智算云

给 AI 工程师的 Kubernetes 速通——概念与最小可用方案

Pod、Deployment、Job、PVC、StatefulSet——只讲在 GPU 工作流里真正会用到的那部分,不讲全套 K8s。

写这篇的动机

GPU 云客户里 70% 的工程师没怎么写过 K8s,但只要做训练编排、推理上线、批量推理,就绕不开它。下面这份是我在客户内训反复讲过的一个最小子集——背完这些就能干活,剩下的等踩坑再说。

一、最小心智模型

Pod        → 一组共享网络/存储的容器,调度的最小单元
Deployment → 滚动管理一堆无状态 Pod(推理服务用这个)
StatefulSet→ 有状态 Pod,有稳定名字 + 稳定卷(分布式训练 worker 常用)
Job        → 跑一次就结束(一次性微调、批量推理)
CronJob    → 定时跑的 Job
Service    → 给 Pod 群起一个稳定 IP / 域名
Ingress    → HTTP 流量从外部进来怎么路由
PVC + PV   → 持久卷申请和实际卷
ConfigMap  → 配置注入
Secret     → 密码 / Token 注入(base64,不是加密)
Namespace  → 软隔离 + 配额边界

记住一句:K8s 把"一台机器能干的事"扩展成"一组机器声明式地干这件事"——你写 YAML 描述目标态,控制器把现实拽过去。

二、kubectl 八件套

kubectl get pods -A                  # 看所有 Pod
kubectl describe pod <p>             # 看为什么 Pending / CrashLoop
kubectl logs -f <p> [-c <container>] # 跟日志
kubectl exec -it <p> -- bash         # 进容器
kubectl apply -f xxx.yaml            # 声明式提交
kubectl delete -f xxx.yaml           # 撤销
kubectl port-forward <p> 8080:8080   # 本地端口转发
kubectl top pod                      # 资源占用(需要 metrics-server)

90% 的现场排障都是先 describe 看 Events,再 logs 看进程输出,最后 exec 进去摸一摸。

三、训练 Job 的最小 YAML

单卡微调任务:

apiVersion: batch/v1
kind: Job
metadata:
  name: lora-sft-qwen
spec:
  backoffLimit: 0
  template:
    spec:
      restartPolicy: Never
      nodeSelector:
        nvidia.com/gpu.product: H100-SXM5
      containers:
      - name: trainer
        image: registry.alayanew.com/llamafactory:0.9
        command: ["bash", "-lc", "llamafactory-cli train cfg.yaml"]
        resources:
          limits:
            nvidia.com/gpu: 1
            cpu: "16"
            memory: 128Gi
        volumeMounts:
        - { name: data,  mountPath: /data }
        - { name: model, mountPath: /model }
      volumes:
      - name: data
        persistentVolumeClaim: { claimName: pvc-data }
      - name: model
        persistentVolumeClaim: { claimName: pvc-model }

要点:

  • nvidia.com/gpu 只能写在 limits 里,requests 自动等于 limits;写错了会被 admission 拒掉。
  • 训练任务用 Job别用 Deployment——失败后 Deployment 会无限拉起。
  • backoffLimit: 0 表示失败一次就停,方便排查。

四、推理 Deployment 的最小 YAML

apiVersion: apps/v1
kind: Deployment
metadata: { name: vllm-qwen }
spec:
  replicas: 2
  selector: { matchLabels: { app: vllm-qwen } }
  template:
    metadata: { labels: { app: vllm-qwen } }
    spec:
      containers:
      - name: vllm
        image: vllm/vllm-openai:v0.7.2
        args:
        - --model=/model/qwen3-72b
        - --tensor-parallel-size=4
        resources:
          limits: { nvidia.com/gpu: 4 }
        ports: [{ containerPort: 8000 }]
        readinessProbe:
          httpGet: { path: /health, port: 8000 }
          initialDelaySeconds: 60
          periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata: { name: vllm-qwen }
spec:
  selector: { app: vllm-qwen }
  ports: [{ port: 80, targetPort: 8000 }]

readinessProbe 一定加——不加滚更新会把流量打到还没加载完模型的 Pod,前端就 503 了。

五、踩坑清单

  1. GPU 分配不均:默认调度器只看 nvidia.com/gpu 数量,不知道 NVLink 拓扑——大模型训练务必配 topologyManager policy=single-numa-node,或用九章智算云提供的 GPU-aware 调度器。
  2. PVC 抢锁ReadWriteOnce 卷绑定一个节点,跨节点 Pod 起不来。多 worker 共享数据集要用 ReadWriteMany(CephFS / NAS)。
  3. OOMKilled 不报错:Pod 直接 137 退出,describe 才看得到 Reason: OOMKilled——一律先看 Events。
  4. HostPort 和 GPU 冲突:同节点同 hostPort 的 Pod 互斥,会让 0.5 张 GPU 闲置;尽量用 Service。

最后更新于

这篇文档对你有帮助吗?

目录