Pod 是怎么被调度和运行的
理解 Kubernetes 排错,先要理解 Pod 的生命周期:Pending → ContainerCreating → Running → Succeeded/Failed。任何一个阶段卡住都会在 kubectl get pods 里看到对应的异常状态。本文按”卡在哪、怎么查、怎么修”来讲。
一、调度相关:Pod 一直 Pending
Pending 通常是调度器找不到合适的节点。常见原因:
- 资源请求超过节点剩余(CPU/Memory request 太大)
- 节点有 taint,Pod 没有对应 toleration
- nodeSelector / affinity 条件过严,没有节点满足
kubectl describe pod my-pod
# 看 Events 段,通常直接写着 "0/3 nodes are available: ..."
用 nodeSelector / affinity 控制调度
spec:
nodeSelector:
disktype: ssd
tolerations:
- key: "gpu"
operator: "Equal"
value: "true"
effect: "NoSchedule"
二、镜像相关:ImagePullBackOff
镜像拉不下来,九成是这几种:
- 镜像名/Tag 写错
- 私有仓库没配
imagePullSecrets - 节点网络访问不了镜像仓库(尤其国内拉 docker.io)
kubectl describe pod my-pod | grep -A5 Events
# 若看到 "pull access denied" 或 "manifest unknown" 即上述原因
三、启动相关:CrashLoopBackOff
容器起来又崩,循环重启。排查顺序:
# 1. 看容器日志(加 --previous 看上一次崩溃的日志)
kubectl logs my-pod --previous
# 2. 看具体事件
kubectl describe pod my-pod
# 3. 如果是配置/依赖问题,可临时进容器调试
kubectl exec -it my-pod -- sh
常见根因:应用启动依赖的数据库没就绪、配置文件路径错误、内存超限被 OOMKilled(看 Events 里有没有 OOMKilled)。
四、就绪与存活探针
很多”服务起来了但访问 503″的问题,是就绪探针没配对:
livenessProbe:
httpGet: { path: /health, port: 8080 }
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet: { path: /ready, port: 8080 }
periodSeconds: 5
liveness 失败会重启容器,readiness 失败会把 Pod 从 Service 后端摘掉但不重启。两者别用同一个路径,否则会误杀。
五、资源限制别忘了
resources:
requests: { cpu: "100m", memory: "256Mi" }
limits: { cpu: "500m", memory: "512Mi" }
不设 limits 容易被邻居”吵醒”或自己把节点内存吃满。设了 memory limit 又超限就会 OOMKilled,要结合日志判断是调大还是修内存泄漏。
小结
K8s 排错的核心心法是:先用 describe 看 Events,再用 logs --previous 看崩溃原因,最后用 exec 进容器确认。绝大多数 Pod 异常都逃不出 Pending / ImagePull / CrashLoop 这三类,照着上面的清单逐一排除即可。




