为了避免业务停机,我们需要不断完善K8S的排障技能, 定期对整个 Kubernetes 集群进行调试和故障排除对运维服务稳定至关重要。故障排除包括识别、诊断和解决 Kubernetes 集群、节点、Pod、容器和其他资源中的各类问题。
由于 Kubernetes 是一个复杂的系统,因此解决问题可能具有挑战性。问题可能发生在单个容器、一个或多个 pod、control、control plane 组件或这些组件的组合中。这使得即使在小型本地 Kubernetes 集群中诊断和修复错误也具有挑战性。如果在大规模生产设置中能见度有限且移动部件众多,问题就会变得更糟。
以下部分列出了一些最常见的 Kubernetes 错误消息和问题、出现时用于识别它们的命令以及解决它们的提示。
1.ImagePullBackOff
Kubernetes pod 无法启动的原因之一是运行时无法从注册表中检索容器镜像。换句话说,pod 不会启动,因为至少有一个在清单中指定的容器没有启动。
当 pod 遇到此问题时,kubectl get pods 命令会将 pod 的状态显示为ImagePullBackOff。当镜像名称或标签错误地输入到 pod 清单中时,可能会发生此错误。在这种情况下,从连接到 Docker 注册表的任何集群节点使用 docker pull 来确认正确的镜像名称。然后,在 pod 清单中更改它。
当容器注册表的权限和身份验证问题阻止 pod 检索镜像时,也会出现ImagePullBackOff。这通常发生在秘密持有凭证(ImagePullSecret)出现问题或 pod 缺少所需的基于角色的访问控制 (RBAC) 角色时。要解决此问题,请确保 pod 和节点具有适当的权限和机密,然后使用 docker pull 命令手动尝试操作。
您还可以通过为 docker pull 命令设置 --v 参数来更改日志详细程度。调高日志级别以获取有关错误发生原因的更多信息。
如果您不知道用于登录和拉取镜像的凭据或 ImagePullSecret 的内容,您可以按照以下步骤操作。
首先,使用kubectl get deploy 或者 kubectl get sts 命令,将 <IMAGE_NAME> 替换为您要检索的 ImagePullSecret 的名称。
问题解决思路:
1-1.如果是K8S第一次部署服务,部署的镜像仓库是私人的镜像仓库,那么很大可能是因为K8S没有完成跟私有镜像仓库的验证,这时候就要完成跟私有镜像仓库的验证,就可以拉取镜像仓库里面的验证了。
1-2.如果是日常K8S的部署服务中出现这个问题,那么很有可能就是拉取的镜像仓库的镜像名字不对。一方面是做编译镜像的时候把镜像名字定义错了,另一方面可能就是定义deployment文件或者helm chart模板的时候把镜像名称搞错了。总之这种情况一般是出现在刚做ci/cd的时候容易出现这种问题。等到ci/cd跑通了,这种情况就基本不会出现了。
2.CrashLoopBackOff
Pod 可能无法启动的另一个原因是无法在节点上调度指定的容器。当 pod 遇到此问题时,kubectl get pods 命令会将 pod 的状态显示为 CrashLoopBackOff。
如果 pod 无法安装请求的卷或者节点没有运行 pod 所需的资源,则可能会发生此错误。要获取有关该错误的更多信息,请运行以下命令:
kubectl describe pod <pod name>
问题解决思路:
2-1.一般出现这种问题就是存活探针或者就绪探针没有通过,导致pod一直在重启,基本上都是业务方面的问题或者配置文件有问题了,在容器里面的服务没有正常跑起来,导致K8S一直在尝试重启pod。这时候,一般
kubectl logs -f <pod name>
一般可以看出业务程序抛出了什么错误导致的退出。
3.Out-of-Memory
当容器因 OOM 错误而终止时,通常会出现资源短缺或内存泄漏。
执行
kubectl describe pod <pod name>
命令来确定 pod 中的容器是否已达到资源限制。如果是这样,终止的原因将显示为 OOMKilled。此错误表明 Pod 的容器已尝试使用超过配置限制的内存。
问题解决思路
3-1.如果每个pod都有定义cpu和内存的限制,那么需要在deployment或者sts中增加内存资源的数值。
3-2.如果pod没有资源的限制,程序方面也没有问题,不过使用的实例类型内存又偏小,无法再扩容调度。这个时候需要选择内存大的实例类型,把pod调度到新的实例类型中去。
3-3.我们之前的遇到java程序在切换到微服务中确实会出现内存溢出的问题,这个需要跟开发反馈,把程序的问题处理一下
4.BackoffLimitExceeded
BackoffLimitExceeded 表示 Kubernetes 作业在多次重启失败后已达到其重试限制。
Kubernetes 中的作业可以控制 pod 的运行时、监视其状态并在 pod 出现故障时重新启动。backoffLimit 是一个作业配置选项,它控制在作业最终被视为失败之前 pod 可以失败和重试的次数。此配置设置的默认值为 6。这意味着作业将重试六次,之后重试将停止。您可以执行
kubectl descrippod <pod name>
命令来确定作业是否因 BackoffLimitExceeded错误而失败。
Kubernetes 作业的成功或失败状态取决于它管理的容器的最终退出代码。因此,如果作业的退出代码不是 0,则视为失败。作业可能因多种原因而失败,包括指定路径不存在或作业无法找到要处理的输入文件。
您可以通过对作业定义执行故障分析来克服此作业故障。执行
kubectl logs <pod name>
命令来检查 pod 的日志,这通常会发现失败的原因。
5.Probe Failures
为了监控和响应 Pod 的状态,Kubernetes 提供了探针(健康检查)以确保只有健康的 Pod 才能为请求提供服务。每个探针(Startup、Liveness 和 Readiness)都有助于 Kubernetes pod 在不健康时进行自我修复。当探针处于挂起状态的时间过长或者未就绪或无法安排时,它可能会失败。
Pod 有四个阶段的生命周期:Pending、Running、Succeeded 和 Failed。它的当前阶段取决于其主要容器的终止状态。如果 pod 卡在 Pending中,则无法将其调度到节点上。在大多数情况下,调度会因资源不足而受阻。
查看 kubectl describe命令的输出将使您更加清楚。如果 pod 保持挂起状态,则可能是一个问题,根本原因可能是节点中的资源不足。或者,如果您为不可用的容器指定主机端口,或者该端口已在 Kubernetes 集群的所有节点中使用,则 pod 可能未就绪。
不管失败的原因是什么,您都可以使用 kubectl describe pod 命令来找出 pod 失败的原因。您的下一步将根据失败的原因而有所不同。例如,如果在容器中运行的应用程序响应时间比配置的探测超时时间长,则 Kubernetes 中可能会发生探测失败。通过增加探测超时、监视日志和手动测试探测来排除故障。确定根本原因后,优化应用程序、扩展资源或调整探针配置。
评论区