这篇内容主要探讨了 Kube.NETes 的调试功能,介绍了 kubectl debug 和 kubectl superdebug。它们支持容器挂载并且能够调试一些需要排查问题的 Pod。文章指出了在 Kubernetes 中使用 kubectl exec 命令的限制,并介绍了 kubectl debug 的作用,它能创建一个新的容器来调试运行中的容器,并且能够在同一个 Pod 内共享系统资源。此外,还提到了 ephemeral contAIners,它们在调试过程中可以临时运行在现有的 Pod 中,支持一些排查操作。最后,文章还提及了一些非 Kubernetes 本地调试容器的方法,包括使用 Docker Engine 或者一些基于 linux namespaces 的工具。
如果你在 Kubernetes 上运行软件,你有时会想要调试所部署的应用。对于习惯使用虚拟机的人来说,一种简单的调试方法是连接到正在运行的 Pod 并进行分享:
kubectl exec -it podname -c containername -- bash
这通常有效并且非常有用。然而,至少有两个 Kubernetes“最佳实践”限制了 exec 在现实世界中的用处:
• 不以 root 身份运行。容器以尽可能少的权限运行,甚至可以使用随机 UID 运行。
• 最小镜像。镜像尽可能小,极端情况下将二进制文件安装到distroless 镜像中。[1]
当应用这些最佳实践时,使用kubectl exec连接到容器要么是不可能的,要么会让你陷入不适合调试的贫瘠荒地般的环境。
调试正在运行的容器的 Kubernetes 原生答案是使用kubectl debug。
debug 命令将一个新容器附加到正在运行的 pod 中。这个新容器可以以不同的用户身份从你选择的任何镜像运行。由于调试容器与其目标容器在同一 Pod 中运行(因此在同一节点上),因此两个容器之间的隔离不需要是绝对的。调试容器可以与同一 Pod 中运行的其他容器共享系统资源。
考虑要检查pod容器postpod中运行的 PostgreSQL 数据库的 CPU 使用情况。Pod 不以 root 身份运行,并且 Postgres 镜像没有类似top或htop安装的工具——换句话说,该kubectl exec命令没什么用处。你可以运行以下命令:
kubectl debug -it
--container=debug-container
--image=alpine
--target=postcont
postpod
你将以 root 身份登录(这是 Alpine 镜像的默认设置),并且可以轻松安装你最喜欢的交互式进程查看器 htop ( apt add htop)。你与容器postcont共享相同的进程命名空间,并且可以查看甚至杀死在那里运行的所有进程!当你退出该进程时,临时容器也将停止存在。
注意:你可以通过按 CTRL+P 或 CTRL+D 断开与临时容器/bash 会话的连接,而无需退出(终止)它。然后你可以稍后使用 重新连接到它kubectl attach。
注意:kubectl debug提供的功能比此处概述的更多,例如使用修改后的启动命令复制 Pod 或启动可访问节点文件系统的“节点”Pod。
上面的命令kubectl debug通过创建一个称为临时容器[2]东西来工作。这些容器应该在现有Pod 中临时运行,以支持故障排除等操作。
“普通”容器和临时容器之间的区别很小。没有什么能真正阻止临时容器长期运行。我认为,通过查看 Kubernetes 在诞生之初所做的基础架构选择,可以最好地理解拥有临时容器的原因:
• Pod 应该是一次性且可更换的,并且支持这一点,
• Pod 规范是不可变的。
当 Kubernetes 主要用于部署无状态工作负载时(当 Pod 本身可以被认为是短暂的)时,这非常有意义。在这个 Kubernetes无所不能的新世界中,它可能会受到限制。Pod 规范保持不变,但 Kubernetes 将临时容器建模为Pod 的子资源。与“普通”容器不同,临时容器不是 Pod规范的一部分,即使它们是 pod 的一部分。这种微妙的区别让每个人都高兴