Kubernetes 基础对象:Pod、Job、Deployment、Service 等

这份文档先补 Kubernetes 基础概念。训练平台、推理平台、MLOps 平台最终都要落到 Kubernetes 对象上,所以必须先知道这些对象是什么、解决什么问题、彼此怎么关联。

一句话理解 Kubernetes:Kubernetes 是一个管理容器的集群操作系统。

它不直接管理你的 Python 脚本,而是管理这些对象:

对象 可以先理解成 主要作用
Node 机器 承载 Pod 和容器
Namespace 项目空间 做团队、项目、租户隔离
Container 运行中的程序环境 真正执行训练、推理或服务进程
Pod 最小调度单元 Kubernetes 调度和管理的基本单位
Job 一次性任务 管训练、数据处理、离线任务
Deployment 长期服务 管 API、控制器、推理服务等常驻副本
Service 稳定访问入口 给一组 Pod 提供固定访问地址
ConfigMap 普通配置 保存非敏感配置
Secret 敏感配置 保存密码、token、密钥、证书
PVC 存储声明 给 Pod 申请持久化存储

1. 总览图

text 复制代码
Cluster
├── Node:集群里的机器
│   ├── kubelet
│   ├── containerd
│   └── Pod
│       └── Container
│
└── Namespace:逻辑隔离空间
    ├── Job -> Pod -> Container
    ├── Deployment -> ReplicaSet -> Pod -> Container
    ├── Service
    ├── ConfigMap
    ├── Secret
    └── PVC

最重要的三条关系:

  • 训练任务:Job -> Pod -> Container -> python train.py
  • 平台服务:Deployment -> ReplicaSet -> Pod -> Container -> api server
  • 推理服务:Deployment/CRD -> Pod -> Container -> model server -> Service

2. Node:集群里的机器

Node 是 Kubernetes 集群里的机器,可以是物理机,也可以是云主机。你可以先简单理解为:Node = 一台服务器

AI Infra 里常见节点类型:

节点类型 作用
CPU 节点 跑平台 API、控制器、普通服务
GPU 节点 跑训练任务、推理服务
存储节点 提供数据、缓存或并行存储能力
控制面节点 跑 apiserver、scheduler、controller-manager 等核心组件

每个工作节点通常会有这些组件:

  • kubelet:节点代理,负责管理本机 Pod。
  • containerd:容器运行时,负责拉镜像、启动容器。
  • CNI:容器网络插件。
  • CSI/Volume plugin:存储挂载插件。
  • NVIDIA driver:GPU 驱动,GPU 节点才有。
  • NVIDIA Device Plugin:把 GPU 上报给 Kubernetes。

常用命令:

bash 复制代码
kubectl get node
kubectl get node -o wide
kubectl describe node <node-name>

GPU 节点重点看:

  • Allocatable 里有没有 nvidia.com/gpu
  • 节点是否 Ready
  • 节点是否有 taint
  • 节点 label 是否符合任务要求。
  • CPU、内存、GPU 是否足够。

3. Namespace:逻辑隔离空间

Namespace 是 Kubernetes 里的逻辑隔离空间。你可以理解为:Namespace = 项目空间 / 团队空间 / 租户空间

例如:team-ateam-blpaimonitoringkube-system

不同 namespace 里可以有同名 Pod,不冲突。AI 平台通常会用 namespace 做团队隔离、项目隔离、权限隔离、资源配额隔离,以及日志和任务归属区分。

常用命令:

bash 复制代码
kubectl get ns
kubectl get pod -n <namespace>
kubectl get all -n <namespace>

注意:如果你不加 -nkubectl 默认查 default namespace,排障时很容易查错地方。

4. Container:真正运行程序的地方

Container 是真正运行程序的环境。比如训练容器里可能执行:

bash 复制代码
python train.py

或者分布式训练命令:

bash 复制代码
torchrun --nproc_per_node=8 train.py

容器来自镜像:

概念 含义
Image 模板,包含文件系统、依赖、代码、启动环境
Container 镜像运行起来后的实例

训练容器可能包含 Ubuntu/CentOS、CUDA、cuDNN、Python、PyTorch、训练代码、业务依赖和启动脚本。

推理容器可能包含 Triton、vLLM、TensorRT-LLM、模型加载逻辑、HTTP/gRPC server、模型文件下载逻辑。

关键点:Kubernetes 不直接调度单个 Container,而是调度 Pod。

5. Pod:Kubernetes 最小调度单元

Pod 是 Kubernetes 里最小的调度和运行单元。你可以理解为:Pod = 一个或多个 Container 的组合

大多数业务场景下,一个 Pod 里只有一个主容器。但有时也会有多个容器。

同一个 Pod 里的容器共享:

  • 同一个 Pod IP。
  • 同一个网络命名空间。
  • 可以共享 volume。
  • 一定被调度到同一台 Node。
  • 生命周期强相关。

Pod 里常见容器类型:

类型 作用
主容器 真正跑业务,例如训练进程、推理服务
init container 主容器启动前先执行,例如准备目录、下载配置
sidecar container 辅助容器,例如日志采集、代理、service mesh sidecar

训练平台里的 Pod 可能长这样:

text 复制代码
Pod: train-resnet-xxxxx
├── main container: pytorch-training
│   └── command: python train.py
├── volume: training-data
├── env: NCCL_DEBUG=INFO
└── resources: cpu / memory / nvidia.com/gpu

常用命令:

bash 复制代码
kubectl get pod -n <namespace>
kubectl get pod -n <namespace> -o wide
kubectl describe pod <pod> -n <namespace>
kubectl logs <pod> -n <namespace>
kubectl exec -it <pod> -n <namespace> -- bash

如果 Pod 里有多个容器,需要指定容器名:

bash 复制代码
kubectl logs <pod> -n <namespace> -c <container-name>
kubectl exec -it <pod> -n <namespace> -c <container-name> -- bash

6. Pod 生命周期和状态判断

学 Kubernetes 排障时,光知道 Pod 是什么还不够,还要知道 Pod 从创建到运行经历哪些阶段。Pod 状态不是简单的"排队、运行、失败",它是在告诉你 Pod 卡在生命周期的哪一步。

一个 Pod 的典型链路是:

text 复制代码
创建 Pod -> 等待调度 -> 分配节点 -> 节点准备环境 -> 拉镜像 -> 挂载卷 -> 启动容器 -> Running -> Succeeded/Failed

Pending 不一定等于排队

Pending 有两种常见情况。

第一种是还没有调度到节点。这时 Node 为空,Events 里通常能看到 FailedScheduling。常见原因是 CPU、内存、GPU 不足,队列未准入,配额不足,亲和性不满足,节点污点不容忍,或者 PVC 没绑定。

第二种是已经调度到节点,但容器还没启动。这时 Node 已经有值,Events 里可能出现 FailedMountFailedCreatePodSandBoxPulling image 等事件。这种不是还在排队,而是节点准备阶段失败。

判断方式:

bash 复制代码
kubectl get pod <pod> -n <namespace> -o wide
kubectl describe pod <pod> -n <namespace>

重点看 NodeEvents

ContainerCreating:容器启动前准备阶段

ContainerCreating 表示 Pod 已经到节点上了,但容器还没有真正跑起来。这一阶段通常在做网络准备、volume 挂载、Secret/ConfigMap 准备、镜像准备、runtime 创建容器。

常见事件和含义:

事件 常见原因
FailedMount PVC、Secret、ConfigMap、CSI、存储系统问题
FailedCreatePodSandBox CNI 网络插件、pause 容器、containerd sandbox 问题
CreateContainerConfigError ConfigMap/Secret 不存在,环境变量引用错误
CreateContainerError runtime 创建容器失败,权限、挂载、runtime 配置问题

如果看到 Unable to attach or mount volumes,一般说明 Pod 已经调度到节点,但 kubelet 挂载 volume 失败或超时,不是还在调度排队。

ImagePullBackOff:镜像拉取问题

ImagePullBackOffErrImagePull 表示卡在拉镜像。

常见原因:镜像地址错误,tag 不存在,镜像仓库无权限,imagePullSecret 缺失,节点到仓库网络不通,镜像太大拉取超时,节点磁盘满。

Events 里常见线索:

线索 含义
manifest unknown 镜像 tag 不存在
pull access denied 镜像仓库权限问题
i/o timeout 网络或 registry 访问问题
no space left on device 节点磁盘满

Running:只代表容器进程活着

Running 不代表业务一定正常。它只说明至少有容器已经启动。

训练任务里常见情况包括:Pod Running 但训练没开始,GPU 利用率为 0,没有训练日志,卡在 torchrun rendezvous,或者 NCCL 初始化卡住。

这时才开始看业务日志和容器内部状态:

bash 复制代码
kubectl logs <pod> -n <namespace>
kubectl exec -it <pod> -n <namespace> -- ps -ef
kubectl exec -it <pod> -n <namespace> -- nvidia-smi

CrashLoopBackOff:容器启动后反复崩

CrashLoopBackOff 表示容器启动了,但很快退出,Kubernetes 按退避策略反复重启。

排查时要看当前日志和上一轮日志:

bash 复制代码
kubectl logs <pod> -n <namespace>
kubectl logs <pod> -n <namespace> --previous

--previous 很重要,因为上一轮崩溃容器的日志往往才是真正原因。

OOMKilled:容器内存超限

OOMKilled 表示容器 CPU 内存超过 limit,被 cgroup 杀掉。它不是 GPU 显存 OOM。

区别如下:

类型 表现
容器内存 OOM K8s 里看到 OOMKilled,退出码常见 137,Pod 可能重启
GPU 显存 OOM 训练日志里看到 CUDA out of memory,Pod 不一定重启

Succeeded 和 Failed

对于 Job 或训练任务,Succeeded 表示容器正常退出,退出码通常是 0;Failed 表示容器异常退出,退出码非 0,或者被系统杀掉。

常见退出码:

退出码 常见含义
0 正常退出
1 应用普通错误
126 命令不可执行
127 命令不存在
137 SIGKILL,常见 OOMKilled
143 SIGTERM,常见被删除、驱逐、优雅终止

最小判断顺序

看到 Pod 异常时,先按这个顺序判断:

  1. Pod 有没有 Node。没有 Node,优先看调度;有 Node,优先看节点准备或容器运行。
  2. Events 里是什么。FailedScheduling 看调度,FailedMount 看存储/volume,FailedCreatePodSandBox 看网络/CNI/sandbox,ImagePullBackOff 看镜像,CrashLoopBackOff 看容器日志,OOMKilled 看内存。
  3. 容器有没有真正启动。没启动时不要先看业务日志,先查 Events、kubelet、containerd;启动后再看 logs、previous logs、进程、端口和 GPU。

7. Job:一次性任务

Job 是 Kubernetes 里表示"一次性任务"的对象。你可以理解为:Job = 管理一次性 Pod 的控制器

Job 的目标是创建 Pod,等待 Pod 成功结束;如果失败,根据策略重试;最终 Job 进入 CompleteFailed

Job 适合这些场景:

  • 训练任务。
  • 数据处理任务。
  • 模型转换任务。
  • 离线评估任务。
  • 批处理脚本。

这些任务的共同特点是:开始、运行一段时间、成功或失败、结束。

Job 和 Pod 的关系:Job -> Pod -> Container -> python train.py

Job 不直接跑代码,它负责创建和管理 Pod。Pod 里的 Container 才真正执行命令。

常用命令:

bash 复制代码
kubectl get job -n <namespace>
kubectl describe job <job> -n <namespace>
kubectl get pod -n <namespace> --selector=job-name=<job-name>

常见问题:

  • Job 创建了但 Pod 没生成。
  • Pod 失败后 Job 不断重试。
  • backoffLimit 达到上限,Job Failed
  • Job Complete 但平台状态没同步。

8. Deployment:长期运行服务

Deployment 用来管理长期运行的服务。你可以理解为:Deployment = 管理常驻服务副本的控制器

它的目标是保证始终有指定数量的 Pod 在运行。例如声明 replicas = 3,如果一个 Pod 挂了,Deployment 会再创建一个新的 Pod,让副本数回到 3。

Deployment 适合这些场景:

  • 平台 API 服务。
  • Web 后端。
  • Controller 服务。
  • 推理服务。
  • 日志服务。
  • 普通常驻服务。

Deployment 和 Job 的区别:

对象 适合场景 行为
Job 一次性任务 跑完就结束
Deployment 长期服务 一直保持副本运行

训练任务通常用 Job 或训练 CRD。平台 API 和推理服务通常用 Deployment 或更高层 CRD。

常用命令:

bash 复制代码
kubectl get deploy -n <namespace>
kubectl describe deploy <deploy> -n <namespace>
kubectl rollout status deploy/<deploy> -n <namespace>
kubectl rollout history deploy/<deploy> -n <namespace>

9. ReplicaSet:Deployment 背后的副本控制器

ReplicaSet 负责保证某个 Pod 模板有指定数量的副本。

通常你不会直接操作 ReplicaSet,因为 Deployment 会自动管理它。它们的关系是:Deployment -> ReplicaSet -> Pod

为什么要知道它?因为排查 Deployment 时经常会看到 ReplicaSet。滚动发布时,Deployment 会创建新的 ReplicaSet,并逐渐替换旧的 ReplicaSet。

常用命令:

bash 复制代码
kubectl get rs -n <namespace>
kubectl describe rs <replicaset> -n <namespace>

10. Service:稳定访问入口

Pod 的 IP 是临时的。Pod 删除重建后,IP 可能变化。

Service 用来给一组 Pod 提供稳定访问入口。你可以理解为:Service = 一组 Pod 的固定访问地址

比如有 3 个推理 Pod:

Pod IP
model-pod-1 10.1.1.1
model-pod-2 10.1.1.2
model-pod-3 10.1.1.3

Service 提供一个稳定名字:model-service.default.svc.cluster.local。调用方访问 Service,Service 再把请求转发到后端 Pod。

在 AI 平台里的作用:

  • 训练场景:分布式训练可能用 Service 做 master/rendezvous 地址。
  • 推理场景:在线请求通过 Service 访问模型服务。
  • 平台场景:Web/API/controller 之间通过 Service 互相访问。

常用命令:

bash 复制代码
kubectl get svc -n <namespace>
kubectl describe svc <svc> -n <namespace>
kubectl get endpoints -n <namespace>
kubectl get endpointslice -n <namespace>

常见问题:

  • Service 存在但 endpoints 为空。
  • selector 配错,选不到 Pod。
  • Pod readiness 失败,不进入 endpoints。
  • 端口映射错误。
  • DNS 解析失败。
  • 网络策略阻断。

11. ConfigMap:普通配置

ConfigMap 用来保存普通配置,例如配置文件、启动参数、环境变量、非敏感开关、模型服务配置、训练参数模板。

Pod 可以把 ConfigMap 注入为环境变量、配置文件或挂载目录。

常用命令:

bash 复制代码
kubectl get cm -n <namespace>
kubectl describe cm <configmap> -n <namespace>
kubectl get cm <configmap> -n <namespace> -o yaml

注意:ConfigMap 不适合放密码、token、AK/SK。敏感信息应该放 Secret。

12. Secret:敏感配置

Secret 用来保存敏感信息,例如数据库密码、对象存储 AK/SK、token、证书、镜像仓库拉取密钥。

Pod 可以通过环境变量或文件挂载使用 Secret。

常用命令:

bash 复制代码
kubectl get secret -n <namespace>
kubectl describe secret <secret> -n <namespace>
kubectl get secret <secret> -n <namespace> -o yaml

Secret 比 ConfigMap 更适合放敏感信息,但它不是绝对安全。生产环境还需要结合 RBAC 权限控制、etcd 加密、审计日志、密钥轮转和最小权限原则。

13. PVC:持久化存储声明

PVC 全称 PersistentVolumeClaim,表示 Pod 向 Kubernetes 申请一块持久化存储。你可以理解为:PVC = Pod 申请一块可挂载的存储

Pod 是临时的。Pod 删除后,容器里的临时文件也会消失。训练任务通常需要持久化训练数据、checkpoint、模型输出、评估结果和共享工作目录,所以需要 PVC、对象存储或并行文件系统。

常用命令:

bash 复制代码
kubectl get pvc -n <namespace>
kubectl describe pvc <pvc> -n <namespace>

常见问题:

  • PVC Pending:没有绑定到 PV。
  • MountVolume failed:挂载失败。
  • 权限问题:容器内无法读写。
  • 容量不足:写 checkpoint 失败。
  • 存储慢:训练数据读取慢、checkpoint 慢。

14. Label 和 Selector

Label 是 Kubernetes 对象上的键值对标签,例如:

yaml 复制代码
labels:
  app: training-api
  task: train-resnet
  user: zhangsan

Selector 用来选择带有某些 label 的对象。

为什么重要:

  • Service 通过 selector 找后端 Pod。
  • Deployment 通过 selector 管理自己的 Pod。
  • 平台经常用 label 标记任务、用户、队列、项目。

常用命令:

bash 复制代码
kubectl get pod -n <namespace> --show-labels
kubectl get pod -n <namespace> -l app=training-api

常见问题:

  • Service selector 配错,导致 endpoints 为空。
  • Deployment selector 和 Pod label 不匹配,导致副本管理异常。

15. Taint 和 Toleration

Taint 是节点上的排斥标记,Toleration 是 Pod 对这种排斥的容忍。

简单理解:Node 有 taint 时,默认不让普通 Pod 上来;Pod 有对应 toleration 时,才允许调度到这个 Node。

AI Infra 里常见用途:

  • GPU 节点打 taint,避免普通服务占用 GPU 节点。
  • 故障节点打 taint,禁止新任务调度。
  • 专属队列节点打 taint,只允许特定团队使用。

常用命令:

bash 复制代码
kubectl describe node <node> | grep -i taint

如果 Pod Pending,Events 里看到 had untolerated taint,说明 Pod 没有对应 toleration。

16. Resource Request 和 Limit

Kubernetes 通过 request 和 limit 管理资源:

字段 含义
request 调度时承诺需要多少资源
limit 运行时最多能使用多少资源

例子:

yaml 复制代码
resources:
  requests:
    cpu: "4"
    memory: 16Gi
    nvidia.com/gpu: "1"
  limits:
    cpu: "4"
    memory: 16Gi
    nvidia.com/gpu: "1"

Scheduler 主要看 request 来决定能不能调度。cgroup 会用 limit 来限制容器资源。

常见问题:

  • request 太大:Pod Pending,调度不上。
  • limit 太小:容器 OOMKilled。
  • 没有设置 GPU request:容器拿不到 GPU。
  • CPU limit 太低:数据加载慢,GPU 利用率低。

17. 训练任务对象关系例子

一个普通训练任务可能长这样:

text 复制代码
Namespace: team-a
└── Job: train-resnet
    └── Pod: train-resnet-xxxxx
        ├── Container: pytorch-training
        │   └── Command: python train.py
        ├── ConfigMap: training-config
        ├── Secret: object-storage-secret
        ├── PVC: training-data
        └── Resources: cpu=8, memory=64Gi, nvidia.com/gpu=1

如果是分布式训练,可能是:

text 复制代码
PyTorchJob: bert-pretrain
├── master Pod -> Container: rank 0
├── worker Pod 1 -> Container: rank 1
├── worker Pod 2 -> Container: rank 2
└── worker Pod 3 -> Container: rank 3

18. 平台服务对象关系例子

平台 API 服务可能长这样:

text 复制代码
Namespace: ai-platform
├── Deployment: training-api
│   └── ReplicaSet
│       ├── Pod: training-api-xxx1
│       ├── Pod: training-api-xxx2
│       └── Pod: training-api-xxx3
├── Service: training-api-service
│   └── selects pods with app=training-api
├── ConfigMap: training-api-config
└── Secret: training-api-secret

Deployment 保证 API Pod 数量稳定,Service 给这些 Pod 提供稳定访问入口。

19. 推理服务对象关系例子

推理服务可能长这样:

text 复制代码
Namespace: model-serving
├── Deployment: llama-serving
│   └── Pod: llama-serving-xxxxx
│       └── Container: vllm-runtime
│           └── Command: start model server
├── Service: llama-serving-svc
│   └── exposes model server
├── PVC or object storage
│   └── model files
└── ConfigMap / Secret
    └── model config and credentials

推理服务更关注服务是否 Ready、Service endpoints 是否正常、模型是否加载成功、GPU 显存是否够、请求延迟和错误率是否正常。

20. 日常最常用命令

查 namespace:

bash 复制代码
kubectl get ns

查 Pod:

bash 复制代码
kubectl get pod -n <namespace>
kubectl get pod -n <namespace> -o wide
kubectl describe pod <pod> -n <namespace>
kubectl logs <pod> -n <namespace>

进入容器:

bash 复制代码
kubectl exec -it <pod> -n <namespace> -- bash

查 Job:

bash 复制代码
kubectl get job -n <namespace>
kubectl describe job <job> -n <namespace>

查 Deployment:

bash 复制代码
kubectl get deploy -n <namespace>
kubectl describe deploy <deploy> -n <namespace>

查 Service:

bash 复制代码
kubectl get svc -n <namespace>
kubectl get endpoints -n <namespace>

查配置、密钥和存储:

bash 复制代码
kubectl get cm -n <namespace>
kubectl get secret -n <namespace>
kubectl get pvc -n <namespace>
kubectl describe pvc <pvc> -n <namespace>

查事件:

bash 复制代码
kubectl get events -n <namespace> --sort-by=.lastTimestamp

21. 最终记忆版

先把这些关系背下来:

对象 记忆方式
Node 集群里的机器
Namespace 项目/团队/租户隔离空间
Container 真正跑程序的地方
Pod Kubernetes 最小调度单元,里面放 Container
Job 管一次性任务,适合训练、数据处理、离线任务
Deployment 管长期服务,适合 API、控制器、推理服务
Service 给一组 Pod 提供稳定访问入口
ConfigMap 普通配置
Secret 敏感配置
PVC 持久化存储声明
Label/Selector 给对象打标签并选择对象
Taint/Toleration 控制 Pod 能不能上某些节点
Request/Limit 管理资源申请和资源上限

再记三条对象链路:

  • 训练任务:Job -> Pod -> Container -> python train.py
  • 平台服务:Deployment -> ReplicaSet -> Pod -> Container -> API Server
  • 推理服务:Deployment/CRD -> Pod -> Container -> Model Server -> Service

后续学习 Kubernetes 排障时,所有状态和事件都围绕这些对象展开。

相关推荐
析数塔1 天前
AI 时代测试开发新范式:从用例验证到 Agent 评测体系
agent·测试·aiops
SRETalk3 天前
如何使用 AI 解答开源项目的问题,其实只需要一句话
aiops·categraf
SRETalk4 天前
夜莺开源监控如何使用 Docker 部署,有哪些注意事项?
aiops·夜莺监控
小猿姐15 天前
MySQL Top 10 热点问题 AI 运维实战:从内核诊断到云原生运维
mysql·云原生·aiops
属鼠哥16 天前
一场正在发生的范式转变:Loop Engineering(循环工程)
人工智能·aiops
AIOps打工人17 天前
新人用 AI 30 分钟,我并不高兴
aiops
松岩20 天前
网络问题导致 Pod Pending
kubernetes·aiops
云智慧AIOps社区1 个月前
轻帆云ITSM|制造业智能化转型,从流程重构看 IT 服务管理发展新趋势
运维·自动化·aiops·智能运维·itsm平台·it服务管理系统