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 分到某个节点,后来发现是节点上报告的内存有个微小的浮点误差,导致资源判定刚好不过...... 评论区来聊聊你的经历。

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

相关推荐
广州灵眸科技有限公司3 小时前
瑞芯微(EASY EAI)RV1126B ubuntu系统SDK源码获取
linux·运维·ubuntu
jiayong233 小时前
微服务无感迁移上云方案深度解析
微服务·云原生·架构
Web打印3 小时前
web打印控件,打印模板分散部署在各客户端本地,修改后需逐台更新,能否统一部署至服务器实现集中维护
运维·服务器
JiaWen技术圈3 小时前
使用 Terraform Grafana Provider 实现 Grafana 全栈 IaC 一体化管理的完整方案
云原生·grafana·terraform
爱吃龙利鱼3 小时前
ubuntu2026.04部署k8s1.36版本的傻瓜式教程(注:运行时为docker,网络插件为calico)
运维·网络·笔记·docker·云原生·kubernetes
浮生若城4 小时前
Linux基础I/O(2):理解“一切皆文件”与缓冲区
linux·运维·服务器
苏宸啊4 小时前
库的使用和制作
运维·服务器
.柒宇.4 小时前
Zabbix7.0部署完整指南
linux·运维·zabbix·监控
wanhengidc4 小时前
云手机手游搬砖 梦境护卫队
运维·服务器·安全·web安全·智能手机