广告

12个用于调试Kubernetes工作负载的命令

  • 浏览(104)
  • 评论(0)
  • 译者:k8s

不管你是遭遇可怕的CrashLoopBack还是其他失败,这些命令将帮助你缩小工作负载问题的范围,以便修复它们。本文使用在任何集群中都可以使用的命令(无论在何处运行它),也没有假设在安装指标服务器之外有集中的指标或日志记录。
大多数命令将使用kubectl命令或插件,你可以通过krew安装这些命令或插件。如果你不想使用这些插件,通常可以从kubectl获得相同的信息,但这些插件将格式化数据,使调试更容易。
假设代码正常工作,并且知道哪个应用程序被破坏,以及它在哪里运行。Kubernetes无法修复损坏的代码。但是如果容器无法启动或者应用程序出现间歇性错误,你可以从这里开始。本文将跳过一些细节,例如查找应用程序正在运行的集群、区域或命名空间,或者哪个版本是最新的,因为这些对于你的环境来说是唯一的。
存在不同类型的工作负载错误,我们将其分为三个故障排除阶段:——工作负载无法运行——无法访问工作负载——调试特定的pod
示例命令和屏幕截图使用了一个名为“spider”的虚拟工作负载,因此每当你在命令中看到spider*、$LABEL或$POD时,都应该将其替换为你自己的工作负载名称。
工作负载无法运行
kubectl get events fieldselector type=Warning allnamespaceskubectl get nodes o wide labelcolumns topology.kubernetes.io/zonekubectl resourcecapacity pods util sort cpu.utilkubectl get all showlabelskubectl lineage pod ${POD}kail l ${LABEL}
第一类错误适用于集群中的所有工作负载。不管它是部署、DaemonSet还是cron作业。在每种情况下,在节点上运行的东西都是一组称为pod的容器。pod是Kubernetes中最小的工作单元,因此我们需要研究pod来解决应用程序问题也就不足为奇了。
就像集群故障排除一样,你应该从广度优先的方法开始,并将范围缩小到特定的问题上。应用程序可能并不是到处都有问题,所以我们应该首先看看它有问题的地方、发生了什么变化以及有什么不同。
我们将使用的示例命令将只查看默认命名空间,但你应该为特定工作负载添加-n $NAMESPACE。所有这些命令的最终目标都是让你找到日志行或错误消息,说明为什么某些东西没有运行。这可能来自你的基础设施提供商、Kubernetes控制器或应用程序。

1. kubectl get events –field-selector type=Warning –all-namespaces

图片
首先,我们应该在集群中尽可能广泛地开始。根据集群中的工作负载大小和数量,此命令可能会有大量输出。在较小的集群中,它可能只足以指出为什么工作负载不工作的一些明显问题。
你可能会在该命令中看到控制器和Kubernetes组件的错误,这可能会显示某些失败的原因或位置。在我们的示例屏幕截图中,你可以看到有警告,因为我们无法为pod分配IP地址。我们可能会在kubelet日志中看到这些相同的错误,但查看集群中的所有警告将向我们展示错误如何级联到不同的控制器中。
2.kubectl get nodes-o wide–label-columns topology.kubernetes.io/zone
图片
此输出对于任何调试过程都非常常见。你应该能够快速识别任何未处于“就绪”状态,或可能具有不同版本的kubelet,或不同的容器运行时的节点。通过添加拓扑区域输出,你还可以查看是否有任何节点问题与特定区域相关,该区域可能存在其他问题,例如网络分区或从属服务不可用。

3. kubectl resource-capacity –pods –util –sort cpu.util

图片
即使在容器的世界中,你仍然需要处理CPU和内存资源。资源容量插件可以节省大量命令,以了解节点的使用方式以及哪些pod可能使用的资源超过了它们应该使用的资源。你可以使用kubectl krew install resource capacity安装该插件。
需要注意的是:此插件要求在集群中安装指标服务器。一旦运行该命令,你应该能够使用该命令查找资源有限或pod未设置限制的潜在问题。

4. kubectl get all –show-labels

图片
这个命令不会显示所有内容,但我们真正关心的是部署、pod和服务。通过包含每个工作负载的标签,我们可以看到类似pod-template-hash标签的内容,这将为我们提供一个哈希值,你可以在部署和pod之间进行匹配。如果任何pod没有运行,我们知道下一步该去哪里。
在这一点上,最好也看看服务,看看它是什么类型的。如果是LoadBalancer类型,则应确保已配置负载均衡器。如果所有pod都在运行,那么应用程序问题可能不是来自pod。以防万一,我们应该获取一个pod名称,以便在接下来的几个命令中对其进行更多检查。

5. kubectl lineage pod ${POD}

图片
lineage命令是另一个kubectl插件,它可以显示是什么在Kubernetes中创建了资源,以及什么依赖于它。若你曾经使用过kubectl tree,那么你熟悉lineage,但它有一些额外的功能。你可以使用kubectl krew install lineage来安装lineage插件。
关于这个命令,笔者最喜欢的一点是,它不仅显示Kubernetes资源,如集群中的ReplicaSets和服务,而且还显示事件、RBAC(基于角色的访问控制)、节点,并具有原生helm支持。默认情况下,该命令将显示依赖项,但使用–dependencies标志,你可以看到依赖于资源的东西。
你还可以查看metrics-server之类的服务,并查看所有ClusterRoleBinding以及服务背后的pod和节点。
图片
6.kail-l ${LABEL}
图片
上一个工作负载故障排除命令将根据标签显示工作负载的所有日志。kail是一个独立的工具,而不是kubectl插件,可与brew install boz/repo/kail一起安装。使其独立的好处是,它可以做一些通常使用单个kubectl命令很难做到的事情。
例如,你可以使用–ns从特定命名空间获取所有日志,或者使用–ing从入口规则后面获取所有pod。
图片
无法访问工作负载

123 kubectl get service o widekubectl get endpointslices o widekubectl portforward deploy $DEPLOYMENT $LOCAL_PORT:$POD_PORT

7. kubectl get service -o wide

图片
你应该首先查看集群中的服务,因为这是流量进出集群的主要方式。如果你使用入口进行流量路由,那么还需要使用kubectl get-o-wide。要检查的重要事项是它是什么类型的服务,是否有外部IP地址或负载均衡器,以及使用了什么标签。
根据我们从前面列出的工作负载中收集的数据,我们应该能够将pod上使用的标签与服务上匹配的标签进行比较。如果它们不匹配,它们就不会成为EndpointSlice的一部分。

8. kubectl get endpointslices -o wide

图片
接下来我们可以看的是EndpointSlices。这将向我们显示命名空间中的每个服务,以及哪些pod IP地址与该服务关联。如果看到没有任何端点的服务,则需要验证pod是否已准备就绪,标签是否匹配。

9. kubectl port-forward deploy/$DEPLOYMENT $LOCAL_PORT:$POD_PORT

图片
此命令将允许我们绕过负载平衡器或入口控制器,查看是否可以将流量直接发送到部署中的一个pod。如果怀疑pod有问题,你还可以将转发流量直接导到pod。这将帮助我们排除服务、负载均衡器和某些网络配置的错误,因为你的连接通过Kubernetes API服务器。
调试特定的POD
kubectl debug it image=debian $PODkubectl label pod $POD appkubectl blame pod
如果仍然没有解决问题,那么我们可以使用一些额外的命令来查看特定的pod,看看是否可以确定发生了什么。

10. kubectl debug pod –it –image=debian $POD

图片
debug命令要求在集群上启用临时容器。目前,这是Kubernetes 1.22的alpha特性,因此可能在你的集群中还不可用。

有时解决问题的最快方法是使用交互式shell。有几种不同的方法可以在运行的pod中获得shell,但调试是笔者最喜欢的。debug命令与exec不同,因为exec要求pod中已经安装了调试工具。但是,debug命令允许你指定一个新的容器,你可以将其“装载”到正在运行的pod中,然后带上自己的工具。
你可以为–image提供你想要的任何容器——不同的错误可能需要不同的工具。笔者通常有一个带有预装工具的专用调试容器,如果你没有,可以使用熟悉的完整发行版来安装所需的任何工具。使用临时容器调试某些东西的一个很酷的地方是,这也适用于FROM scratch构建的静态二进制容器,并且没有其他文件或包管理器。
debug命令还可用于获取节点上的交互式shell。这与SSHing到节点类似,但是debug命令在安装了工具的情况下以特权模式运行容器。如果你使用的是最小容器操作系统,或者没有在节点上配置SSH访问,那么这一点尤其有用。

11. kubectl label pod $POD app-

图片
这是笔者最喜欢的Kubernetes调试命令之一。默认情况下,部署将向pod添加标签,例如app=nginx。当你使用服务公开部署时,它也会在该标签上匹配。通过运行此命令,你将从pod中删除app标签。
因为复制控制器和服务对象匹配标签,所以一旦你删除app标签,新的pod将替换你从中删除标签的pod,但使你的pod保持运行。现在有了一个pod,可以进行故障排除,而不用担心发送生产流量,也不用担心pod会从水平pod自动缩放器放大或缩小。移除标签时,pod不会被有效跟踪。
在屏幕截图中,可以看到笔者从httpbin pod中删除了app标签,这导致在ReplicaSet中替换了一个新的pod,并留下旧的pod供调试。

12. kubectl blame pod $POD

图片
blame命令是一个很好的插件,你可以使用它来查看pod清单的哪些部分发生了更改,以及是谁或什么改变了它们。你可以使用kubectl krew install blame安装它。有了这个输出,你可以快速找出是什么控制器修改了清单,并可以查看这些组件以了解为什么它们会更改清单。
这里的输出不是完美的;它不会显示对清单的所有修改。由于webhook或默认值的原因,某些字段在存储到etcd之前会被修改。但是知道一个字段的更改频率以及哪些控制器正在修改清单中的哪些字段仍然非常有用。

原文链接:https://thenewstack.io/living-with-kubernetes-12-commands-to-debug-your-workloads/

  • 分享到:
  • icon
  • icon
  • icon
  • icon
箭头