跳到主要内容

L1.7 Kubernetes 核心对象:Pod / Service / Ingress

三维坐标 layer: L1(算力与编排)level: Engineerpillar: 硬件架构

L1.4 讲 GPU 调度与 Gang 编排时,默认你已经能读懂一份 K8s YAML。本章补齐这块前置:Pod 是什么、Service 怎么暴露、Ingress 怎么接流量——以及 AI 作业里最常见的 Pending / CrashLoopBackOff 怎么查。

学习目标

  • 前置知识:读过 L0.6 环境基线(装过 Docker / kind);会用命令行。无需自有 K8s 集群。
  • 学完产出:① 能画出「Deployment → ReplicaSet → Pod」的控制关系,说清 Pod 为何是 K8s 最小调度单元;② 能区分 ClusterIP / NodePort / LoadBalancer 三种 Service 类型及 AI 推理服务的典型选型;③ 能写一份带 resources.limitslivenessProbe 的最小 Deployment + Service YAML;④ 能用 kubectl describe pod 读懂 Events 里的 Pending / OOM / ImagePullBackOff 根因;⑤ 在 kind 本地集群亲手部署一个 mock 推理 Pod 并通过 Service 访问。
  • 阅读姿势:K8s 对 AI Infra 工程师不是「运维选修课」,而是读调度 YAML、查 Gang Job、对接 GPU Operator 的通用语言

背景与现状

Kubernetes 把「跑容器」抽象成声明式 API:你描述期望状态(3 副本、每 Pod 1 GPU、镜像 v1.2),控制平面持续 reconcile 直到实际状态匹配。AI 平台(Kubeflow、Volcano Job、vLLM Helm Chart)最终都落在这套对象上。

对象职责AI 场景举例
Pod最小调度单元,1+ 容器共享网络/存储单卡训练 Worker、vLLM 推理实例
Deployment无状态多副本,滚动升级水平扩展的推理网关
Job / CronJob跑完即停 / 定时批任务离线评估、Embedding 回填
Service稳定虚拟 IP + DNS,负载均衡到 Pod集群内访问推理 API
IngressHTTP/HTTPS 七层路由对外暴露 /v1/chat/completions
ConfigMap / Secret非敏感 / 敏感配置注入模型路径、API Key

业界信号:几乎所有云厂商 AI 平台(EKS/GKE/ACK + Volcano/Kueue)的 GPU 作业最终都是 Pod + 自定义 CRD。不会读 Pod YAML,就无法排查「为什么 8 卡 Job 只起了 6 个」。

原理与架构

2.1 控制平面与数据平面

读图要点:你提交的 YAML 存进 etcd;Deployment 控制器创建 ReplicaSet 再创建 Pod;调度器把 Pod 绑定到节点;kubelet 拉镜像并启动容器。

2.2 Pod 生命周期与常见状态

状态含义AI 常见根因
Pending已创建未调度或未拉镜像资源不足(GPU 不够)、节点选择器不匹配、镜像拉取慢
Running容器已启动正常
CrashLoopBackOff启动后反复退出CUDA 版本错、入口命令错、OOM
CompletedJob 成功结束批处理正常
FailedJob 失败训练脚本非零退出

2.3 Service 三种类型

  • ClusterIP:集群内 DNS my-svc.default.svc.cluster.local,Sidecar / 其他微服务互访。
  • NodePort:开发调试;生产少用(端口管理混乱)。
  • LoadBalancer:云环境对外暴露推理 API 的默认方式;配合 Ingress 做路径路由。

2.4 Ingress:七层路由

Ingress 不替代 Service,而是在 Service 之上做 HTTP 路由:

# 示意:/v1/* → vllm-svc,/metrics → prom-svc
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: llm-ingress
spec:
rules:
- host: infer.example.com
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: vllm-svc
port:
number: 8000

动手实践:kind 上部署 mock 推理服务

实验目标:用 kind 起集群,部署一个返回 JSON 的 mock 推理 Deployment,通过 ClusterIP Service 在集群内 curl 通。

环境前置

kind create cluster --name k8s-basics 2>/dev/null || true
kubectl cluster-info

步骤 1:Deployment + Service

# mock-infer.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mock-infer
spec:
replicas: 2
selector:
matchLabels:
app: mock-infer
template:
metadata:
labels:
app: mock-infer
spec:
containers:
- name: server
image: python:3.11-slim
command: ["python", "-m", "http.server", "8080"]
ports:
- containerPort: 8080
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
livenessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: mock-infer-svc
spec:
selector:
app: mock-infer
ports:
- port: 80
targetPort: 8080
type: ClusterIP
kubectl apply -f mock-infer.yaml
kubectl get pods -w # 等到 2/2 Running
kubectl get svc mock-infer-svc

步骤 2:集群内访问

kubectl run curl-test --rm -it --restart=Never --image=curlimages/curl -- \
curl -s http://mock-infer-svc/
# 预期:返回 Simple HTTP server 页面 HTML

步骤 3:排查练习

# 故意改错镜像名,观察 ImagePullBackOff
kubectl set image deployment/mock-infer server=python:nonexistent-tag
kubectl describe pod -l app=mock-infer | tail -20
kubectl rollout undo deployment/mock-infer

踩坑预警

  1. resources 不写 limits:在共享集群上容易被 OOMKill 或挤占邻居;GPU Job 必须写 nvidia.com/gpu: 1
  2. Probe 探针路径错:liveness 失败会无限重启,表现为 CrashLoop;readiness 失败则不会接流量。
  3. Service selector 与 Pod label 不一致:Service 存在但无 Endpoints,curl 超时。
  4. kind 默认无 LoadBalancerEXTERNAL-IP 长期 <pending> 是正常的,用 kubectl port-forward 或 Ingress 代替。

配套代码ai-infra-labs run_k8s_basics.sh — kind + mock Deployment/Service 一键验收。

深入思考

思考题:为什么 AI 训练 Job 常用 Job 而非 Deployment?

展开参考答案

Deployment 面向长期运行的无状态服务:Pod 挂了会自动重建,期望副本数恒定。分布式训练 Worker 跑完就退出,不应被「自动重建」——否则 checkpoint 语义混乱。

Job(及 Volcano Job / PyTorchJob CRD)面向有终点的批计算completions 个 Pod 成功即 Completed;失败可按 backoffLimit 重试。Gang 调度(L1.4)在 Job 之上再加 PodGroup,保证 8 卡同时就绪。

推理服务用 Deployment(7×24);训练/评估用 Job。混用是平台设计的第一性选型。

延伸阅读