7 张图解 CrashLoopBackOff,如何发现问题并解决它?
Posted CN-FuWei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了7 张图解 CrashLoopBackOff,如何发现问题并解决它?相关的知识,希望对你有一定的参考价值。
一、什么是 CrashLoopBackOff
CrashLoopBackOff
是一种 Kubernetes 状态,表示 Pod 中发生的重启循环:Pod 中的容器已启动,但一遍又一遍的崩溃然后又重新启动。
Kubernetes 将在重新启动之间等待越来越长的BackOff
时间,以便您有机会修复错误。因此,CrashLoopBackOff 本身并不是一个错误,而是表明发生了一个错误,导致 Pod 无法正常启动。
Pod 在 Running、Failed 和 Waiting 之间循环
请注意,它重新启动的原因是因为它restartPolicy
设置为Always
(默认情况下)或OnFailure
,然后 kubelet 读取此配置并重新启动 Pod 中的容器并导致循环。这种行为实际上很有用,因为这为丢失的资源完成加载提供了一些时间,也为我们检测问题和调试提供了一些时间,稍后会详细介绍。
这解释了CrashLoop
部分,但是BackOff
时间呢?基本上,这是重启之间的指数延迟(10 秒、20 秒、40 秒……),上限为 5 分钟。当 Pod 状态显示 CrashLoopBackOff 时,表示它当前正在等待指示的时间,然后再重新启动 Pod。除非它被修复,否则它可能会再次失败。
Pod 处于循环中。尝试运行,但失败了,所以进入失败状态。稍等片刻以帮助您调试,则会尝试再次运行。如果问题没有解决,就陷入了循环,将再次失败
二、如何检测集群中的 CrashLoopBackOff?
最有可能的是,您通过kubectl get pods
列出一个或多个处于此状态的 Pod:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
flask-7996469c47-d7zl2 1/1 Running 1 77d
flask-7996469c47-tdr2n 1/1 Running 0 77d
nginx-5796d5bc7c-2jdr5 0/1 CrashLoopBackOff 2 1m
nginx-5796d5bc7c-xsl6p 0/1 CrashLoopBackOff 2 1m
从输出中,您可以看到最后两个 pod:
-
不处于
READY
(0/1
) 状态。 -
他们的状态显示
CrashLoopBackOff
。 -
列
RESTARTS
显示重新启动次数。
这三个信号指向我们解释的内容:Pod 出现故障,它们正在重新启动。在重新启动之间,有一个宽限期,表示为CrashLoopBackOff
.
您可能在 Pod 处于Running
或Failed
状态的短暂时间内找到它。
CrashloopBackoff 的时间线。每次失败时,BackoffTime 和 Restart Count 都会增加
三、CrashLoopBackOff 的常见原因
重要的是要注意 CrashLoopBackOff
不是导致 pod 崩溃的实际错误。请记住,它只是显示STATUS
列中发生的循环。您需要找到影响容器的潜在错误。
与实际应用程序相关的一些错误是:
-
错误配置: 就像配置文件中的错误配置
-
资源不可用: 例如未挂载的 PersistentVolume
-
错误的命令行参数: 要么丢失,要么不正确的命令行参数
-
bug 和异常: 这可以是任何异常,对你的应用来说都是非常具体的
最后是网络和权限的错误:
-
您试图绑定被占用的端口。
-
内存限制太低,容器被
Out Of Memory
杀死。 -
liveness 探针返回错误,未报告 Pod 已 Ready。
-
只读文件系统,或缺乏权限。
以上这些只是可能原因的列表,可能还有很多其他原因。
现在让我们看看如何深入挖掘并找到真正的原因。
四、调试、排障和修复
上文,了解到 pod 最终处于 CrashLoopBackOff
状态的原因有很多。现在,怎么知道是哪个在影响?让我们回顾一下可以用来调试它的一些命令,以及使用它的顺序。
这可能是我们最好的做法:
-
检查
pod 描述
。 -
检查
pod 日志
。 -
检查 events。
-
检查 deployment。
1.查看 pod 描述:kubectl describe pod
该kubectl describe pod
命令提供特定 Pod 及其容器的详细信息:
$ kubectl describe pod the-pod-name
Name: the-pod-name
Namespace: default
Priority: 0
…
State: Waiting
Reason: CrashLoopBackOff
Last State: Terminated
Reason: Error
…
Warning BackOff 1m (x5 over 1m) kubelet, ip-10-0-9-132.us-east-2.compute.internal Back-off restarting failed container
…
从描述输出中,您可以提取以下信息:
-
当前 pod
State
是Waiting
. -
等待状态的 原因是 CrashLoopBackOff。
-
上一个 状态是 Terminated。
-
上次终止的原因 是 Error。
这与我们一直在解释的循环行为一致。
通过使用kubectl describe pod
,您可以检查以下配置错误:
-
Pod 定义
-
容器
-
为容器拉取的 镜像
-
为容器分配的 资源
-
错误或缺少的 参数
-
…
…
Warning BackOff 1m (x5 over 1m) kubelet, ip-10-0-9-132.us-east-2.compute.internal Back-off restarting failed container
…
在最后几行中,您会看到与此 pod 关联的最后一个事件的列表,其中之一是"Back-off restarting failed container"
,这是重启循环的事件。即使发生了多次重新启动,也应该只有一行。
2.查看日志:kubectl logs
您可以查看 pod 的所有容器的日志:
kubectl logs mypod --all-containers
或者指定的容器:
kubectl logs mypod -c mycontainer
日志可能会显示有用的信息。
3.查看事件:kubectl get events
可以列出相关的事件:
kubectl get events
或者,您可以使用以下命令列出单个 Pod 的所有事件:
kubectl get events --field-selector involvedObject.name=mypod
请注意,此信息也出现在describe pod
输出的底部。
4.检查部署:kubectl describe deployment
您可以通过以下方式获取此信息:
kubectl describe deployment mydeployment
如果deployment
定义了所需的 Pod 状态,它可能包含导致 CrashLoopBackOff
的错误配置。
结合起来看
在下面的示例中,您可以看到如何挖掘日志,在其中发现命令参数中的错误。
调试 Crashloopbackoff。它显示了三个终端以及几个调试命令之间的关系。
五、在 Prometheus 中检测 CrashLoopBackOff
如果您使用 Prometheus 进行监控,这里有一些提示可以帮助您在发生 CrashLoopBackOff
时发出警报。
使用以下表达式,可以快速扫描集群中处于CrashLoopBackOff
状态的容器。您需要提前部署 Kube State Metrics
https://github.com/kubernetes/kube-state-metrics
kube_pod_container_status_waiting_reasonreason="CrashLoopBackOff" == 1
检测 pod 状态为 CrashLoopBackOff 的 PromQL 示例
或者,你可以用以下方法跟踪 pod 发生的重启次数:
rate(kube_pod_container_status_restarts_total[5m]) > 0
基于重启率检测 CrashLoopBackOff 的 PromQL 示例
警告:并非集群中发生的所有重启都与 CrashLoopBackOff 状态有关。
重新启动和 crashloopbackoff 之间的相关性。并非所有重启都是由 crashloopbackoff 引起的
在每个 CrashLoopBackOff 周期之后应该有一个重新启动 可能有与 CrashLoopBackOff 无关的重新启动。
可以创建如下所示的 Prometheus 警报规则,当任何 pod 处于此状态时接收通知:
- alert: RestartsAlert
expr: rate(kube_pod_container_status_restarts_total[5m]) > 0
for: 10m
labels:
severity: warning
annotations:
summary: Pod is being restarted
description: Pod $labels.pod in $labels.namespace has a container $labels.container which is being restarted
六、结论
在这篇文章中,我们看到了 CrashLoopBackOff
本身并不是一个错误,而只是一个在 pod 中发生的重试循环的通知。
我们看到了它所经过的状态的描述,以及如何使用kubectl
命令跟踪它。
此外,我们还看到了可能导致此状态的常见错误配置,以及您可以使用哪些工具来调试它。
最后,我们回顾了 Prometheus
如何帮助跟踪和提醒 Pod
中的 CrashLoopBackOff
事件。
虽然不是一个直观的消息,但 CrashLoopBackOff
是一个有用的概念,它是有意义的,没有什么可害怕的。
参考:https://u.kubeinfo.cn/7AO7bG
16 张图解 | 一致性哈希算法
以上是关于7 张图解 CrashLoopBackOff,如何发现问题并解决它?的主要内容,如果未能解决你的问题,请参考以下文章
k8s启动Pod遇到CrashLoopBackOff的解决方法