如果您经常使用容器,那么在某些时候您可能想要查看正在运行的容器的文件系统。也许容器行为不正常,你想阅读一些日志,也许你想检查容器内的一些配置文件......或者,也许,像我一样,你想在该容器中的二进制文件上放置一些eBPF探测器(稍后详细说明)。不管是什么原因,在这篇文章中,我们将介绍一些可用于检查容器中文件的方法。我们将从查看容器文件系统的简单且通常推荐的方法开始,并讨论为什么它们并不总是有效。接下来,我们将对Linux内核如何管理容器文件系统有一个基本的了解,我们将使用它以一种不同但仍然简单的方式检查文件系统。方法1:执行到容器中如果您快速搜索一下如何检查容器的文件系统,您会发现一个常见的解决方案是使用Docker命令:dockerexec-itmycontainer/bin/bash这是一个很好的起点.如果它满足您的所有需求,您应该继续使用它。然而,这种方法的一个缺点是它需要容器内存在一个外壳。如果容器中没有/bin/bash、/bin/sh或其他shell,此方法将不起作用。例如,我们为Pixie项目构建的许多容器都是基于distroless的,并且不包含用于保持图像较小的shell。在这些情况下,这种方法不起作用。即使shell可用,您也无法访问您习惯使用的所有工具。因此,如果容器中没有安装grep,那么你也无法访问grep。这是寻找更好工作的另一个原因。方法二:使用nsenter如果深入研究,您会发现容器进程与Linux主机上的任何其他进程一样,但在命名空间中运行以将它们与系统的其余部分隔离开来。所以你可以使用nsenter命令进入目标容器的命名空间,使用类似这样的东西:#GetthehostPIDoftheprocessinthecontainerPID=$(dockercontainerinspectmycontainer|jq'.[0].State.Pid')#Usensentertogointothecontainer'smountnamespace.sudonsenter-m-t$PID/bin/bash进入目标进程的挂载(-m)命名空间(-t$PID),运行/bin/bash。进入挂载命名空间本质上意味着我们获得了容器所见的文件系统视图。这种方法似乎比docker的exec方法更有前途,但也有类似的问题:它需要将/bin/bash(或其他shell)包含在目标容器中。如果我们输入的不是挂载命名空间,我们仍然可以访问主机上的文件,但是因为我们在执行/bin/bash(或其他shell)之前进入挂载命名空间,如果挂载命名空间中没有shell,我们是倒霉。方法三:使用dockercopy解决这个问题的另一种方法是简单地将相关文件复制到宿主机上,然后使用复制的文件。要从正在运行的容器中复制选定的文件,您可以使用:dockercpmycontainer:/path/to/filefile您还可以使用以下方法对整个文件系统进行快照:dockerexportmycontainer-ocontainer_fs.tar这些命令使您可以在容器运行时检查文件当您可能没有shell或您需要的工具时,这些命令是对前两种方法的巨大改进。方法四:查找主机上的文件系统复制方法解决了我们的许多问题,但是如果您要监视日志文件怎么办?或者,如果您尝试将eBPF探测器部署到容器中的文件怎么办?在这些情况下,复制将不起作用。我们想直接从主机访问容器的文件系统。容器的文件应该在主机的文件系统中,但是在哪里呢?Docker的检查命令给了我们一个线索:dockercontainerinspectmycontainer|jq'.[0].GraphDriver'这给了我们:{"Data":{"LowerDir":"/var/lib/docker/overlay2/63ec1a08b063c0226141a9071b5df7958880aae6be5dc9870aff179it/ab3:/var/lib/docker/overlay2/524a0d000817a3c20c5d32b79c6153aea545ced8eed7b78ca25e0d74c97efc0d/diff","MergedDir":"/var/lib/docker/overlay2/63ec1a08b063c0226141a9071b5df7958880aae6be5dc9870a279a13ff7134ab/merged","UpperDir":"/var/lib/docker/overlay2/63ec1a08b063c0226141a9071b5df7958880aae6be5dc9870a279a13ff7134ab/diff","WorkDir":"/var/lib/docker/overlay2/63ec1a08b063c0226141a9071b5df7958880aae6be5dc9870a279a13ff7134ab/work"},"Name":"overlay2"}我们来分析一下:LowerDir:包含容器中所有层的文件系统,最后一层除了UpperDir:最上层容器的文件系统。这也是反映任何运行时修改的地方。MergedDir:文件系统所有层的组合视图。WorkDir:用于管理文件系统的内部工作目录。基于overlayfs的容器文件系统结构。因此,要查看容器中的文件,只需查看MergedDir路径即可。sudols/var/lib/docker/overlay2/63ec1a08b063c0226141a9071b5df7958880aae6be5dc9870a279a13ff7134ab/merged如果您想了解有关文件系统如何工作的更多详细信息,可以查看MartinHeinz关于覆盖文件系统的博客文章:https://martinheinz.dev/blog/44。方法五:/proc/
