排查 K8s 问题时,有三大核心命令:
- kubectl describe pod/node
:查看资源事件 (Events),定位根本原因。 - kubectl logs
:查看应用日志,解决程序问题。 - kubectl get
:查看资源状态。
第一层:Pod 状态码 (Pod Status Codes)#
状态码 (Status) | 核心原因 | 核心排查步骤 |
---|---|---|
Pending | 无法调度:调度器找不到合适的节点。 | 1. kubectl describe pod <name> ,检查 Events ,定位具体原因:- Insufficient cpu/memory (资源不足)。- Taints/Tolerations (污点与容忍不匹配)。- Affinity rules (亲和性/反亲和性规则不匹配)。- PVC not bound (存储卷未就绪)。 |
ImagePullBackOff / ErrImagePull | 镜像拉取失败:Kubelet 无法从仓库拉取镜像。 | 1. kubectl describe pod <name> ,检查 Events ,定位具体原因:- 镜像名或 Tag 错误 (检查 YAML)。 - 私有仓库认证失败 (检查 imagePullSecrets )。- 网络不通 (登录节点手动 docker/crictl pull 测试)。 |
CrashLoopBackOff | 容器反复崩溃:容器启动后立即退出,Kubelet 不断重启。 | 1. kubectl logs <pod-name> --previous (查看 上一次 崩溃的日志,极其重要)。2. kubectl logs <pod-name> (查看当前日志)。3. 根据日志排查应用 Bug、配置错误或内存溢出。 |
RunContainerError | 容器运行时错误:配置正确,但底层容器运行时(如 containerd)无法启动容器。 | 1. kubectl describe pod <name> ,Events 会显示 RunContainerError 。2. SSH 登录到节点,使用 journalctl -u containerd (或 docker) 查看运行时日志,寻找更底层的错误信息。 |
CreateContainerConfigError | 容器配置错误:创建容器所需的配置(如 ConfigMap/Secret)有问题。 | 1. kubectl describe pod <name> ,Events 会明确指出哪个资源找不到或格式错误。 |
Running (但 Ready 为 0/1) | 就绪探针 (Readiness Probe) 失败:Pod 在运行,但未准备好接收流量。 | 1. kubectl describe pod <name> ,Events 会记录 Readiness probe failed 。2. 检查 ReadinessProbe 配置(初始延迟、超时)或应用依赖的下游服务是否故障。 |
Terminating (卡住) | Pod 无法正常终止:通常是因为有阻止其删除的 finalizer,或存储卷无法卸载。 | 1. kubectl describe pod <name> ,检查 Events 是否有 FailedDetachVolume 等存储相关错误。2. kubectl edit pod <name> ,查看 metadata.finalizers 字段,可能是某个控制器添加的 finalizer 未被清理。 |
Unknown | 状态未知:通常是节点控制器无法与该 Pod 所在节点的 Kubelet 通信。 | 1. 这几乎等同于节点 NotReady 。立即检查该 Pod 所在节点的健康状况(见第四层)。 |
Job 失败: BackoffLimitExceeded | 任务重试次数超限:Job 创建的 Pod 因执行失败,重试次数达到上限后,Job 被标记为失败。 | 1. kubectl get pods -l job-name=<job-name> 找到该 Job 创建的失败 Pods。2. kubectl logs <failed-pod-name> 查看日志,定位任务失败的根本原因。 |
第二层:容器退出码 (Container Exit Codes)#
退出码 (Exit Code) | 含义 | 核心排查步骤 |
---|---|---|
1 | 通用程序错误 | 1. 查看应用日志:kubectl logs <pod-name> --previous 。 |
126 / 127 | 命令不可执行 / 未找到 | 1. 检查 Dockerfile (chmod +x ) 和 YAML command 路径。 |
137 | OOMKilled (内存溢出) | 1. kubectl describe pod <name> 确认 Reason: OOMKilled 。2. 增加 resources.limits.memory 。 |
139 | 段错误 (SIGSEGV):代码 Bug。 | 1. 通知开发人员 进行代码调试。 |
143 | 优雅终止 (SIGTERM):正常行为。 | 1. 在删除或更新 Pod 时出现,无需处理。 |
第三层:网络状态码与错误 (Network Status Codes & Errors)#
错误码/状态 | 核心原因 | 核心排查步骤 |
---|---|---|
Endpoints 为空 | Service Selector 未匹配到 Pod。 | 1. kubectl describe svc <name> 检查 Selector 。2. kubectl get pods --show-labels 对比 Pod 的 Labels 。 |
HTTP 502/503/504 | Ingress 网关错误/服务不可用/超时。 | 1. 综合排查 Endpoints、Pod 健康状态 (CrashLoopBackOff , 0/1 Ready )。2. 504: 检查 Pod 日志和资源占用 ( kubectl top pod ),判断是否应用处理慢。 |
Connection refused | 连接被拒绝:网络路径通,但目标 Pod 的端口上没有进程在监听。 | 1. kubectl exec -it <pod-name> -- netstat -tulnp ,确认应用是否在正确的端口上监听。2. 检查应用的启动日志,看是否有端口绑定失败的错误。 |
Connection timed out | 连接超时:数据包在网络中丢失,通常是网络策略或防火墙问题。 | 1. 检查网络策略:kubectl get networkpolicy -A ,确认是否有策略阻止了此流量。2. 检查节点安全组或底层网络防火墙。 |
No route to host | 没有到主机的路由:通常是节点间的网络(CNI)出了问题。 | 1. 检查 CNI 插件的 Pods (calico-node , flannel-ds 等) 是否在所有节点都正常运行。 |
第四层:节点状态码 (Node Status Codes)#
状态码 (Status) | 核心原因 | 核心排查步骤 |
---|---|---|
NotReady | 节点失联:Kubelet 与 API Server 通信中断。 | 1. SSH 登录节点,依次检查 kubelet , containerd , df -h , free -m 。 |
SchedulingDisabled | 调度已禁用:节点被 cordon ( cordon 隔离) 了,不再接受新 Pod。 | 1. 这是管理员操作,非故障。使用 kubectl uncordon <node-name> 可恢复调度。 |
MemoryPressure | 内存压力:节点可用内存过低。 | 1. 节点可能会开始 驱逐 (Evict) Pods。登录节点用 top 找出内存大户。 |
DiskPressure | 磁盘压力:节点磁盘空间不足。 | 1. 登录节点,df -h 定位分区,清理镜像、容器和日志。 |
PIDPressure | PID 压力:节点上进程 ID 资源耗尽。 | 1. 登录节点,检查是否有进程 fork 炸弹或应用创建了过多线程/进程。 |
第五层:存储状态码 (Storage Status Codes)#
状态码 (Status) / 事件 | 核心原因 | 核心排查步骤 |
---|---|---|
PVC: Pending | PVC 无法绑定到 PV。 | 1. kubectl describe pvc <name> ,检查 Events ,看是 PV 不匹配还是 StorageClass 问题。 |
Pod Event: FailedMount | 卷挂载失败。 | 1. kubectl describe pod <name> ,Events 会提供详细原因,如 NFS 权限、云盘状态等。 |
Pod Event: FailedDetachVolume | 卷卸载失败:通常是底层存储(如云盘)正忙或出现问题。 | 1. 此问题会导致 Pod 卡在 Terminating 状态。2. 检查 CSI 插件日志或云厂商控制台,看该存储卷的状态。 |
应用日志: Read-only file system | 文件系统只读:Pod 写入 PV 时报错。 | 1. kubectl exec -it <pod-name> -- mount 查看挂载信息,确认挂载选项是否为 ro (只读)。2. 可能是存储后端本身出现问题,进入了只读保护模式。 |