讲解
Kubernetes 排障的核心是「顺着状态链路找异常环节」。一个 Pod 从创建到 Running 要经过:准入控制 → 调度(Pending 卡这里)→ 拉镜像(ImagePullBackOff 卡这里)→ 启动容器(CrashLoopBackOff 卡这里)→ 探针就绪(Ready 0/1 卡这里)。每个环节有各自典型的报错状态和对应的查看工具,记住这条链路,90% 的问题都能在几分钟内定位到环节。
三板斧的出手顺序。第一板 kubectl get pods:看 STATUS 列定位环节——Pending 查调度(describe 看事件,多为资源不足或污点),ImagePullBackOff/ErrImagePull 查镜像(名字错、tag 不存在、私有仓库没配 imagePullSecrets),CrashLoopBackOff 查应用本身(启动即崩,看日志),Running 但 READY 0/1 查探针(readiness 不过)。第二板 kubectl describe pod:Events 部分按时间记录了每个环节发生了什么,信息密度最高。第三板 kubectl logs:应用视角的输出现场,容器重启过要加 --previous 看「上一次是怎么死的」。
再往上层走还有两根支柱:kubectl get events(命名空间级事件流,--sort-by 按时间排,看全局异常);kubectl exec / port-forward(进容器或把端口拉回本机,做交互式验证)。两个容易忽视的点:一是 Service 层故障(Pod 都健康但访问不通)要查 endpoints——selector 标签不匹配时端点是空的;二是 DNS 故障用 nslookup 在集群内验证。排障的通用心法:先分清「哪一层坏了」(调度/镜像/进程/探针/网络/存储),再在该层用对应工具看现场,不要上来就重启。
示例
故障一:镜像 tag 不存在。这个 Pod 会被真实创建,然后卡在拉镜像环节——我们用三板斧定位它:
apiVersion: v1
kind: Pod
metadata:
name: ohmydocs-verify-broken
labels:
app: ohmydocs-verify-broken
spec:
containers:
- name: nginx
image: nginx:9.9.9-not-exist
for i in 1 2 3 4 5 6 7 8; do
reason=$(kubectl get pod ohmydocs-verify-broken -o jsonpath='{.status.containerStatuses[0].state.waiting.reason}' 2>/dev/null || true)
[ -n "$reason" ] && break
sleep 5
done
echo "等待中的原因: $reason"
kubectl describe pod ohmydocs-verify-broken | grep -i -A2 'Failed' | head -4
kubectl delete pod ohmydocs-verify-broken --wait
故障二:应用启动即崩。CrashLoopBackOff 现场 + 用 logs --previous 看上一次崩溃的输出:
apiVersion: v1
kind: Pod
metadata:
name: ohmydocs-verify-crasher
labels:
app: ohmydocs-verify-crasher
spec:
restartPolicy: Always
containers:
- name: busybox
image: busybox:1.36
command: ["sh", "-c", "echo '启动失败:配置文件不存在'; exit 1"]
for i in $(seq 1 12); do
restarts=$(kubectl get pod ohmydocs-verify-crasher -o jsonpath='{.status.containerStatuses[0].restartCount}' 2>/dev/null || echo 0)
[ "$restarts" -ge 2 ] && break
sleep 5
done
kubectl get pod ohmydocs-verify-crasher --no-headers
echo "重启次数: $restarts"
kubectl logs ohmydocs-verify-crasher --previous --tail=2 || kubectl logs ohmydocs-verify-crasher --tail=2
排障工具箱常规动作:看命名空间事件流(按时间排序,找 Warning):
kubectl get events --sort-by=.lastTimestamp | tail -6
常见坑
- 上来就删 Pod 重建:现场没了,问题下次还会来;先 describe + logs 取证,再考虑重启。
- 忘了 --previous:CrashLoopBackOff 的当前容器可能还没输出就死了,logs 看不到东西——上一次的生命轨迹在 --previous 里。
- 把 ImagePullBackOff 当网络故障:先核对镜像名和 tag 拼写,再查私有仓库的 imagePullSecrets,最后才是网络。
- 忽视 events 的时效:事件默认只保留约一小时,昨天的问题今天 describe 看不到事件——长期留痕要靠日志与监控系统。
小结
排障 = 顺状态链路(Pending→拉镜像→启动→探针)定位环节,get 看状态、describe 看事件、logs(--previous)看应用现场,events 看全局。先定位层、再取证据、最后动手。最后一章认识生态里的包管理器:Helm。