Kubernetes Pod 故障归类与排查方法

Stella981
• 阅读 854

Pod 概念

  • Pod是kubernetes集群中最小的部署和管理的基本单元,协同寻址,协同调度。

  • Pod是一个或多个容器的集合,是一个或一组服务(进程)的抽象集合。

  • Pod中可以共享网络和存储(可以简单理解为一个逻辑上的虚拟机,但并不是虚拟机)。

  • Pod被创建后用一个UID来唯一标识,当Pod生命周期结束,被一个等价Pod替代,UID将重新生成。

Docker 是 Kubernetes Pod 中最常用的容器运行时,但 Pod 也能支持其他的容器运行,比如 rkt、podman等。

Kubernetes 集群中的 Pod 可被用于以下两个主要用途:

  • 运行单个容器的 Pod。“每个 Pod 一个容器”模型是最常见的 Kubernetes 用例;在这种情况下,可以将 Pod 看作单个容器的包装器,并且 Kubernetes 直接管理 Pod,而不是容器。

  • 运行多个协同工作的容器的 Pod。Pod 可能封装由多个紧密耦合且需要共享资源的共处容器组成的应用程序。这些位于同一位置的容器可能形成单个内聚的服务单元,一个容器将文件从共享卷提供给公众,而另一个单独的“挂斗”容器则刷新或更新这些文件。Pod 将这些容器和存储资源打包为一个可管理的实体。

Pod 控制器

控制器可以为您创建和管理多个 Pod,管理副本和上线,并在集群范围内提供自修复能力。例如,如果一个节点失败,控制器可以在不同的节点上调度一样的替身来自动替换 Pod。

包含一个或多个 Pod 的控制器一些示例包括:

  • Deployment kubernetes中最常用的控制器,用于运行无状态应用

  • StatefulSet 用于运行有状态应用

  • DaemonSet 作用就像是计算机中的守护进程,它能够运行集群存储、日志收集和监控等『守护进程』

控制器通常使用您提供的 Pod 模板来创建它所负责的 Pod。

Pod 故障归类

  • Pod状态 一直处于 Pending

  • Pod状态 一直处于 Waiting

  • Pod状态 一直处于 ContainerCreating

  • Pod状态 处于 ImagePullBackOff

  • Pod状态 处于 CrashLoopBackOff

  • Pod状态 处于 Error

  • Pod状态 一直处于 Terminating

  • Pod状态 处于 Unknown

上面是个人总结,如果不全请见谅!

Pod 排查故障命令

  • kubectl get pod <pod-name> -o yaml # 查看 Pod 配置是否正确

  • kubectl describe pod <pod-name> # 查看 Pod 详细事件信息

  • kubectl logs <pod-name> [-c <container-name>] # 查看容器日志

Pod 故障问题与排查方法

  • Pod 一直处于 Pending 状态

    Pending状态,这个状态意味着,Pod 的 YAML 文件已经提交给 Kubernetes,API 对象已经被创建并保存在 Etcd 当中。但是,这个 Pod 里有些容器因为某种原因而不能被顺利创建。比如,调度不成功(可以通过 kubectl describe pod 命令查看到当前 Pod 的事件,进而判断为什么没有调度)。可能原因:资源不足(集群内所有的 Node 都不满足该 Pod 请求的 CPU、内存、GPU 等资源);HostPort 已被占用(通常推荐使用 Service 对外开放服务端口)。

  • Pod 一直处于 Waiting 或 ContainerCreating 状态

    首先还是通过 kubectl describe pod 命令查看到当前 Pod 的事件。可能的原因包括:

    1、镜像拉取失败,比如,镜像地址配置错误、拉取不了国外镜像源(gcr.io)、私有镜像密钥配置错误、镜像太大导致拉取超时(可以适当调整 kubelet 的 --image-pull-progress-deadline 和 --runtime-request-timeout 选项)等。

    2、CNI 网络错误,一般需要检查 CNI 网络插件的配置,比如:无法配置 Pod 网络、无法分配 IP 地址。

    3、容器无法启动,需要检查是否打包了正确的镜像或者是否配置了正确的容器参数。

    4、Failed create pod sandbox,查看kubelet日志,原因可能是磁盘坏道(input/output error)。

  • Pod 一直处于 ImagePullBackOff 状态

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

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

    1、查询 docker-registry 类型的 Secret

    # 查看 docker-registry Secret 
    

    2、创建 docker-registry 类型的 Secret

    # 首先创建一个 docker-registry 类型的 Secret
    
  • Pod 一直处于 CrashLoopBackOff 状态

    CrashLoopBackOff 状态说明容器曾经启动了,但又异常退出。此时可以先查看一下容器的日志。

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

  • Pod 处于 Error 状态

    通常处于 Error 状态说明 Pod 启动过程中发生了错误。常见的原因包括:依赖的 ConfigMapSecret 或者 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-period=0 --force强制删除 Pod。除非明确知道 Pod 的确处于停止状态(比如 Node 所在 VM 或物理机已经关机),否则不建议使用该方法。特别是 StatefulSet 管理的 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。

    Unknown 这是一个异常状态,意味着 Pod 的状态不能持续地被 kubelet 汇报给 kube-apiserver,这很有可能是主从节点(Master 和 Kubelet)间的通信出现了问题。

参考链接

往期精彩文章

推荐精彩文章

您的关注是小站的动力

Kubernetes Pod 故障归类与排查方法 欢迎大家关注交流,定期分享自动化运维、DevOps、Kubernetes、Service Mesh和Cloud Native

扫码『加群』交流技术

Kubernetes Pod 故障归类与排查方法

本文分享自微信公众号 - YP小站(ypxiaozhan)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Prodan Labs Prodan Labs
3年前
Kubernetes Ingress — NGINX
在Kubernetes中,Service是一种抽象的概念,它定义了每一组Pod的逻辑集合和访问方式,并提供一个统一的入口,将请求进行负载分发到后端的各个Pod上。Service默认类型是ClusterIP,集群内部的应用服务可以相互访问,但集群外部的应用服务无法访问。为此Kubernetes提供了NodePorts,LoadBalan
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
K8s创建pod yaml文件详解
kubernetes创建pod的yaml文件,参数说明apiVersion:v1指定api版本,此值必须在kubectlapiversion中kind:Pod指定创建资源的角色/类型metadata:资源的元数据/属性name:web04pod资源的名字,在同一个namespace中必须唯一lab
Wesley13 Wesley13
2年前
K8S基础概念
一、核心概念1、NodeNode作为集群中的工作节点,运行真正的应用程序,在Node上Kubernetes管理的最小运行单元是Pod。Node上运行着Kubernetes的Kubelet、kubeproxy服务进程,这些服务进程负责Pod的创建、启动、监控、重启、销毁、以及实现软件模式的负载均衡。Node包含
Stella981 Stella981
2年前
Service Account和RBAC授权
一、介绍ServiceAccount概念的引入是基于这样的使用场景:运行在pod里的进程需要调用KubernetesAPI以及非KubernetesAPI的其它服务。ServiceAccount它并不是给kubernetes集群的用户使用的,而是给pod里面的进程使用的,它为pod提供必要的身份认证。二、创建ServiceAcco
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
2年前
(三)Kubernetes 快速入门
 Kubernetes的核心对象APIServer提供了RESTful风格的编程接口,其管理的资源是KubernetesAPI中的端点,用于存储某种API对象的集合,例如,内置Pod资源是包含了所有Pod对象的集合。资源对象是用于表现集群状态的实体,常用于描述应于哪个节点进行容器化应用、需
Wesley13 Wesley13
2年前
kubernetes资源对象
podPod是K8S的最小操作单元,一个Pod可以由一个或多个容器组成;整个K8S系统都是围绕着Pod展开的,比如如何部署运行Pod、如何保证Pod的数量、如何访问Pod等。特点Pod是能够被创建、调度和管理的最小单元;每个Pod都有一个独立的IP;一个Pod由一个或多个容器构成,并共享命名空间和共享存储等;Pod所有容
Wesley13 Wesley13
2年前
K8S 容器之间通讯方式
概述首先k8s里面容器是存在于pod里面的,所以容器之间通讯,一般分为三种类型:1\.pod内部容器之间2\.pod与pod容器之间3\.pod访问service服务pod内部容器之间这种情况下容器通讯比较简单,因为k8spod内部容器是共享网络空间的,所以容器直接可以使用localhost访