从 Mac OS X 上的 Docker 层复制文件树

Copy out file tree from Docker layers on Mac OS X

我对 Docker 容器进行了一些本地更改并 commited 它们,现在正尝试在构建未来实例时复制它们。但是,事实证明很难检查进行了哪些具体更改。我知道包含更改的图层,但现有工具(例如 wagoodman/dive)不能很好地检测到此类更改。

图层存储在 /var/lib/docker/overlay2/ 中,但我在 Mac OSX 中,它不作为文字路径存在,必须通过连接到虚拟机才能访问容器中的文件系统。 ,但此方法以只读方式打开文件系统,并且缺少大多数工具:

docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh

我已经用它来验证图层看起来 大致 正如我预期的那样。为了更详细地查看,我想通过 docker cp 将文件树提取到我的工具所在的主文件系统。 nsenter 调用是 运行 作为容器 festive_lehmann,在那个会话中我在 /var/lib/docker/overlay2/be90015c1ff3efd16d145dc079edc78b5ee59f65b947b68c06b0c4885bbf9d84/diff/ 打开了 shell。但是,另一个会话中的 docker cp 会产生此错误:

$ docker cp festive_lehmann:/var/lib/docker/overlay2/be90015c1ff3efd16d145dc079edc78b5ee59f65b947b68c06b0c4885bbf9d84/diff/. ./diff/
Error: No such container:path: festive_lehmann:/var/lib/docker/overlay2/be90015c1ff3efd16d145dc079edc78b5ee59f65b947b68c06b0c4885bbf9d84/diff

我检查过这不是特定于复制目录的:

$ docker cp festive_lehmann:/var/lib/docker/overlay2/be90015c1ff3efd16d145dc079edc78b5ee59f65b947b68c06b0c4885bbf9d84/link .
Error: No such container:path: festive_lehmann:/var/lib/docker/overlay2/be90015c1ff3efd16d145dc079edc78b5ee59f65b947b68c06b0c4885bbf9d84/link

因为我确实在那个路径上打开了一个 shell,我认为这是容器无法正常操作的某种问题,同样的事情使得有必要使用奥术 nsenter 连接它的技巧。但是我其实并不理解那些技巧,相关的标志(-i-t--privileged--pid)也不是docker cp 接受。是否有正确的调用或解决方法?

docker cp 命令正在从容器命名空间内的容器文件系统复制。 nsenter 命令正在更改您的命名空间,因此您在 运行 来自 shell 的命令中不再看到容器文件系统。

如果您想查看这些更改,我的建议是使用 dive 工具,或者您可以使用 docker save 手动完成,将图像内容保存到 tar 包含 tar+gzip 层 blob 的文件。剖析该结构并不太困难,您会在顶部看到一个 json 文件,将您定向到每个层的名称,并且可以使用 tar 命令提取文件(例如tar -xzvf $blob_name -C $extract_dir).

另一种选择是启动如下命令:

docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i \
  tar -cf /var/lib/docker/overlay2/be90015c1ff3efd16d145dc079edc78b5ee59f65b947b68c06b0c4885bbf9d84/diff \
  | tar -xvf -