一、常用命令
首先列出Pod排查过程中的常用命令:
查看Pod状态:kubectl get pod podname -o wide
查看Pod的yaml配置:kubectl get pods podname -o yaml
查看pod事件:kubectl describe pods podname
查看容器日志:kubectl logs podsname -c container-name
二、Pod状态
Error:Pod 启动过程中发生错误
NodeLost : Pod 所在节点失联
Unkown : Pod 所在节点失联或其它未知异常
Waiting : Pod 等待启动
Pending : Pod 等待被调度
ContainerCreating : Pod 容器正在被创建
Terminating : Pod 正在被销毁
CrashLoopBackOff :容器退出,kubelet 正在将它重启
InvalidImageName :无法解析镜像名称
ImageInspectError :无法校验镜像
ErrImageNeverPull :策略禁止拉取镜像
ImagePullBackOff :正在重试拉取
RegistryUnavailable :连接不到镜像中心
ErrImagePull :通用的拉取镜像出错
CreateContainerConfigError :不能创建 kubelet 使用的容器配置
CreateContainerError :创建容器失败
RunContainerError :启动容器失败
PreStartHookError : 执行 preStart hook 报错
PostStartHookError :执行 postStart hook 报错
ContainersNotInitialized :容器没有初始化完毕
ContainersNotReady :容器没有准备完毕
ContainerCreating :容器创建中
PodInitializing :pod 初始化中
DockerDaemonNotReady :docker还没有完全启动
NetworkPluginNotReady :网络插件还没有完全启动
三、pod遇到的问题
1、pod一直处于Pending状态
Pending 状态说明 Pod 还没有被调度到某个节点上,需要看下 Pod 事件进一步判断原因,比如:
下面是我遇到的一些原因:
节点资源不够
节点资源不够有以下几种情况:
1、CPU负载过高
2、剩余可被分配的内存不足
3、剩余可用GPU数量不足
如果判断某个 Node 资源是否足够?通过下面的命令查看node资源情况,关注以下信息:
Allocatable : 表示此节点能够申请的资源总和
Allocated resources : 表示此节点已分配的资源 (Allocatable 减去节点上
所有 Pod 总 的 Request)
前者与后者相减,可得出剩余可申请的资源。如果这个值小于 Pod 的 request,就不满足 Pod 的 资源要求,Scheduler 在 Predicates (预选) 阶段就会剔除掉这个 Node,也就不会调度上去。
不满足 nodeSelector 与 affinity
如果节点上存在污点 (Taints),而 Pod 没有响应的容忍 (),Pod 也将不会调度上 去。通过 可以看下 Node 有哪些 Taints:
污点既可以是手动添加也可以是被自动添加,下面可以看一下。
手动添加的污点:
通过类似以下方式可以给节点添加污点:
自动添加的污点
如果节点运行状态不正常,污点也可以被自动添加,从 v1.12 开始, TaintNodesByCondition 特性进入 Beta 默认开启,controller manager 会检查 Node 的 Condition,如果命中条件 就自动为 Node 加上相应的污点,这些 Condition 与 Taints 的对应关系如下:
解释下上面各种条件的意思:
OutOfDisk 为 True 表示节点磁盘空间不够了
Ready 为 False 表示节点不健康
Ready 为 Unknown 表示节点失联,在 node-monitor-grace-period 这
么长的时间内没有 上报状态 controller-manager 就会将 Node 状态置
为 Unknown (默认 40s)
MemoryPressure 为 True 表示节点内存压力大,实际可用内存很少
PIDPressure 为 True 表示节点上运行了太多进程,PID 数量不够用了
DiskPressure 为 True 表示节点上的磁盘可用空间太少了
NetworkUnavailable 为 True 表示节点上的网络没有正确配置,无法跟
其它 Pod 正常通 信
kube-scheduler 没有正常运行
检查 maser 上的 kube-scheduler 是否运行正常,异常的话可以尝试重启临时恢复。
3、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 的,可以根据实际需求做合理的调整。
系统OOM
如果是 cgrou OOM 杀掉的进程,从 Pod 事件的下 Reason 可以看到是 OOMKilled ,说明 容器实际占用的内存超过 limit 了,同时内核日志会报: ``。可以根据需求调整下 limit。
节点内存碎片化
如果节点上内存碎片化严重,缺少大页内存,会导致即使总的剩余内存较多,但还是会申请内存失败,
健康检查失败
2、Pod 一直处于 ContainerCreating 或 Waiting 状 态
Pod 配置错误
检查是否打包了正确的镜像
检查配置了正确的容器参数
挂载 Volume 失败
Volume 挂载失败也分许多种情况,先列下我这里目前已知的。
limit 设置太小或者单位不对
如果 limit 设置过小以至于不足以成功运行 Sandbox 也会造成这种状态,常见的是因为 memory limit 单位设置不对造成的 limit 过小,比如误将 memory 的 limit 单位像 request 一样设 置为小 m ,这个单位在 memory 不适用,会被 k8s 识别成 byte, 应该用 Mi 或M
拉取镜像失败
镜像拉取失败也分很多情况,这里列举下:
配置了错误的镜像
Kubelet 无法访问镜像仓库(比如默认 pause 镜像在 gcr.io 上,国内环境访问需要特殊处 理)
拉取私有镜像的 没有配置或配置有误
镜像太大,拉取超时
3. Pod 一直处于 Terminating 状态
磁盘爆满
如果 docker 的数据目录所在磁盘被写满,docker 无法正常运行,无法进行删除和创建操作,所以 kubelet 调用 docker 删除容器没反应,看 event 类似这样:
存在 Finalizers
k8s 资源的 metadata 里如果存在 ,那么该资源一般是由某程序创建的,并且在其 创建的资源的 metadata 里的 finalizers 加了一个它的标识,这意味着这个资源被删除时需要 由创建资源的程序来做删除前的清理,清理完了它需要将标识从该资源的 finalizers 中移除,然 后才会最终彻底删除资源。比如 Rancher 创建的一些资源就会写入 finalizers 标识。
处理建议:kubectl edit 手动编辑资源定义,删掉 ,这时再看下资源,就会发现 已经删掉了
4、Pod 一直处于 Unknown 状态
通常是节点失联,没有上报状态给 apiserver,到达阀值后 controller-manager 认为节点失联 并将其状态置为
可能原因:
节点高负载导致无法上报
节点宕机
节点被关机
网络不通
5、Pod 一直处于 Error 状态
通常处于 Error 状态说明 Pod 启动过程中发生了错误。常见的原因包括:
依赖的 ConfigMap、Secret 或者 PV 等不存在
请求的资源超过了管理员设置的限制,比如超过了 等
违反集群的安全策略,比如违反了 等
容器无权操作集群内的资源,比如开启 RBAC 后,需要为 配置角色绑定
6、Pod 一直处于 ImagePullBackOff 状态
http 类型 registry,地址未加入到 insecure- registry
dockerd 默认从 https 类型的 registry 拉取镜像,如果使用 https 类型的 registry,则 必须将它添加到 参数中,然后重启或 reload dockerd 生效。
https 自签发类型 resitry,没有给节点添加 ca 证书
如果 registry 是 https 类型,但证书是自签发的,dockerd 会校验 registry 的证书,校验 成功才能正常使用镜像仓库,要想校验成功就需要将 registry 的 ca 证书放置到 位置
私有镜像仓库认证失败
如果 registry 需要认证,但是 Pod 没有配置 ,配置的 Secret 不存在或者 有误都会认证失败。
镜像文件损坏
如果 push 的镜像文件损坏了,下载下来也用不了,需要重新 push 镜像文件。
镜像拉取超时
如果节点上新起的 Pod 太多就会有许多可能会造成容器镜像下载排队,如果前面有许多大镜像需要下 载很长时间,后面排队的 Pod 就会报拉取超时。
镜像不存在
镜像配置错误或者镜像不存在会导致拉取超时。
领取专属 10元无门槛券
私享最新 技术干货