Kubernetes Pod 排错指南

Pod排错


Pod 各种异常现象,可能的原因以及解决方法。

排查过程常用的命名如下 :
  • 查看 Pod 状态: kubectl get pod <pod-name> -o wide
  • 查看 Pod yaml 配置: kubectl get pod <pod-name> -o yaml
  • 查看 Pod 事件: kubectl describe pod <pod-name>
  • 查看容器日志: kubectl logs <pod-name> [-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 : 网络插件还没有完全启动

Failed


失败(Failed):Pod中的所有容器都已终止了,并且至少有一个容器是因为失败终止。即容器以非0状态退出或者被系统禁止。 (容器进程主动退出)

容器进程如果是自己主动退出 ( 不是被外界中断杀死 ) ,退出状态码一般在 0-128 之间,根据约定,正 常退出时状态码为 0 1-127 说明是程序发生异常,主动退出了,比如检测到启动的参数和条件不满足要求,或者运行过程中发生 panic 但没有捕获处理导致程序退出。除了可能是业务程序 BUG ,还有其它许多可能原因,这里我们一一列举下。
DNS 无法解析
可能程序依赖集群 DNS 服务,比如启动时连接数据库,数据库使用 service 名称或外部域名都需
DNS 解析,如果解析失败程序将报错并主动退出。解析失败的可能原因 :
  • 集群网络有问题,Pod 连不上集群 DNS 服务
  • 集群 DNS 服务挂了,无法响应解析请求
  • Service 或域名地址配置有误,本身是无法解析的地址

程序配置有误  

  • 配置文件格式错误,程序启动解析配置失败报错退出
  • 配置内容不符合规范,比如配置中某个字段是必选但没有填写,配置校验不通过,程序报错主动退出

 

 

Pod 一直处于 ImagePullBackOff 状态


http 类型 registry,地址未加入到 insecure-registry

dockerd 默认从 https 类型的 registry 拉取镜像,如果使用 https 类型的 registry ,则必须将它添加到 insecure-registry 参数中,然后重启或 reload dockerd 生效。

 

https 自签发类型 resitry,没有给节点添加 ca 证书

如果 registry https 类型,但证书是自签发的,dockerd 会校验 registry 的证书,校验成功才能正常使用镜像仓库,要想校验成功就需要将 registry ca 证书放置到 /etc/docker/certs.d/<registry:port>/ca.crt 位置。

 私有镜像仓库认证失败

如果 registry 需要认证,但是 Pod 没有配置 imagePullSecret ,配置的 Secret 不存在或者
有误都会认证失败。

 

镜像文件损坏

如果 push 的镜像文件损坏了,下载下来也用不了,需要重新 push 镜像文件。

 

镜像拉取超时
如果节点上新起的 Pod 太多就会有许多可能会造成容器镜像下载排队,如果前面有许多大镜像需要下载很长时间,后面排队的 Pod 就会报拉取超时。 kubelet 默认串行下载镜像 :
--serialize-image-pulls Pull images one at a time. We recommend *not* changing the default value on nodes that run docker daemon with version < 1.9 or an Aufs storage backend. Issue #10959 has more details. (default true)

 也可以开启并行下载并控制并发:

--registry-qps int32 If > 0, limit registry pull QPS to this value. If 0, unlimited. (default 5) 2. --registry-burst int32 Maximum size of a bursty pulls, temporarily allows pulls to burst to this number, while still not exceeding registry-qps. Only used if --registry-qps > 0 (default 10)

 镜像不不存在:

kubelet 日志 :
PullImage "imroc/test:v0.2" from image service failed: rpc error: code = Unknown desc = Error response from daemon: manifest for imroc/test:v0.2 not found

 

Pod 一直处于 ImageInspectError 状态


通常是镜像文件损坏了,可以尝试删除损坏的镜像重新拉取 

 

 

 

 

 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

可能原因 :
  • 节点高负载导致无法上报
  • 节点宕机
  • 节点被关机
  • 网络不通

Pod 一直处于 Error 状态


通常处于 Error 状态说明 Pod 启动过程中发生了错误。常见的原因包括:

  • 依赖的 ConfigMapSecret 或者 PV 等不存在
  • 请求的资源超过了管理员设置的限制,比如超过了 LimitRange
  • 违反集群的安全策略,比如违反了 PodSecurityPolicy
  • 容器无权操作集群内的资源,比如开启 RBAC 后,需要为 ServiceAccount 配置角色绑定
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值