深色模式
K8s Pod 异常排查
摘要:Pod 异常时
kubectl describe的 Events 段往往已给出原因,但很多人只跑logs。本文按状态分类给出定位路径,并解释退出码 0/1/2/137/143 的真实含义。
适用环境
bash
kubectl version --short 2>/dev/null || kubectl version
kubectl config current-context
kubectl get nodes1
2
3
2
3
排障步骤
第 1 步:看状态与分布
bash
kubectl get pod -n <ns> -o wide
kubectl get pod -n <ns> --field-selector=status.phase!=Running1
2
2
第 2 步:describe 是信息量最大的一步
bash
kubectl describe pod <pod> -n <ns>1
重点看三段:Events(调度与启动过程)、State(终止原因与退出码)、Conditions(调度是否就绪)。
第 3 步:Pending —— 没被调度上
bash
kubectl describe pod <pod> -n <ns> | sed -n '/Events/,$p'
kubectl describe node <node> | grep -A 10 'Allocated resources'1
2
2
常见原因:资源不足、节点污点未容忍、节点选择器不匹配、PVC 未绑定。
第 4 步:ImagePullBackOff —— 镜像拉不下来
bash
kubectl get pod <pod> -n <ns> -o jsonpath='{.spec.containers[*].image}'
kubectl get events -n <ns> --sort-by=.lastTimestamp | tail -201
2
2
检查镜像名与标签是否存在、私有仓库密钥(imagePullSecrets)是否配置、节点是否能访问仓库。
第 5 步:CrashLoopBackOff —— 启动后立刻退出
bash
kubectl logs <pod> -n <ns> --previous # 上一次崩溃的日志,最关键
kubectl logs <pod> -n <ns> -c <container> --tail=1001
2
2
退出码的含义
0 正常退出(可能是任务型容器跑完了)、1/2 应用异常、137 被 SIGKILL(通常是内存超限被 OOM 杀)、143 被 SIGTERM(优雅退出或驱逐)。
第 6 步:确认是否被探针杀掉
bash
kubectl get pod <pod> -n <ns> -o jsonpath='{.spec.containers[*].livenessProbe}'
kubectl describe pod <pod> -n <ns> | grep -iE 'liveness|readiness|startup'1
2
2
探针参数不当会造成反复重启
initialDelaySeconds 过短,慢启动应用会在就绪前被 liveness 杀掉,陷入 CrashLoopBackOff。慢启动应用应配置 startupProbe。
第 7 步:Evicted —— 被驱逐
bash
kubectl get pod -n <ns> --field-selector=status.phase=Failed
kubectl describe node <node> | grep -iE 'Pressure|Conditions' -A 51
2
2
验证
bash
kubectl get pod -n <ns> -o wide
kubectl get pod <pod> -n <ns> -o jsonpath='{.status.containerStatuses[*].lastState}'
kubectl logs <pod> -n <ns> --tail=201
2
3
2
3
常见坑
只看 logs 看不到调度失败
Pending 阶段的 Pod 没有任何容器日志,原因只在 Events 里。
重启次数会掩盖首次崩溃
--previous 只能看上一次,多轮重启后首次崩溃日志已丢失,应提前配置日志采集。
节点 Ready 不代表可调度
节点可能被 cordon 或存在污点,kubectl get node 仍显示 Ready。
直接删除 Pod 强制重建
若根因是资源不足或配置错误,重建只会再失败一次。先修根因,再触发重建。