Kubernetes故障排查为什么需要结构化方法论
K8s集群的故障表现往往与根因不在同一层级——Pod报CrashLoopBackOff可能是应用代码问题,也可能是资源配置错误或Secret挂载失败。无头排查容易在错误方向浪费时间。结构化排查的顺序是:集群级→节点级→Pod级→容器级→应用级,逐层缩小范围。
Pod CrashLoopBackOff的五种常见根因与诊断命令
CrashLoopBackOff是最常见也最令人困惑的Pod状态,本质是容器反复启动后退出。逐条排查:
1. 应用启动失败(退出码非0)
# 查看容器退出码和上次日志
kubectl get pod <pod-name> -o jsonpath='{.status.containerStatuses[0].lastState.terminated.exitCode}'
kubectl logs <pod-name> --previous
# 退出码1:应用错误,看日志定位具体异常
# 退出码137:OOMKilled,内存不足被杀
# 退出码139:Segfault,通常是C库或JNI问题
2. 存活探针配置过于激进
# 检查探针配置
kubectl get pod <pod-name> -o yaml | grep -A10 livenessProbe
# 常见问题:initialDelaySeconds太短,应用还没初始化完就被探测
# 修复:把initialDelaySeconds设为应用实际启动耗时的1.5倍
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30 # 根据实际启动时间调整
periodSeconds: 10
failureThreshold: 3
3. ConfigMap或Secret挂载失败
# 查看Events中的挂载错误
kubectl describe pod <pod-name> | grep -A5 Warning
# 典型错误:"secret <name> not found"——Secret在另一个namespace
# 修复:确保Secret与Pod在同一个namespace,或使用cross-namespace引用
4. 资源Limit设置不合理
# 查看实际资源使用vs限制
kubectl top pod <pod-name> --containers
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[0].resources}'
# CPU Throttle误判:limits.cpu设太低,应用看起来慢但不报错
# 区分OOM和CPU throttle:OOM会重建容器,throttle只是变慢
5. Init容器执行失败
# 查看Init容器状态
kubectl get pod <pod-name> -o jsonpath='{.status.initContainerStatuses}'
kubectl logs <pod-name> -c <init-container-name>
Service与网络策略的连通性诊断
服务不可达是第二大类故障。排查链路:Service→Endpoint→NetworkPolicy→DNS。
# 1. 检查Service是否有后端Endpoint
kubectl get endpoints <svc-name>
# 如果ENDPOINTS是<none>,说明selector匹配不到Pod
# 2. 在集群内测试连通性
kubectl run tmp-shell --rm -i --tty --image busybox -- sh
# 在临时Pod内:
wget -qO- <svc-name>.<namespace>.svc.cluster.local:8080
nslookup <svc-name>.<namespace>.svc.cluster.local
# 3. 检查NetworkPolicy是否阻断流量
kubectl get networkpolicy -n <namespace>
kubectl describe networkpolicy <policy-name> -n <namespace>
NetworkPolicy的坑在于默认行为——如果namespace中存在任何允许入站的Policy,未匹配的流量会被拒绝而不是允许。排查时用kubectl describe逐条检查规则是否遗漏了必要的端口或来源。
节点NotReady的排查路径
节点NotReady通常由kubelet问题引起,排查顺序:
# 1. SSH到故障节点,检查kubelet状态
systemctl status kubelet
journalctl -u kubelet --since "1 hour ago" | tail -50
# 2. 检查节点资源压力(磁盘/内存/PID)
df -h /var/lib/kubelet # 磁盘使用率超过85%会触发驱逐
free -h
ps -e --no-headers | wc -l # PID数量
# 3. 检查节点条件
kubectl describe node <node-name> | grep -A5 Conditions
# 4. 常见修复
# 磁盘满:清理旧容器镜像
crictl rmi --prune
# PID耗尽:调整kubelet的pidLimit
# kubelet证书过期:重新签发证书
集群级故障的应急响应流程
etcd不可用是集群级故障中最严重的场景——所有写操作都会失败。应急步骤:
# 检查etcd集群健康
ETCDCTL_API=3 etcdctl endpoint health \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
# 如果多数节点不可用,集群已丧失写入能力
# 不要尝试重启所有etcd节点——会造成数据丢失
# 正确做法:保留一个数据最完整的节点,移除故障节点后逐一恢复
ETCDCTL_API=3 etcdctl member remove <failed-member-id>
故障排查的关键不是记住所有命令,而是掌握分层诊断的方法论。从集群到应用逐层缩小范围,每一层用对应的诊断工具确认状态,避免盲目猜测。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kubernetes-rong-qi-bian-pai-gu-zhang-pai-cha-shou-ce-cong/