k8s pod故障分类与排查

一、Pod故障状态基本有几种
Pod状态 处于Pending
Pod状态 处于Waiting
Pod状态 处于ContainerCreating
Pod状态 ImagePullBackOff
Pod状态 CrashLoopBackOff
Pod状态 Error
Pod状态 Terminating
Pod状态 Unknown
Pod状态 OOM killed
pod状态 running

二、Pod故障我们可以用下面一些手段查看

1、命令
kubectl get pod <pod-name> -o yaml  # 查看Pod yaml配置是否正确
kubectl describe pod <pod-name>      # 查看Pod详细事件信息
kubectl logs <pod-name> [-c <container-name>]  # 查看容器日志
cat /var/log/messages
journalctl -u kube-scheduler
journalctl -xefu kubelet
journalctl -u kube-apiserver
journalctl -u kubelet |tail
journalctl -xe

2、样例

例1:kubectl describe pod kubernetes-dashboard-849cd79b75-s2snt --namespace kube-system
例2:kubectl logs -f pods/monitoring-influxdb-fc8f8d5cd-dbs7d -n kube-system
例3:kubectl logs --tail 200 -f kube-apiserver -n kube-system |more
例4;kubectl logs --tail 200 -f cc -n default

3、用登录到宿主机docker查看日志,因为有些问题比较复杂
docker logs 439b1f6989e3 (容器id)


四、总结我们环境下遇到的Pod故障问题与排查方法

1)、Pod 一直处于 Pending 状态
Pending 状态 意味着Pod已经开始创建,API对象已经被创建并保存在Etcd当中。
但是,这个Pod里有些容器因为某种原因而不能被顺利创建。
1、node节点资源不满足包括CPU、内存、GPU。例如:
resources:
limits:
cpu: "2"
memory: 4Gi
requests:
cpu: "2"
memory: 4Gi
2、node 标签设置错误,不能满足调度要求。即pod yaml里面的nodeSelector设置成了其他的比如: a:b
    但是node节点,没有设置该标签。
3、被调度的node节点处于not ready ,从而不被调度(rancher查看是非常方便的,包括当前cpu,内存等占用,建议安装rancher管理)
4、可以通过kubectl describe pod podname 查看具体原因


2)、Pod 一直处于Waiting或ContainerCreating状态

首先还是通过kubectl describe pod 命令查看当前Pod的事件。可能的原因有:
1、镜像拉取失败,比如远程镜像库项目地址配置错误导致拉取不到该镜像、
或node节点上没有安装包、镜像密钥配置错误、镜像太大导致拉取超时等
2、CNI网络插件错误,一般需要检查CNI网络插件的配置,比如:无法配置Pod网络、无法分配IP地址(tunl0,我们这里用的是ipip模式)。

3、容器无法启动,需要检查是否打包了正确的镜像或者是否配置了正确的容器参数
4、Failed create pod sandbox,查看kubelet日志,原因可能是磁盘坏道(input/output error)。

3)、Pod 一直处于ImagePullBackOff状态

通常是镜像名称配置错误或者私有镜像的密钥配置错误导致。这种情况可以使用docker pull来验证镜像是否可以正常拉取。

如果私有镜像密钥配置错误或没有配置,按下面检查:

1、查询docker-registry类型的Secret
# 这个实际就是docker镜像仓库的密钥,我们开发打包项目,上传到我们的docker仓库
pod yaml 中会配置,只有创建该镜像的账户,根据该账户我们才可以生成对应的sercet

$ kubectl get secrets my-secret -o yaml | grep 'dockerconfigjson:' | awk '{print $NF}' | base64 -d
2、创建docker-registry类型的Secret
# 首先创建一个 docker-registry 类型的 Secret,样例
$ kubectl create secret docker-registry my-secret --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL

DOCKER_REGISTRY_SERVER 是docker仓库地址,我们用的habor搭建的
--docker-username是账户名
 --docker-password 是账户密码
--docker-email 是在habor账户开通时设置的邮箱也一定要正确
# 然后在 Deployment 或sts 中引用这个 Secret
spec:
containers:
- name: private-reg-container
image: <your-private-image>
imagePullSecrets:
- name: my-secret
4)Pod 一直处于CrashLoopBackOff状态

此状态说明容器曾经启动了,但又异常退出。这个时候我们用 pod exec 命令是进入不了pod,因为已经销毁。

通过命令 kubectl logs 和 kubectl logs --previous 可以发下一些容器退出的原因,比如:容器进程退出、健康检查失败退出; 还而已到容器内执行命令(kubectl exec cassandra - cat /var.log/cassandra/system.log)来进一步查看退出原因;如果还是没有线索,那就需要SSH登录该Pod所在的Node上,查看Kubelet或者Docker的日志进一步排查。

5)Pod 处于 Error 状态

通常处于Error状态说明Pod启动过程中发生了错误。常见的原因:依赖的ConfigMap、Secret或PV等不存在;请求的资源超过了管理员设置的限制,比如超过了LimitRange等;违反集群的安全策略,比如违反了PodSecurityPolicy等;容器无法操作集群内的资源,比如开启RDAC后,需要为ServiceAccount配置角色绑定。

6)Pod 处于Terminating或Unknown状态

  从v1.5开始,Kubernetes不会因为Node失联而删除其上正在运行的Pod,而是将其标记为Terminating 或 Unknown 状态。想要删除这些状态的Pod有四种方法:

  1、从集群中删除Node。使用公有云时,kube-controller-manager会在VM删除后自动删除对应的Node。而在物理机部署的集群中,需要管理员手动删除Node(kubectl delete node)。

  2、Node恢复正常。kubelet会重新跟kube-apiserver通信确认这些Pod的期待状态,进而再决定删除或者继续运行这些Pod。用户强制删除,用户可以执行(kubectl delete pods pod-name --grace-period=0 --force)强制删除Pod。 
     特别是sts 管理的Pod,强制删除容易导致数据丢失等问题。

   3、Pod行为异常,这里所说的行为异常是指Pod没有按预期的行为执行,比如没有运行podSpec 里面设置的命令行参数。这一般是podSpec yaml文件内容有误,可以尝试使用 --validate 参数重建容器,比如(kubectl delete pod mypod 和 kubectl create --validate -f mypod.yaml);也可以查看创建后的podSpec是否是对的,比如(kubectl get pod mypod -o yaml);修改静态Pod的Manifest后未自动重建,kubelet 使用inotify 机制检测 /etc/kubernetes/manifests 目录(可通过 kubelet 的 -pod-manifest-path 选项指定)中静态Pod的变化,并在文件发生变化后重新创建相应的 Pod。但有时也会发现修改静态Pod的 Manifest后未自动创建新 Pod的情景,此时已过简单的修复方法是重启 Kubelet。
   4、可以使用scale动态扩容,缩容的方式进行销毁。

   Unknown 这个异常状态意味着Pod的状态不能持续地被 kubelet汇报给 kube-apiserver,这很有可能是主从节点间的通信出现了问题
7)内存不足  OOM killed
  yaml 里面的内存申请不正确,会出现这种状态。
8) pod处于running状态
   虽然处于running 但是却使用不了,这种情况我们遇到是,pod访问不了外网或者其他pod,主要是由于node节点机器的calico ipip模式出问题了。有的node就没有启动tunl0,
   有的机器,启动了以后没有分配ip等诸多问题。

上一篇:kubectl scale sts


下一篇:探针配置失误,线上容器应用异常死锁后,kubernetes集群未及时响应自愈重启容器?