首页 > 云计算 > Docker/K8 > 如何进行 K8S Pod 内部调试?
调试运行中的容器和 Pod 不像直接调试进程那么容易,本文介绍了通过临时容器共享命名空间的方式调试业务容器进程的方法。
调试 pod 最简单的方法是在有问题的 pod 中执行命令,并尝试排除故障。这种方法很简单,但有许多缺点。
因此,我们需要探索其他调试 pod 的方法。
当 kubectl exec 不够用时(比如容器已经崩溃,或者容器镜像没有包含调试实用程序,比如 distroless 镜像),或者正在运行的 pod 没有调试所需的特权时,临时容器 ephemeral container 对于交互式故障排除非常有用。
临时容器背后的主要思想是,K8S 将具有选定自定义镜像的新容器添加到现有 pod 中,而不需要重新启动该 pod。这个新的容器可以共享目标容器的资源,包括:
Linux 网络命名空间
Linux 进程命名空间
访问共享卷
访问 K8S 节点
我将为每个用例提供一个示例。
在开始演示前,需要有一个版本为 1.23 的 k8s 集群,建议使用 kind,但也可以使用其他任何配置器。
我们从创建演示集群开始。
创建新集群很简单,只需运行命令 kind create cluster。

一旦创建了集群,需要验证是否启动并可访问。

所有操作都将从主kind节点执行,所以需要通过 docker exec -it bash 访问。

kubectl create deployment nginx --image=nginx

nicolaka/netshoot
作为新的临时容器的镜像,该镜像包含许多故障排除工具,如
tcpdump
和
strace
。kubectl debug -it pod-name --image=<ephemeral-container> -- command

systemd-cgls -u kubelet-kubepods-besteffort.slice


tcpdump -n port 80
现在,试着从 k8s 主节点向这个 pod 发送一些请求。
curl

现在观察临时容器终端,会发现 TCP 报文会被打印出来:

第一个演示完成,现在我们可以从临时容器捕获网络数据包了。
接下来看第二个用例。
SYS_PTRACE
--target <container-name>
,可以轻松共享 Linux 进程命名空间。kubectl debug -it <pod-name > --image=nicolaka/netshoot --target <container-name> -- bash

curl -v -XPATCH -H "Content-Type: application/json-patch+json" \'\--data-binary @- << EOF[{"op": "add", "path": "/spec/ephemeralContainers/-","value": {"command":[ "/bin/sh" ],"stdin": true, "tty": true,"image": "nicolaka/netshoot","name": "debug-strace","securityContext": {"capabilities": {"add": ["SYS_PTRACE"]}},"targetContainerName": "nginx" }}]EOF
现在可以在权限不被拒绝的情况下调用
strace
。

SYS_PTRACE
的权限,但具体给什么权限取决于所用的调试器,或者简单点可以给临时容器特权访问,从而不需要担心需要允许哪个系统调用。
/proc/<process-id>/root
目录下。
nginx
配置。

好了,接下来我们看一下临时容器的最后一个用例。
kubectl debug node/<node-name> -it --image=<image-name>
kubectl debug
会根据节点名称自动生成新 Pod 的名称。
/host
上。
chroot /host
。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70013542/viewspace-2939257/ ,如需转载,请注明出处,否则将追究法律责任。