1. 概述

在使用 Docker 时,有时我们需要检查容器内的配置或日志文件。

在这篇快速教程中,我们将学习如何检查 Docker 容器的文件系统,以解决此类情况。

2. 交互式探索

大多数情况下,如果我们能够获得容器的 shell 访问权限,我们可以互动式地探索其文件系统。

2.1. 使用 Docker 运行带有 shell 访问权限的容器

让我们使用 docker run 命令直接启动具有 shell 访问权限的容器:

运行带有 shell 访问权限的容器

这里,我们以交互模式启动 Alpine Linux 容器并连接到其 shell。

但是,如果我们要探索的不是直接基于 Linux 分发版的情况会怎样呢?

基于默认启动命令的容器

Cassandra Docker 容器附带默认启动命令,用于运行 Cassandra。因此,我们不再连接到 shell。

相反,我们只是看到应用程序的标准输出填充了日志消息。然而,我们可以通过以下方式绕过默认启动命令:

让我们将 /bin/bash 作为额外参数传递给 docker run 命令:

通过 `docker run` 命令启动 Bash shell

不幸的是,这种方法有一个副作用。实际上,Cassandra 应用程序不再启动,我们需要从 shell 手动执行。

当我们采用这种方法时,我们假设可以控制容器的启动。在生产环境中,这可能不可行。

2.2. 在运行的容器中启动 shell

幸运的是,我们可以使用 docker exec 命令连接到运行的容器,它允许我们访问运行的容器。

首先,我们启动要探索的容器:

启动要探索的容器

接着,我们使用 docker ps 查找容器 ID:

获取已停止容器的容器 ID

然后,我们使用 docker exec 命令将 /bin/bash 作为参数,并添加 -it 选项:

使用 `docker exec` 启动 Bash shell

在这里,我们选择了 Bash 作为首选的 shell。这可以根据容器所基于的 Linux 发行版而变化。

相比之下,我们的第一个示例使用 Alpine Linux,默认提供了 Bourne Shell:

默认提供 Bourne Shell 的 Alpine Linux

由于 Bash 不可用,我们使用 docker exec 命令将 /bin/sh 作为参数:

使用 `docker exec` 启动 sh shell

3. 非交互式探索

有时,容器已停止,我们无法进行互动式探索,或者它根本就没有 shell。

例如,hello-world 是一个 最小化容器,**从从 scratch 开始构建**。因此,无法获得 shell 访问权限。

幸好,在这两种情况下,我们都可以将容器文件系统导出到主机机器上进行进一步探索。

让我们看看如何实现这一点。

3.1. 导出文件系统

我们可以通过使用 docker export 命令将容器的文件系统导出到 .tar 文件。

首先,我们运行 hello-world 容器:

运行 hello-world 容器

同样,我们首先通过向 docker ps 添加 -a 标志来获取已停止容器的容器 ID:

获取已停止容器的容器 ID

然后,我们使用 docker export-o 选项将文件系统导出到 hello.tar 文件中:

使用 `docker export` 导出文件系统

最后,我们使用 tar 工具打印存档的内容,使用 -tvf 标志:

使用 `tar` 工具打印存档内容

或者,我们也可以使用任何归档浏览器查看内部内容。

3.2. 复制文件系统

我们还可以使用 docker cp 命令复制整个文件系统。

让我们也尝试一下这个方法。

首先,我们将从根目录(/)开始复制整个文件系统到容器中的 test 目录:

复制整个文件系统到 `test` 目录

接下来,让我们打印 test 目录的内容:

打印 `test` 目录的内容

4. 结论

在这篇快速教程中,我们讨论了如何探索 Docker 容器的文件系统。

大多数容器可以直接通过 docker run 命令启动并带有 shell 访问权限。此外,我们可以通过 docker exec 命令帮助在运行的容器中启动 shell。

对于已停止的容器或最小化容器,我们只需本地导出甚至复制整个文件系统即可。