从Docker映像中提取文件?


24

我想从Docker映像中提取文件,而不必运行该映像。

docker save对于我来说,该选项不是当前可行的选项,因为它节省了太多文件,仅用于解压缩特定文件。


您正在使用什么发行版?
ryekayo

@ryekayo:Ubuntu 14,docker 1.12.4(api 1.24)
BlakBat

Answers:


21

您可以使用以下命令从图像中提取文件:

docker create $image  # returns container ID
docker cp $container_id:$source_path $destination_path
docker rm $container_id

根据docker create 文档,这不会运行容器:

docker create命令将在指定图像上创建可写容器层,并为运行指定命令做准备。然后将容器ID打印到STDOUT。这与docker run -d从未启动容器的情况相似。然后,您可以随时使用docker start <container_id>命令启动容器。


作为参考(我以前的回答),从图像中提取文件的效率较低的方法如下:

docker run some_image cat $file_path > $output_path

3
您可能想要超越入口点。docker run --entrypoint /bin/sh my_image -c /bin/cat some_file
安德鲁

1
这将运行图像,这正是我不想在问题中提到的内容。
BlakBat

嗯,这是一个好点。我同意当时的当前答案并不令人满意。
英国广播公司

1
@BlakBat此更新的答案对您有用吗?我想我应该已经创建了一个新答案,但是现在已经完成了。
英国广播公司

1
@bbc实际上,此更新的答案不会启动容器(问题的症结所在),并且不需要是root用户。
BlakBat

2

以上都不对我有用。完整的工作命令是:

docker run --rm --entrypoint /bin/sh image_name -c "cat /path/filename" > output_filename

不带引号cat的传递不带文件名,因此它不知道显示什么。在命令完成后删除容器也是一个好主意。


您所指的命令将仅根据Docker以及在Dockerfile中设置ENTRYPOINT / CMD的正确程度而起作用;这与报价无关。您还说要删除容器,但您指定--rm。最后,当我发布问题时,我指定了“无需运行图像”,并且没有答案可以解决。
BlakBat

1
无论在Dockerfile中设置了哪个CMD和ENTRYPOINT,我都会覆盖它们两者,因此它将始终有效(当然在Linux上)。“依靠码头工人”是什么意思?设置,版本,env,什么?您的问题是不正确的,因为无法执行图像,只有容器可以执行。我认为没有正确的答案,您必须处理许多文件或创建一个临时容器。--rm删除临时容器,其他答案在磁盘上留下一些垃圾。
sekrett

1

如果我没记错的话,我相信Docker容器确实会存储在以下目录中为Ubuntu创建的缓存文件:

/var/lib/docker/aufs/diff/<container_id>

从那里,您应该能够访问文件系统并检索您的文件。


不。该目录仅包含layersizejson,并且用户也不可读(即使用户在docker组中)。/var/lib/docker/aufs/diff将包含我要查找的文件(但未按容器ID进行分类),并且也不可读。
BlakBat

给我一些,我会查一下。我知道一个事实,有一种方法可以检索文件而无需进入容器或运行它。
ryekayo

通过不可读,它如何显示?我找到了一个示例,您可以通过转到/ var / lib /
docker

我的错。用户可以访问/var/lib/docker/aufs(但不能访问中的所有其他目录/var/lib/docker/
BlakBat

您可以以root身份访问吗?
ryekayo,2016年

0

如果docker save无法存储的完整输出,则可以使用管道从中提取所需的文件。

不幸的是,由于输出是“焦油焦油”,因此它可能是一个稍微迭代的过程。

我刚才需要提取文件时做的是:

1)确定您感兴趣的文件最近更改过的图像版本(此操作可能取决于图像)以及创建/保存的日期

2)使用以下docker save命令从命令的输出中获取完整的目录:

docker save IMAGE_NAME | tar -tvf -

3)layer.tar在该命令的输出中对与您在步骤1中确定的图像的日期相匹配的| grep layer.tar文件进行细化。(可以添加以仅显示这些文件)

4)将该layer.tar文件提取到标准输出中,并获取其目录:

docker save IMAGE_NAME | tar -xf - -O CHECKSUM_FROM_LIST/layer.tar | tar -tvf -

5)确认列出了所需文件,并在找到名称后将其解压缩:

docker save IMAGE_NAME | tar -xf - -O CHECKSUM_FROM_LIST/layer.tar | tar -xf - PATH/TO/YOUR/FILE

如果layer.tar在步骤2/3中有多个文件与您要查找的日期相匹配,则可能需要对每个文件重复步骤4,直到找到正确的文件为止。

用您的情况的正确图像名称,校验和和文件名替换上述命令中大写字母的文本。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.