0


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

状态的原因有很多。现在,怎么知道是哪个在影响?让我们回顾一下可以用来调试它的一些命令,以及使用它的顺序。

这可能是我们最好的做法:

  1. 检查pod 描述
  2. 检查pod 日志
  3. 检查 events
  4. 检查 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
…

从描述输出中,您可以提取以下信息:

  • 当前 podStateWaiting.
  • 等待状态的 原因是 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_reason{reason="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 *


本文转载自: https://blog.csdn.net/zfw_666666/article/details/126606394
版权归原作者 CN-FuWei 所有, 如有侵权,请联系我们删除。

“7 张图解 CrashLoopBackOff,如何发现问题并解决它?”的评论:

还没有评论