Kubernetes Pod 从创建到运行全流程拆解:5 个阶段 + 排错实录

你有没有盯着一个 Pending 的 Pod 骂过娘?明明 YAML 没错,就是起不来,然后对着屏幕发呆。老实说,我刚搞 K8s 那阵子,经常被一个 CrashLoopBackOff 整到怀疑人生。

后来我静下心把 Pod 从提交到跑起来的每一步都捋了一遍,画了张流程图,再遇到问题顺着链路一摸一个准。今天把这些东西掰开揉碎讲给你听,全是 SRE 视角的实战经验,版本基于 Kubernetes 1.28(我测试用的集群版本),其它小版本也差不多,核心链路没变。


你需要的背景和准备

这篇文章适合正在和 Pod 状态斗智斗勇的开发、运维、SRE。你要有:

  • 一个能用的集群(Minikube、Kind 都行)
  • kubectl 客户端,能执行 applydescribe
  • 对 Pod、Deployment 这些概念有基本认知

光看不练没用,建议你边看边敲。


Pod 诞生五步曲

我把整个过程拆成五个阶段,每个阶段卡住,Pod 状态就会停在某个中间态。下面从 kubectl apply 开始讲起。

1. 准入与持久化------你的 YAML 去哪了?

你敲下 kubectl apply -f pod.yaml 之后,请求第一时间到 API Server 。别以为就直接写 etcd 了,先得过三关:认证 → 授权 → 准入控制

认证授权基本不会出大问题,问题多半出在准入控制。比如你写了个 privileged: true 的容器,刚好集群开了 PodSecurity 准入,直接给你拒掉,API Server 返一个 forbidden 的错误。我当初就因为这个,在工位上折腾了半小时,事件里才看到 "violates PodSecurity" 字样。

过完这三关,API Server 才把 Pod 对象序列化写入 etcd 。这时候 Pod 只是 etcd 里一条普普通通的记录,没有 nodeNamestatus.phasePending。换句话说,Pod 还是个"黑户",连该去哪台机器都不知道。

这步最容易炸的点 :要是你配了 ValidatingWebhook 或 MutatingWebhook,而 webhook 服务挂了或超时,API Server 会一直等,然后报 failed calling webhook。我遇到过一次,集群升级后旧的 webhook 还没适配,新 Pod 全都建不出来。遇到这种,临时踢掉 webhook 就能应急。

小细节:kubectl apply 会把 YAML 干进了 etcd,但 Deployment 之类的控制器还要额外创建 ReplicaSet,那是另一条链路,这里只聚焦 Pod 自己。

2. 调度------Scheduler 该上场了

Scheduler 通过 watch 机制发现了一个 nodeName 为空的 Pod,于是摩拳擦掌开始干活。流程是经典的预选 + 优选 :先把不符合条件的节点踢掉(资源不足、有污点且 Pod 没容忍、节点选择器不匹配等等),再给剩下的节点打分,最后把得分最高的节点写回 Pod 的 spec.nodeName,再经由 API Server 存入 etcd。

调度失败的 Pod 会一直 Pending ,你在 kubectl describe pod 里能看到类似 "0/3 nodes are available: 3 node(s) had untolerated taint" 的提示。我看过太多人给 Pod 设了 8C 16G 的资源请求,但整个集群每个节点才 4C 8G,不 pending 才见鬼。还有那种忘记给 GPU 节点加 toleration 的,一样卡住。

说一个我踩过的坑:集群节点很多(几百台),调度变慢。后来我调了 Scheduler 的 percentageOfNodesToScore 参数,只让部分节点参与优选,速度立马上去,但代价是可能不会选到全局最优节点。这个适合大规模集群,小集群别碰。

3. 容器创建前奏------kubelet 接手,CNI 也来了

一旦 Pod 被钉到某个节点,该节点上的 kubelet 就通过 watch 拿到了属于它的 Pod。kubelet 做事很守规矩,先不急着拉业务镜像,而是调 CRI 创建 Pod Sandbox

Sandbox 是什么?其实就是给 Pod 搞一个共享的命名空间(网络、IPC 等),本质上是一个 pause 容器。也正是这一步,会触发 CNI 插件给 Pod 分配网络------建网络命名空间、分 IP、配路由。网络不通或者 CNI 插件炸了,Pod 就卡在 ContainerCreating,事件里能看到类似 "network: failed to allocate for range" 这样的错误。

我遇到最坑爹的一次:集群网络插件是 Calico,calico-node 这 Pod 自己挂逼了,结果所有新 Pod 全部停在 ContainerCreating,一查节点上的 calico 日志,发现连不上 etcd。重启 calico-node,世界清净了。

所以,ContainerCreating 很久不结束,不要只看 Pod 事件,顺便看一眼节点上 kubelet 日志和 CNI 组件的健康状况。

4. 拉镜像、建容器------终于到你写的应用了

Sandbox 网络搞通之后,kubelet 才开始拖业务镜像。镜像拉取是这个阶段最熟悉也最烦人的拦路虎:ImagePullBackOff 。原因千奇百怪:镜像名拼错、tag 不存在、私有仓库没配 imagePullSecrets、网络不通...... 我有次把 image: myapp:latest 推到仓库,结果仓库里根本没有 latest tag,一直拉不下来,查了十分钟才发现 tag 没推成功。

拉完镜像,kubelet 调 CRI 创建并启动容器。如果你的 CMDENTRYPOINT 有问题,容器启动就退出了。kubelet 会根据 restartPolicy 不断地重启,表现出来就是 CrashLoopBackOff。这时候你要做的是:

  • kubectl describe pod 看容器退出码(Exit Code)------非 0 基本就是应用崩了
  • kubectl logs 抓日志,看应用报错
  • 如果容器还没启动就死了,可能在挂载卷阶段就炸了

说到挂载卷,CreateContainerConfigError 也是高频错误。ConfigMap 或 Secret 名字写错、不存在,Pod 事件会直接告诉你 "MountVolume.SetUp failed for volume xxx"。我曾经把 secretName 写成 secretname,YAML 里不明显,排查时气得想抽自己。

5. 就绪与健康------探针拍板能不能接流量

容器跑起来,还没完。kubelet 会按你配的探针来检查容器是否真正健康,这才是服务可用的最后一道关卡。

如果你配了 startupProbe,kubelet 会先跑它。成功之后才开始跑 livenessProbereadinessProbe。startupProbe 特别适合 Java 这种慢启动的,我以前给一个 Spring Boot 应用配了长 failureThreshold,避免还没启动完就被 liveness 杀掉。但有一点要注意:startupProbe 失败会导致容器重启,跟 liveness 一样,只是它只在启动阶段有效。

readinessProbe 成功的那一刻,Pod 的状态才变成 Running 且 Ready 为 True,接着才会被 Endpoint Controller 加进 Service 的端点里,流量才真正打进来。如果 readiness 一直失败,Pod 显示 Running 但 ready 是 0/1,线上部署看着 Pod 全绿,实则一个请求都接不住,这是典型的"假 Running",我当年在凌晨上线时被坑惨了。

整个流程走完,Pod 终于可以正常干活了。


怎么验证全流程

你随便搞个 Pod 一 apply,用下面命令看实时事件,一清二楚:

复制代码
kubectl get events --watch

更细的用:

复制代码
kubectl describe pod <pod-name>

重点关注 ConditionsEvents 的时间线,哪一步卡住一目了然。我还习惯看 kubectl get pod -o yaml 里的 status 字段,有时调度信息、网络 IP 分配都在里面。


常见错误速查

|----------------------------|---------------------------------|
| 状态 / 现象 | 可能根因 |
| 一直 Pending,无可用节点 | 资源不够、污点容忍缺失、nodeSelector/亲和性不满足 |
| ContainerCreating 超久 | CNI 插件故障、存储卷挂载不上 |
| ImagePullBackOff | 镜像名写错、secret 未配置、仓库不可达 |
| CrashLoopBackOff | 应用启动崩溃、退出码非 0、startupProbe 失败 |
| CreateContainerConfigError | ConfigMap/Secret 名称不对、引用不存在的卷 |

这些状态本质上就是 Pod 在不同阶段挂掉的体现,你只要照着阶段往回推,很快能定位。


好了,整个链路捋下来了。下次 Pod 抽风,别再盯着屏幕干瞪眼,把这五个阶段当成排查路线图用。你遇到过什么诡异问题没?比如我见过一次调度器死活不把 Pod 分到某个节点,后来发现是节点上报告的内存有个微小的浮点误差,导致资源判定刚好不过...... 评论区来聊聊你的经历。

如果这文章帮你省了点咖啡钱和时间,丢给同事也看看,救人一命。

相关推荐
鹤落晴春5 小时前
RH124问答3:从命令行管理文件
linux·运维·服务器
guslegend6 小时前
大模型驱动大数据SRE智能运维
大数据·运维
遇见火星6 小时前
Docker Compose 完全入门:一键启动所有容器
运维·docker·容器·docker compose
小啊曼6 小时前
CIO实战方法论_11_组织变革打破部门墙
运维
❀搜不到6 小时前
远程服务器codex使用本地cc-switch的deepseek api
运维·服务器
虾壳云官方7 小时前
OpenClaw 2.7.9 Windows 一键部署教程:零基础也能搭建 AI 自动化助手
运维·人工智能·windows·自动化·openclaw·openclaw一键部署
江南风月7 小时前
WGCLOUD保姆级教程最新版整理
运维·zabbix·运维开发·prometheus·日志审计
志栋智能7 小时前
超自动化巡检:知识沉淀与团队协作的新载体
大数据·运维·网络·数据库·人工智能·自动化
vsropy9 小时前
Ubuntu网络图标消失问题/有网络问号
linux·运维·ubuntu
fofantasy9 小时前
NSK LH12AN 微型导轨技术手册
运维·网络·数据库·经验分享·规格说明书