对于越来越多的Kubernetes容器云,排查Kubernetes集群成为了一个棘手的问题。本文将通过直观的方式向您展示如何排查Kubernetes故障。本文是系列文章-疑难解答的续篇。图解部署配置可以参考上一篇文章:图解Kubernetes应用部署概述在上一篇文章中,我们介绍了Kubernetes的三个关键组件的入口,service和Pod是如何连接的,以及相关配置的要点。了解如何正确配置YAML只是一个开始。最重要和最实际的是知道如何解决问题。在深入研究部署故障排除之前,我们必须首先给出一个故障排除Kubernetes的心智模型。由于每个部署中包含三个组件,因此需要从底部开始依次调试所有组件。解决Kubernetes部署故障的关键是3个步骤:确保Pod正常运行;确保服务可以将流量分派给Pod;检查ingress配置是否正确。VisualDiagram首先检查Pod是否已经创建,是否正常。其次,如果pod是正常的,你应该检查service是否能把流量分流到pod上。最后,检查服务和入口之间的连接。Pod故障排除在大多数情况下,问题出在Pod本身。它应该确保Pod正在运行并准备就绪(READY为1)。检查方法:kubectlgetpods如上会话,最后一个Pod处于“Running”和“Ready”状态,前两个Pod不处于Running状态,也不处于“Ready”状态。关键点可以通过以下命令排查Pod故障:kubectllogs:用于查看Pod容器日志。kubectldescribepod:用于查看与Pod相关的事件列表。kubectlgetpod:用于获取Pod的YAML定义。kubectlexec-tibash:进入Pod容器的交互式终端。常见Pod错误列表Pod可能会出现各种启动和运行时错误。启动错误:ImagePullBackoff,ImageInspectError,ErrImagePull,ErrImageNeverPull,RegistryUnavailable,InvalidImageName运行时错误:CrashLoopBackOff,RunContainerError,KillContainerError,VerifyNonRootError,RunInitContainerError,CreatePodSandboxError,ConfigPodSandboxError,KillPodSandboxError,SetupNetworkError,TeardownNetworkError关键错误代码及其修复方法ImagePullBackOff当Kubernetes无法检索Pod当容器的图像之一时发生此错误。主要有以下三个原因:镜像名称不合法。例如,您输入的名称有误,或者图像不存在。为图像指定了不存在的标签。您尝试检索的图像属于私有注册表,但Kubernetes无权访问它。解决方法:前两种情况可以通过修改镜像名称和标签来解决。第三个问题是凭证需要添加到注册中心并在Pod中引用。在官方文档中有一个关于如何实现这一点的例子。CrashLoopBackOff如果容器启动失败,Kubernetes状态会显示CrashLoopBackOff错误。通常,Pod容器在以下情况下无法启动:应用程序中存在阻止其启动的错误;容器配置不正确;Liveness探测失败次数过多;解决方法:查看容器中的日志,详细了解失败的原因。kubectllogs--previousRunContainerError容器启动失败时的错误,直到容器内的应用程序启动之前。这个问题一般是因为配置错误,比如:挂载一个不存在的volume,比如ConfigMap或者Secrets,挂载一个只读的volume为read-write解决方法:对于这个错误,应该使用kubectldescribepod来收集并分析错误。Pod处于Pending状态当Pod创建时,该Pod仍处于Pending状态。主要可能原因:集群没有足够的资源(如CPU和内存)来运行pod;当前命名空间有一个ResourceQuota对象,创建一个pod会使命名空间超过配额;pod绑定到一个挂起的PersistentVolumeClaim;解决方法:检查kubectldescribe命令的事件部分:kubectldescribepod对于由于ResourceQuotas导致的错误,您可以使用以下方法检查集群的日志:kubectlgetevents--sort-by=.metadata.creationTimestampPod未就绪如果Pod是正在运行但未就绪,表示“就绪”探测失败。当就绪探测失败时,Pod不会连接到服务,也不会向实例转发任何流量。解决方法Readiness探测失败是特定于应用程序的错误,因此应检查kubectl描述中的“事件”部分以识别错误。服务故障排除如果您的pod正在运行并准备就绪,但您仍然没有收到来自您的应用程序的响应,您应该检查您的服务是否配置正确。关键点服务的主要功能是根据流量的标签将流量路由到Pod。因此,您应该首先检查该服务有多少个Pod,这可以通过检查服务中的端点来查看:kubectldescribeservice|grepEndpoints端点是一对,当服务(至少)以Pod为目标时,应该至少有一个。如果“Endpoints”部分为空,有两个原因:没有使用正确标签运行的pod,您应该检查您是否在正确的命名空间中。服务的选择器标签中有错字;如果您可以看到端点列表,但仍然无法访问应用程序,这主要是由于服务中的targetPort配置错误。具体排查可以使用kubectlport-forward连接服务:kubectlport-forwardservice/3000:80入口排查如果Pod运行正常,服务可以向Pod分发流量,可能的原因是入口配置不正确:根据入口可能使用不同的控制器类型,需要根据具体对应的方法进行调试。重点是检查入口配置参数serviceName和servicePort是否配置正确。可以使用以下命令检查:kubectldescribeingress如果“Backend”栏为空,则一定是配置有误。如果在“Backend”一栏可以看到端口,但仍然无法访问应用,可能是以下问题:没有如何将ingress发布到公网;没有如何将集群发布到公网;您可以直接连接到IngressPod以将基础设施问题与入口隔离开来。首先查看ingresscontrollerPod列表:kubectlgetpods--all-namespaces其次使用kubectldescribe命令查看端口:kubectldescribepodnginx-ingress-controller-6fc5bcc最后连接Pod:kubectlport-forwardnginx-ingress-controller-6fc5bcc3000:80--namespacekube-system这样,访问电脑3000端口时,请求会被转发到Pod的80端口。该应用程序现在可以使用吗?如果是,则问题出在基础架构中。应检查如何将流量安排到集群。如果这不起作用,则问题出在入口控制器中。应调试入口控制器。常见的入口控件有Nginx、HAProxy、Traefik等,可以查看具体的控制器相关文档进行排查。这里我们以Nginx为例:排查Nginx控制器Ingress-nginx项目是官方的Kubectl插件。您可以使用kubectlingress-nginx来:查看日志、后端、证书等;连接到入口;检查当前配置。对应的命令为:kubectlingress-nginxlint:用于检查nginx.confkubectlingress-nginxbackend:用于检查后端(类似于kubectldescribeingress)kubectlingress-nginxlogs:查看控制器日志。总结对具有复杂架构(如Kubernetes)的集群进行故障排除是一项艰巨的任务。有“虎食天,爪无处”之说。任务艰巨,首要任务是寻找故障排除思路。Kubernetes集群的排查应该遵循自下而上的排查方法:先从Pod开始,然后是service和entry,依次排查。
