Pod 各种异常现象,可能的原因以及解决方法。
排查过程常用的命名如下 :- 查看 Pod 状态: kubectl get pod
-o wide - 查看 Pod 的 yaml 配置: kubectl get pod
-o yaml - 查看 Pod 事件: kubectl describe pod
- 查看容器日志: kubectl logs
[-c ]
失败(Failed):Pod中的所有容器都已终止了,并且至少有一个容器是因为失败终止。即容器以非0状态退出或者被系统禁止。 (容器进程主动退出)
容器进程如果是自己主动退出 ( 不是被外界中断杀死 ) ,退出状态码一般在 0-128 之间,根据约定,正 常退出时状态码为 0 , 1-127 说明是程序发生异常,主动退出了,比如检测到启动的参数和条件不满足要求,或者运行过程中发生 panic 但没有捕获处理导致程序退出。除了可能是业务程序 BUG ,还有其它许多可能原因,这里我们一一列举下。 DNS 无法解析 可能程序依赖集群 DNS 服务,比如启动时连接数据库,数据库使用 service 名称或外部域名都需 要 DNS 解析,如果解析失败程序将报错并主动退出。解析失败的可能原因 :- 集群网络有问题,Pod 连不上集群 DNS 服务
- 集群 DNS 服务挂了,无法响应解析请求
- Service 或域名地址配置有误,本身是无法解析的地址
程序配置有误
- 配置文件格式错误,程序启动解析配置失败报错退出
- 配置内容不符合规范,比如配置中某个字段是必选但没有填写,配置校验不通过,程序报错主动退出
Pod 处于 CrashLoopBackOff 状态
Pod 如果处于 CrashLoopBackOff 状态说明之前是启动了,只是又异常退出了,只要 Pod 的 restartPolicy 不是 Never 就可能被重启拉起,此时 Pod 的 RestartCounts 通常是大于0 的,可以先看下容器进程的退出状态码来缩小问题范围。 容器进程主动退出
如果是容器进程主动退出,退出状态码一般在 0-128 之间,除了可能是业务程序 BUG,还有其它许多可能原因。
系统 OOM
如果发生系统 OOM,可以看到 Pod 中容器退出状态码是 137,表示被 SIGKILL 信号杀死,同时 内核会报错: Out of memory: Kill process ... 。大概率是节点上部署了其它非 K8S 管理的进程消耗了比较多的内存,或者 kubelet 的 --kube-reserved 和 --system-reserved 配的比较小,没有预留足够的空间给其它非容器进程,节点上所有 Pod 的实际内存占用总量不会超过 /sys/fs/cgroup/memory/kubepods 这里 cgroup 的限制,这个限制等于 capacity - "kube-
reserved" - "system-reserved" ,如果预留空间设置合理,节点上其它非容器进程( kubelet, dockerd, kube-proxy, sshd 等 ) 内存占用没有超过 kubelet 配置的预留空间是不会发生系统 OOM 的,可以根据实际需求做合理的调整。cgroup OOM
如果是 cgrou OOM 杀掉的进程,从 Pod 事件的下 Reason 可以看到是 OOMKilled ,说明
容器实际占用的内存超过 limit 了,同时内核日志会报 : `` 。 可以根据需求调整下 limit 。
节点内存碎片化
如果节点上内存碎片化严重,缺少大页内存,会导致即使总的剩余内存较多,但还是会申请内存失败, 参考 处理实践: 内存碎片化
健康检查失败
参考 Pod 健康检查失败 进一步定位。
Pod 一直处于 Unknown 状态
通常是节点失联,没有上报状态给 apiserver,到达阀值后 controller-manager 认为节点失联并将其状态置为 Unknown 。
可能原因 :- 节点高负载导致无法上报
- 节点宕机
- 节点被关机
- 网络不通
通常处于 Error 状态说明 Pod 启动过程中发生了错误。常见的原因包括:
- 依赖的 ConfigMap、Secret 或者 PV 等不存在
- 请求的资源超过了管理员设置的限制,比如超过了 LimitRange 等
- 违反集群的安全策略,比如违反了 PodSecurityPolicy 等
- 容器无权操作集群内的资源,比如开启 RBAC 后,需要为 ServiceAccount 配置角色绑定



