故障排查
排查 Kubernetes 问题时,先确定故障层级,再检查事件、状态条件和日志。直接删除 Pod 可能暂时掩盖问题,但不会解释根因。
排查顺序
基础信息:
kubectl get nodes -o wide
kubectl get pods -A -o wide
kubectl get events -A --sort-by=.lastTimestamp
kubectl describe pod <pod> -n <namespace>
kubectl logs <pod> -n <namespace> --all-containers
kubectl logs <pod> -n <namespace> --previousEvents 具有保留期限,只适合作为近期线索,长期分析需要集中日志、指标和审计系统。
Pod Pending
常见原因:
- requests 超过节点可分配资源。
- nodeSelector、Affinity、TopologySpread 或污点无法满足。
- PVC 未绑定或存储拓扑不匹配。
- ResourceQuota、准入策略或调度器插件拒绝。
kubectl describe pod <pod> -n <namespace>
kubectl get nodes -L topology.kubernetes.io/zone
kubectl describe node <node>
kubectl get pvc,pv,storageclass -A重点阅读 Pod Events 中 scheduler 给出的 FailedScheduling 原因,不要只通过增加节点解决所有 Pending。
ImagePullBackOff
检查镜像名称、tag、平台架构、仓库连通性和凭据:
kubectl describe pod <pod> -n <namespace>
kubectl get serviceaccount <sa> -n <namespace> -o yaml
kubectl get secret <pull-secret> -n <namespace> -o yaml节点侧可使用 CRI 工具验证:
sudo crictl pull <image>
sudo crictl images避免在排错输出中泄露 registry credential。
CrashLoopBackOff
CrashLoopBackOff 表示容器反复退出并进入指数退避,不是具体根因。检查:
kubectl logs <pod> -n <namespace> --previous
kubectl get pod <pod> -n <namespace> \
-o jsonpath='{range .status.containerStatuses[*]}{.name}{" exit="}{.lastState.terminated.exitCode}{" reason="}{.lastState.terminated.reason}{"\n"}{end}'常见原因包括启动命令错误、配置缺失、依赖不可用、OOM、文件权限和探针配置错误。退出码 137 通常需要结合 OOMKilled、节点内存和 cgroup 指标确认,不能只看数字下结论。
Service 无法访问
从选择器到后端逐层验证:
kubectl get service <service> -n <namespace> -o yaml
kubectl get endpointslice -n <namespace> \
-l kubernetes.io/service-name=<service> -o wide
kubectl get pods -n <namespace> --show-labels
kubectl exec -n <namespace> <client-pod> -- \
curl -v http://<service>:<port>检查 Service selector、Pod readiness、port/targetPort、NetworkPolicy 和应用实际监听地址。应用只监听 127.0.0.1 时,其他 Pod 无法通过 Pod IP 访问。
DNS 故障
kubectl get pods,service -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns
kubectl exec <pod> -n <namespace> -- cat /etc/resolv.conf
kubectl exec <pod> -n <namespace> -- nslookup kubernetes.default.svc需要区分:
- Service 名称不存在。
- CoreDNS Pod 或 Service 异常。
- NetworkPolicy 阻止 UDP/TCP 53。
- 节点上游 DNS 配置形成转发环路。
- 使用了错误的 namespace 或 cluster domain。
PVC 无法挂载
kubectl describe pvc <pvc> -n <namespace>
kubectl describe pod <pod> -n <namespace>
kubectl get volumeattachment
kubectl get csinode,csidriver
kubectl get pods -A | grep -i csi检查 StorageClass、accessModes、volumeBindingMode、节点/可用区拓扑、CSI controller/node plugin 和云盘状态。ReadWriteOnce 通常表示单节点读写,不等于单 Pod;需要严格单 Pod 挂载时使用驱动支持的 ReadWriteOncePod。
Node NotReady
kubectl describe node <node>
kubectl get lease -n kube-node-lease <node> -o yaml
sudo systemctl status kubelet containerd
sudo journalctl -u kubelet --since '30 min ago'
sudo crictl info重点检查 kubelet 心跳、运行时、磁盘/内存/PID 压力、证书、时间同步、CNI 和节点到 API Server 的网络。
调试容器和节点
镜像缺少 shell 或调试工具时使用临时容器:
kubectl debug -it <pod> -n <namespace> \
--image=nicolaka/netshoot --target=<container>调试节点:
kubectl debug node/<node> -it --image=ubuntu临时容器和节点调试通常具有较高权限,应受 RBAC、准入和审计约束。生产环境应使用经过审核并固定 digest 的调试镜像。
常用诊断输出
kubectl get --raw='/readyz?verbose'
kubectl api-resources
kubectl auth can-i --list -n <namespace>
kubectl top nodes
kubectl top pods -A
kubectl cluster-info dump --output-directory=/tmp/cluster-infokubectl top 依赖 Metrics Server;它反映近期资源指标,不代替长期监控。