通常情况下pod发生问题时首先收集一下错误
kubectl get pod <pod-name> -o yaml 查看 Pod 的配置是否正确
kubectl describe pod <pod-name> 查看 Pod 的事件
kubectl logs <pod-name> [-c <container-name>] 查看容器日志
Pod Pending 状态
如果一个 Pod 处于 Pending 状态,表示 Pod 没有被调度到节点上。通常这是因为某种类型的资源不足导致无法调度。 查看上面的 kubectl describe … 命令的输出,其中应该显示了为什么没被调度的原因。 常见原因如下:
- 资源不足: 你可能耗尽了集群上所有的 CPU 或内存。此时,你需要删除 Pod、调整资源请求或者为集群添加节点。
关于pod的资源计算可以参考官方文档:
https://kubernetes.io/zh/docs/concepts/configuration/manage-resources-containers/ - 使用了 hostPort: 如果绑定 Pod 到 hostPort,那么能够运行该 Pod 的节点就有限了。多数情况下,hostPort 是非必要的,而应该采用 Service 对象来暴露 Pod。 如果确实需要使用hostPort,那么集群中节点的个数就是所能创建的 Pod 的数量上限。通常情况下是HostPort 已被占用
Pod 在 Waiting 状态或者ContainerCreating 状态
如果 Pod 处于 Waiting 状态,则表示 Pod 已经被调度到某工作节点,但是无法在该节点上运行。 同样,kubectl describe … 命令的输出可能很有用。 Waiting 状态的最常见原因是拉取镜像失败。要检查的有以下几个方面:
- 确保镜像名字拼写正确核实是否是配置了错误的镜像
- kubelet无法访问镜像(国内环境访问部分带有gcr.io需要做额外特殊设置)
- 核实私有镜像的密钥、免密设置等
- 镜像太大,拉取超时(可以适当调整 kubelet 的 --image-pull-progress-deadline 和 --runtime-request-timeout 选项)
- 确保镜像已被推送到镜像仓库 用手动命令 docker pull <镜像> 试试看
- 镜像是否可拉取
pod 异常日志抛出CNI网络错误以及无法启动
CNI 网络错误无法配置pod网络或无法分配ip地址,一般需要检查 CNI 网络插件的配置。
容器无法启动,则需要检查使用的镜像和容器配置的参数是否无误,通常情况下是由于没有常驻进程和参数设置造成。
Pod 处于 Crashing 或别的不健康状态
一般情况是pod被调度后,容器资源管理约束造成,排查参考官方文档:https://kubernetes.io/zh/docs/concepts/configuration/manage-resources-containers/
Pod 处于 ImagePullBackOff 状态
这种情况通常是镜像名称配置错误或者私有镜像的密钥配置错误导致。可以使用docker pull <image>
来验证镜像是否可以正常拉取.
如是私有镜像仓库,需要首先创建一个docker-registry 类型的 Secret (使用的云服务的仓库如阿里镜像仓库如使用免密插件需要去掉这个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
在容器中引用secret
spec:
containers:
- name: private-reg-container
image: <your-private-image>
imagePullSecrets:
- name: my-secret
Pod 一直处于 CrashLoopBackOff 状态
CrashLoopBackOff 状态说明容器曾经启动了,但又异常退出了。可以先查看一下容器的日志
kubectl logs <pod-name>
kubectl logs --previous <pod-name>
一般退出原因有:
-
容器进程退出(无常驻进程或者服务进程意外退出导致)
-
健康或存活检查失败退出
-
也可以登录pod所在节点查看系统日志及kubelet、docker日志进一步排查
Pod 处于 Error 状态
通常处于 Error 状态说明 Pod 启动过程中发生了错误。常见的原因包括
依赖的 ConfigMap、Secret 或者 PV 等不存在
请求的资源超过了管理员设置的限制,比如超过了 LimitRange 等
违反集群的安全策略,比如违反了 PodSecurityPolicy 等
容器无权操作集群内的资源,比如开启 RBAC 后,需要为 ServiceAccount 配置角色绑定
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
–grace- - 3.period=0 --force 强制删除 Pod。除非明确知道 Pod 的确处于停止状态(比如 Node 所在 VM 或物理机已经关机),否则不建议使用该方法。特别是 StatefulSet 管理的 Pod,强制删除容易导致脑裂或者数据丢失等问题。
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。
对于pod异常官方已给出方案流程可参考:Troubleshoot Applications
思路图解: