https://zhuanlan.zhihu.com/p/410217354
作为 Kubernetes 管理员,我经常发现自己需要调试应用程序和系统问题。我遇到的大多数问题都可以通过 Grafana 仪表板和 Prometheus 指标解决,或者通过运行一个或多个 Elasticsearch 查询来检查日志。但有时我需要更深入地检查正在运行的 Pod 内的活动。许多调试指南使用 kubectl exec 命令在容器内运行一个或多个命令:
$ kubectl exec -it container-XXXX dig @10.10.0.1 google.com
但是如果容器中没有安装 shell 会发生什么?或者,如果您的容器以非特权用户身份运行(应该如此),并且未安装调试问题所需的工具,该怎么办?如果您没有 root,那么安装实用程序有点困难,而且它会破坏临时基础设施的全部意义。在这些情况下,Linux nsenter 命令将成为您最好的朋友!
如果您不熟悉 nsenter,它允许您在给定的命名空间中运行程序。因此,假设您在 Kubernetes 集群中运行了一个微服务,并且您的开发人员告诉您 DNS 解析无法正常工作。要使用 nsenter 调试此问题,您可以访问运行服务的主机,并使用“-t”(进程到目标)和“-n”(进入网络命名空间)选项执行 nsenter。最后一个参数是在进程网络命名空间中运行的命令:
$ nsenter -t 1294 -n dig +short @10.11.2.2 *.*.svc.cluster.local
10.10.0.10
10.10.0.1
在上面的示例中,nsenter 再次运行 dig 命令获取集群 DNS 服务 IP。它还使用驻留在主机文件系统上的 dig 二进制文件,而不是容器。当您需要捕获进出容器的流量时,Nsenter 也非常有用:
$ nsenter -t 1294 -n tcpdump -i eth0 port 80 and "tcp[tcpflags] & tcp-syn != 0"
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
06:04:20.424938 IP 10.11.2.1.39168 > 10.11.2.3.80: Flags [S], seq 1491800784, win 29200, options [mss 1460,sackOK,TS val 59669904 ecr 0,nop,wscale 7], length 0
06:04:20.425000 IP 10.11.2.3.80 > 10.11.2.1.39168: Flags [S.], seq 3823341284, ack 1491800785, win 28960, options [mss 1460,sackOK,TS val 59669904 ecr 59669904,nop,wscale 7], length 0
在上面的示例中,nsenter 在进程 ID 1294 的命名空间内执行了 tcpdump 实用程序。使这个超级强大的原因在于,您可以使用运行应用程序所需的最少位数来运行容器,并且您的应用程序也可以作为非特权用户运行。当您需要调试问题时,您无需接触容器。您只需在 Kubernetes worker 上启动二进制文件并进行调试即可。