POD故障处理
本文介绍关于 k3s/k8s Pod异常问题的诊断流程、排查方法、常见问题及解决方案。
本文目录
类别 | 内容 |
---|---|
诊断流程 | 诊断流程 |
常见排查方法 | 检查Pod的状态 检查pod的详情及事件 检查pod的容器日志 检查pod的配置 检查Pod的监控 使用终端进入容器常规诊断 |
常见问题及解决方案 | 常见的Pod异常状态及处理方式 Pod OOM异常问题处理 |
诊断流程
查看Pod是否处于异常状态,具体操作,请参见检查Pod的状态。
a. 如果Pod状态异常,可通过查看Pod的事件、Pod的日志、Pod的配置等信息确定异常原因。具体操作,请参见常见排查方法。关于Pod异常状态及处理方式,请参见常见的Pod异常状态及处理方式。
b. 如果Pod状态为Running但未正常工作,请参见Pod状态为Running但没正常工作。
若确认是Pod OOM异常问题,请参见Pod OOM异常问题处理。
如果问题仍未解决,请提交工单。
常见的Pod异常状态及处理方式
Pod状态 | Pod含义 | 解决方案 |
---|---|---|
Pending | Pod未被调度到节点上。 | Pod状态为Pending |
Init:N/M | Pod包含M个Init容器,其中N个已经启动完成。 | Pod状态为Init:N/M(Init:Error和Init:CrashLoopBackOff) |
Init:Error | Init容器已启动失败。 | Pod状态为Init:N/M(Init:Error和Init:CrashLoopBackOff) |
Init:CrashLoopBackOff | Init容器启动失败,反复重启。 | Pod状态为Init:N/M(Init:Error和Init:CrashLoopBackOff) |
Completed | Pod的启动命令已执行完毕。 | Pod状态为Completed |
CrashLoopBackOff | Pod启动失败,反复重启。 | Pod状态为CrashLoopBackOff |
ImagePullBackOff | Pod镜像拉取失败。 | Pod状态为ImagePullBackOff |
Running | Pod运行正常。Pod Running但是未正常工作。 | 无需处理Pod状态为Running但没正常工作 |
Terminating | Pod正在关闭中。 | Pod状态为Terminating |
Evicted | Pod被驱逐。 | Pod状态为Evicted |
OOMKilled | Pod OOM。 | Pod状态为OOMKilled |
常见排查方法
检查Pod的状态
- 登录运维操作服务器。
- 进入ONES运维工具箱容器。
ones-ai-k8s.sh # 进入ones运维操作容器
# cd /data/ones/ones-ai-k8s # K8S实例 - 输入Pod所在的命名空间,查看Pod状态。
kubectl get ns # 查看全部命名空间
kubectl -n $namespace get po
kubectl -n $namespace get po |grep -vi running # 查看非Running状态Pod
kubectl get po -A |grep -vi running # 查看所有命名空间非Running状态Pod- 若状态为Running 或Completed 说明Pod运行正常。
- 若状态不为Running 或Completed说明Pod状态异常,请参见常见的Pod异常状态及处理方式进行处理。
检查Pod的详情及事件
登录运维操作服务器。
进入ONES运维工具箱容器。
ones-ai-k8s.sh # 进入ones运维操作容器
# cd /data/ones/ones-ai-k8s # K8S实例输入Pod所在的命名空间,输入PodName查看Pod资源 describe详情信息。
kubectl -n $namespace describe po $ PodName
查看Pod渲染编排情况、镜像、Pod IP、Event、Limit资源限制、所在节点等详细信息,当Pod出现异常重点关注Event事件信息。
检查Pod的容器日志
- 登录运维操作服务器。
- 进入ONES运维工具箱容器。
ones-ai-k8s.sh # 进入ones运维操作容器
# cd /data/ones/ones-ai-k8s # K8S实例 - 输入Pod所在的命名空间,输入PodName查看该Pod容器日志
kubectl -n $namespace logs $PodName
kubectl -n $namespace logs $PodName -c $ContainerName # 如果 Pod 中有多个容器,使用此选项指定容器名,以查看特定容器的日志。
kubectl -n $namespace logs $PodName --tail=20 # 查看最新20行日志
kubectl -n $namespace logs $PodName -f # 实时追踪 Pod 的日志
kubectl -n $namespace logs --previous $PodName # 查看 Pod 上一个容器实例的日志,例:崩溃前容器日志
kubectl -n $namespace logs $PodName > /tmp/PodName.log # 保存日志信息 - 从其他渠道获取日志信息;例:kibanna(EFK\ELK)、grafana(loki)、运维工具箱在线下载日志.
检查Pod的配置
- 登录运维操作服务器。
- 进入ONES运维工具箱容器。
ones-ai-k8s.sh # 进入ones运维操作容器
# cd /data/ones/ones-ai-k8s # K8S实例 - 输入Pod所在的命名空间,输入PodName查看Pod的配置信息。查看Pod的详细配置,包括容器、卷挂载、环境变量等信息。确认配置是否符合预期。特别关注以下配置:
kubectl -n $namespace get po $PodName -o yaml
- 容器镜像版本: 确保使用的容器镜像版本是预期的版本。(查看配置确认)
- 环境变量: 检查环境变量配置,确保配置正确且没有缺漏。
- 卷挂载: 确认卷挂载配置,检查挂载点是否正确,卷是否成功挂载。
检查Pod的监控
登录运维操作服务器。
进入ONES运维工具箱容器。
ones-ai-k8s.sh # 进入ones运维操作容器
# cd /data/ones/ones-ai-k8s # K8S实例输入Pod所在的命名空间,输入PodName查看Pod的监控信息。
kubectl -n $namespace top po $PodName
通过此命令可以查看实时的CPU和内存使用情况,帮助定位资源问题。关注以下指标:
- CPU使用率: 确认是否有异常的CPU使用率波动。
- 内存使用率: 检查内存占用情况,确认是否超过了分配的限制。
- 如上通过
top
命令查看当前Pod实时资源状态,再k3s环境不支持
,同时也建议通过部署内置监控系统,通过grafana面板确认资源及历史资源状态,通过时间曲线维度,更容易发现问题。
使用终端进入容器常规诊断
登录运维操作服务器。
进入ONES运维工具箱容器。
ones-ai-k8s.sh # 进入ones运维操作容器
# cd /data/ones/ones-ai-k8s # K8S实例输入Pod所在的命名空间,输入PodName和ContainerName使用以下命令进入容器终端。
kubectl -n $namespace exec -it $PodName -c $ContainerName -- /bin/bash
kubectl -n $namespace exec -it $PodName -c $ContainerName -- /bin/sh # 没有bash时,通过sh进入终端
kubectl -n $namespace exec -it $PodName -- ping <destination-ip-or-domain>
# 容器制作Base基座有所区别,个别容器可能不适用以下命令。
ps # 通过ps 等命令进行常规进程诊断,需要根据容器业务进行进一步排查,例Project-api,可以排查服务进程、进一步排查其进程使用的配置,是否存在业务配置异常。
ping、curl、wget、telnet nslookup host # 通过此类网络客户端工具排查网络等连通性问题,例:对端点kafka service endpoint 异常,可以通过ping kafka-ha通过ones-tools容器进行诊断
ones-ai-k8s.sh # 进入ones运维操作容器
make ones-tools NAMESPACE=ones # ones 为namespace
ping kafka-ha # 例:测试pod之间端点连通性
mysql -h mysql-cluster-mysql-master -u root -p # 登录MySQL测试,查询联调等
redis # redis联调同理通过3/4步骤命令可以进入容器内部,进行容器内部的调试和排查。
Pod状态为Pending
问题原因
若Pod停留在Pending状态,说明该Pod不能被调度到某一个节点上。通常是由于资源依赖、资源不足、该Pod使用了hostPort、污点和容忍等原因导致集群中缺乏需要的资源。
问题现象
Pod的状态为Pending。
解决方案
查看Pod的事件,根据事件描述,定位Pod不能被调度到节点的原因。主要原因有以下几类:
资源依赖
创建Pod时,需要依赖于集群中ConfigMap、PVC等资源。例如,Pod添加存储卷声明前,存储卷声明需要先与存储卷绑定。
资源不足
查看该Pod节点资源状态(通过登录节点查看/通过grafana监控面板查看/其他方式)
说明
某个节点实际使用的CPU、内存资源非常低,新加入一个Pod时,如果会导致实际使用的资源超过该节点最大可供使用的资源,则调度程序不会将该Pod分配到该节点。这样可避免在日常的流量高峰时段,节点上出现资源短缺的情况。
若集群中的CPU或内存都已经耗尽,可参考如下方法处理。
- 紧急删除或减少不必要的Pod,或通过滚动释放调度到其他节点。
- 根据自身业务情况,调整Pod的资源配置,设置容器CPU和内存资源上下限。
- 集群节点资源扩容升配,或添加新的节点。
该Pod使用了hostPort
如果您使用了hostPort,那么Deployment或ReplicationController中
Replicas
值不能超过集群中的节点数,因为每个实例的任意端口只有一个。如果该端口被其他应用占用,将导致Pod调度失败。因此建议您不要使用hostPort,您可以使用Service访问Pod。污点和容忍
当您在Pod的事件中看到Taints或Tolerations时,说明是由于污点导致,您可以删除污点或者给Pod设置容忍,具体情况需要具体处理,如若当节点异常,已经出现不可调度污点情况,需要紧急处理。
Pod状态为Init:N/M(Init:Error和Init:CrashLoopBackOff)
问题原因
- 若Pod停留在Init:N/M状态,说明该Pod包含M个Init容器,其中N个已经启动完成,但仍有M-N个Init容器未启动成功。
- 若Pod停留在Init:Error状态,说明Pod中的Init容器启动失败。
- 若Pod停留在Init:CrashLoopBackOff状态,说明Pod中的Init容器启动失败并处于反复重启状态。
问题现象
- Pod的状态为Init:N/M。
- Pod的状态为Init:Error。
- Pod的状态为Init:CrashLoopBackOff。
解决方案
- 查看Pod的事件,确认当前Pod中未启动的Init容器是否存在异常。具体操作,请参见检查Pod的详情及事件。
- 查看Pod中未启动的Init容器的日志,通过日志内容排查问题。具体操作,请参见检查Pod的容器日志。
- 查看Pod的配置,确认未启动的Init容器配置是否正常。
Pod状态为ImagePullBackOff
问题原因
若Pod停留在ImagePullBackOff状态,说明此Pod已被调度到某个节点,但拉取镜像失败。
问题现象
Pod的状态为ImagePullBackOff。
解决方案
通过查看该Pod的事件描述,查看具体拉取失败的镜像名称。
确认容器镜像名称是否正确。
登录到Pod所在的节点,执行
docker pull [$Image]
ctr image pull [$Image]
命令,查看是否能正常下载容器镜像。说明
[$Image]
为容器镜像的名称。- 若镜像拉取失败,请排查私有镜像仓库服务状态及网络连通状态,排查是否缺失镜像等。
Pod状态为CrashLoopBackOff
问题原因
若Pod停留在CrashLoopBackOff状态,说明容器中应用程序有问题。
问题现象
Pod的状态为CrashLoopBackOff。
解决方案
- 查看Pod的事件,确认当前Pod是否存在异常。具体操作,请参见检查Pod的详情及事件。
- 查看Pod的日志,通过日志内容排查问题。具体操作,请参见检查Pod的容器日志。
- 查看Pod的配置,确认容器中的健康检查配置是否正常有效。具体操作,请参见检查Pod的配置。。关于Pod健康检查的更多信息,请联系该业务组一并分析,参见K8S/K3S配置存活、就绪和启动探测器配置说明。
Pod状态为Completed
问题原因
若Pod出现Completed状态,说明容器中的启动命令已执行完毕,容器中的所有进程都已退出。
问题现象
Pod的状态为Completed,确认该资源编排,正常情况可以忽略。
解决方案
- 查看Pod的配置,确定Pod中容器的启动命令。具体操作,请参见检查Pod的配置。
- 查看Pod的日志,通过日志内容排查问题。具体操作,检查Pod的容器日志。
Pod状态为Running但没正常工作
问题原因
部署使用的YAML文件有问题。
问题现象
Pod状态为Running但没正常工作。
解决方案
查看Pod的配置,确定Pod中容器的配置是否符合预期。具体操作,请参见检查Pod的配置。
使用以下方法,排查环境变量中的某一个Key是否存在拼写错误。
以command拼写成commnd为例,说明拼写问题排查方法。
说明
创建Pod时,环境变量中的某一个Key拼写错误的问题会被集群忽略,如Command拼写为Commnd,您仍能够使用该YAML文件创建资源。但容器运行时,不会执行有拼写问题的YAML文件,而是执行镜像中的默认命令。
kubectl -n $namespace get po $PodName -o yaml >XXX.yaml # 保存该资源编排配置
在执行
kubectl apply -f
命令前为其添加--validate
,然后执行kubectl apply --validate -f XXX.yaml
命令。如果您将command拼写成commnd,将看到错误信息
XXX] unknown field: commnd XXX] this may be a false alarm, see https://gXXXb.XXX/6842pods/test
。执行以下命令,将输出结果的pod.yaml文件与您创建Pod使用的文件进行对比。
kubectl -n $namespace get pods $PodName -o yaml > pod.yaml
说明
[$PodName]
为异常Pod的名称,您可以通过kubectl get pods
命令查看。- pod.yaml文件比您创建Pod所使用的文件多几行,说明已创建的Pod符合预期。
- 如果您创建Pod所使用文件里的代码行在pod.yaml文件中没有,说明您创建Pod使用的文件存在拼写问题。
查看Pod的日志,通过日志内容排查问题。具体操作,检查Pod的容器日志。
可通过终端进入容器查看容器内的本地文件是否符合预期。具体操作,请参见使用终端进入容器常规诊断
Pod状态为Terminating
问题原因
若Pod的状态为Terminating,说明此Pod正处于关闭状态。
问题现象
Pod状态为Terminating。
解决方案
Pod停留在Terminating状态一段时间后会被自动删除。若Pod一直停留在Terminating状态,可执行如下命令强制删除:
kubectl delete pod $PodName -n $namespace --grace-period=0 --force
Pod状态为Evicted
问题原因
当节点的内存、磁盘空间、文件系统的inode和操作系统可分配的PID等资源中的一个或者多个达到特定的消耗水平,就会引发kubelet主动地驱逐节点上一个或者多个Pod,以回收节点资源。
问题现象
Pod的状态为Evicted。
解决方案
执行以下命令,查看Pod的
status.message
字段,来确定Pod被驱逐的原因。kubectl get pod $PodName -o yaml -n $namespace
预期输出:
status:
message: 'Pod the node had condition: [DiskPressure].'
phase: Failed
reason: Evicted通过上述
status.message
字段,可以判断当前Pod是因为节点磁盘压力 (DiskPressure) 被驱逐。说明
注意这里仅以磁盘压力驱逐为例,其它例如内存压力(MemoryPressure)和PID压力(PIDPressure)等也会以类似的方式展示。
执行以下命令,删除被驱逐的Pod。
kubectl get pods -n [$namespace]| grep Evicted | awk '{print $1}' | xargs kubectl delete pod -n [$namespace]
以下汇总如何避免Pod被驱逐的方法:
- 内存压力:
- 根据自身业务情况,调整Pod的资源配置,设置容器的CPU和内存资源上下限。
- 为节点进行扩容升配。
- 磁盘压力:
- 定时清理节点上的业务Pod日志,避免磁盘被日志打满。
- 为节点进行磁盘扩容。
- PID压力:根据自身业务情况,调整Pod的资源配置。
Pod OOM异常问题处理
问题原因
当集群中的容器使用超过其限制的内存,容器可能会被终止,触发OOM(Out Of Memory)事件,导致容器异常退出。关于OOM事件,调整Pod的资源配置,设置容器的内存资源上下限,该类场景无法一概而论,需要该业务模块进一步定位分析,避免业务内存使用不佳,泄漏等问题。
问题现象
- 若被终止的进程为容器的阻塞进程,可能导致容器异常重启。
- 若出现OOM异常问题,请参见检查Pod的详情及事件。
- 若有配置集群异常报警服务,则OOM事件出现时可收到相关报警。
解决方案
查看发生OOM异常的Pod所在的节点。
命令行方式查看
执行以下命令,查看容器信息。
kubectl get pod $PodName -o wide -n $namespace
预期输出:
NAME READY STATUS RESTARTS AGE IP NODE
pod_name 1/1 Running 0 12h 192.20.6.52 ones-001Grafana监控面板查看:查看Pod详情下的节点信息,Grafana检查节点的监控 通过kubectl查看 请参见检查Pod的详情及事件。
登录Pod所在的Node,查看内核日志
/var/log/message
。在日志中查询关键字out of memory
,确认具体被OOM终止的进程。如果该进程是容器的阻塞进程,OOM终止后容器会重启。通过Grafana监控面板,观测Pod内存监控查看内存增长曲线,确定异常出现时间。
根据监控、内存增长时间点、日志、进程名等信息,排查Pod内对应进程是否存在内存泄漏。
- 若OOM是进程内存泄漏导致,请联系业务模块自行排查泄露原因。
- 若进程运行状态正常,则根据实际运行需要,适当增大Pod的内存限制,建议Pod的内存实际使用量不超过内存限制值的80%。
📄️ Node故障处理
本文介绍关于 k3s/k8s Node节点异常问题的诊断流程、排查思路、常见问题及解决方案。
📄️ POD故障处理
本文介绍关于 k3s/k8s Pod异常问题的诊断流程、排查方法、常见问题及解决方案。
📄️ Alert故障处理
本文介绍关于 k3s/k8s 常见告警主题处理及解决方案。
📄️ ONES故障处理
本文介绍关于 ONES 常见场景故障处理及解决方案。