CrashLoopBackOff 概述
首先关于CrashLoopBackOff并不是代表一种错误, "CrashLoopBackOff 是 Kubernetes 中的一个状态,表示在一个 Pod 中发生的重启循环:Pod 中的一个容器启动之后发生了问题,然后反复重启。
Kubernetes 会在重启之间等待逐渐增加的退避时间,我们在发现CrashLoopBackOff之后可以对集群进行及时的修复。因此,CrashLoopBackOff 本身并不是一个问题,而是表明有一个错误在发生,阻止了 Pod 正确启动。"
CrashLoopBackOff之所以会导致Pod重新启动,是因为在Pod的配置策略中 restartPolicy 设置为 Always(默认)或 OnFailure。kubelet 读取此配置并重新启动 Pod 中的容器导致循环。实际上,这种行为非常有用,因为它为缺少的资源完成加载提供了一些时间,同时也为我们检测问题和调试提供了时间(后面会详细讲到)
这解释了 "CrashLoop" 的部分,但 "BackOff" 时间是什么呢?它表示Pod重启时间的延迟(10秒,20秒,40秒,...),最多延迟五分钟。当一个 Pod 的状态显示为 CrashLoopBackOff 时,这意味着它当前正在等待指定的时间,然后再次重新启动 Pod
如何检测到CrashLoopBackOff问题?
什么是 CrashLoopBackOff
通过使用 kubectl get pods 命令列出 Pods 时,发现了一个或多个处于这种状态的 Pods
$ kubectl get podsNAME READY STATUS RESTARTS AGEflask-7996469c47-d7zl2 1/1 Running 1 77dflask-7996469c47-tdr2n 1/1 Running 0 77dnginx-5796d5bc7c-2jdr5 0/1 CrashLoopBackOff 2 1mnginx-5796d5bc7c-xsl6p 0/1 CrashLoopBackOff 2 1m
从输出中,我们可以看到最后两个 Pods:
处于未就绪状态(0/1)。
它们的状态显示为 CrashLoopBackOff。
列 RESTARTS 显示一个或多个重新启动。
这三个信号指向了我们之前解释的情况:Pods 失败,然后被重新启动。在重新启动之间,存在一个优雅的等待期,这被表示为 CrashLoopBackOff。
我们也可以在 Pods 处于短暂的 Running 或 Failed 状态时找到它们
CrashLoopBackOff的常见原因
需要注意的是,CrashLoopBackOff 不是导致 Pod 崩溃的实际错误。它只是在状态列中显示正在发生的循环。所以我们需要找到影响容器的根本错误原因是什么
与实际应用程序相关的一些错误包括:
配置错误:比如配置文件中的拼写错误。
资源不可用:比如未挂载的持久卷(PersistentVolume)。
命令行参数错误:要么缺失,要么不正确。
错误和异常:可以是任何与您的应用程序非常具体的错误。
最后,与网络和权限相关的错误包括:
尝试绑定已存在的端口。
内存限制过低,因此容器会因内存不足而被终止。
存活探测错误未将 Pod 报告为Active状态。
只读文件系统,或者一般权限不足。
类似的等待状态还有 ImagePullBackOff,这是在无法拉取容器镜像时出现的状态。
再次强调,这只是可能导致问题的一些原因列表,还可能有其他原因。现在让我们看看如何深入挖掘并找到实际的原因。
CrashLoopBackOff 错误排查和修复
从上面内容中,我们了解到pod最终处于CrashLoopBackOff状态的原因有很多。那么,怎么知道具体什么原因影响的呢? 这里,我们来介绍一些常用的调试工具以及使用顺序。
一般的排查方式如下:
查看Pod信息。
检查Pod日志。
检查集群Event。
检查Deployment部署。
01.检查pod详细信息- kubectl description pod
kubectl description pod 命令提供特定pod及其容器的详细信息:
$ kubectl describe pod the-pod-nameName: the-pod-nameNamespace: defaultPriority: 0…State: WaitingReason: CrashLoopBackOffLast State: TerminatedReason: Error…Warning BackOff 1m (x5 over 1m) kubelet, ip-10-0-9-132.us-east-2.compute.internal Back-off restarting failed container…
从描述输出中,您可以提取以下信息:
当前 Pod 的状态为 "等待"。
等待状态的原因是 "CrashLoopBackOff"。
最后(或以前)的状态是 "终止"。
最后一次终止的原因是 "错误"。
这与我们一直在解释的循环行为相吻合。
通过使用 kubectl describe pod,您可以检查以下是否存在配置错误:
Pod 的定义。
contaniner信息。
contaniner拉取的镜像。
为container分配的资源。
错误或丢失的参数。
这有助于找出问题并进行进一步的调试。
…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"。这是与重新启动循环相关的事件。即使发生多次重新启动,应该只有一行来表示这个事件。
02. 检查日志 - 使用 kubectl logs
您可以查看 Pod 中所有容器的日志:
kubectl logs mypod --all-containersCode language: JavaScript (javascript)
或者甚至是 Pod 中的一个容器的日志:
kubectl logs mypod -c mycontainerCode language: JavaScript (javascript)
如果受影响的pod中有错误的值,日志可能会显示有用的信息。
03. 检查Event - 使用 kubectl get events
使用get events查看
kubectl get eventsCode language: JavaScript (javascript)
或者,可以使用以下命令列出单个Pod的所有事件:
kubectl get events --field-selector involvedObject.name=mypodCode language: JavaScript (javascript)
注意,这些信息也出现在描述pod输出的底部。
04. 检查Deploment - kubectl describe deployment
如何如下命令进行查看
kubectl describe deployment mydeploymentCode language: JavaScript (javascript)
这是一个定义所需Pod状态的部署,它可能包含导致CrashLoopBackOff的错误配置。
如何在Prometheus中检测CrashLoopBackOff
如果您正在使用 Prometheus 进行云监控,以下是一些建议,可以帮助我们在发生 CrashLoopBackOff 时触发警报。
我们也可以通过使用以下表达式(需要 Kube State Metrics)来快速扫描集群中处于 CrashLoopBackOff 状态的容器:
kube_pod_container_status_waiting_reason{reason="CrashLoopBackOff"} == 1
或者,我们可以追踪发生在 Pod 中的重新启动次数,使用以下方式:
rate(kube_pod_container_status_restarts_total[5m]) > 0
注意:并非集群中的所有重新启动都与 CrashLoopBackOff 状态相关。
在每次 CrashLoopBackOff 期间之后应该会有一次重新启动(1),但也可能存在与 CrashLoopBackOff 无关的重新启动(2)。
之后,我们可以创建一个像下面这样的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并不是一个很直观的错误信息展示,但它是一个有意义的功能,至少我们在这个期间进行具体问题的排查。
如果想进一步交流的话,欢迎加我 V:kubedata
我们宗旨:分享创造价值、交流促进成长,欢迎关注:云原生大数据技术荟