docker:从图像中提取图层

时间:2016-11-13 15:52:59

标签: docker

让我们以鲸鱼图像为例。 docker history显示以下内容:

IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
6b362a9f73eb        17 months ago       /bin/sh -c #(nop) ENV PATH=/usr/local/bin:/us   0 B
<missing>           17 months ago       /bin/sh -c sh install.sh                        30.37 kB
<missing>           17 months ago       /bin/sh -c git reset --hard origin/master       43.27 kB
<missing>           17 months ago       /bin/sh -c #(nop) WORKDIR /cowsay               0 B
<missing>           17 months ago       /bin/sh -c git clone https://github.com/moxie   89.9 kB
<missing>           17 months ago       /bin/sh -c apt-get -y update && apt-get insta   58.58 MB
<missing>           18 months ago       /bin/sh -c #(nop) CMD ["/bin/bash"]             0 B
<missing>           18 months ago       /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$/   1.895 kB
<missing>           18 months ago       /bin/sh -c echo '#!/bin/sh' > /usr/sbin/polic   194.5 kB
<missing>           18 months ago       /bin/sh -c #(nop) ADD file:f4d7b4b3402b5c53f2   188.1 MB

我想提取显示ADD file:bla的图层。有这样的工具/方式吗?

5 个答案:

答案 0 :(得分:8)

看起来其他人也希望拥有此功能,但不幸的是,它现在似乎并不存在。

另见 this issue 在这里 related request 被拒绝了。

如果您保存完整的泊坞窗(docker save),然后使用图层提取压缩包,那么这很可能:

docker run -it <your image>
# do fancy stuff in the container
docker commit <your container> foobar # create image from container
docker history foobar # will show you the layers
docker save -o foobar.tar foobar # dumps container contents to foobar.tar

现在foobar.tar将包含来自不同时间的文件系统状态。在我的例子中,检查此tarball会显示带有

的文件repositories
{"foobar":{"latest":"fdf43d96e691c57e9afb4b85dba2e6745146a7ca9076c7284c6b2e1f93434562"}}

表示最新图层为fdf43...。您可以通过

获取该层的文件系统内容的tarball
tar -x fdf43d96e691c57e9afb4b85dba2e6745146a7ca9076c7284c6b2e1f93434562/layer.tar -f foobar.tar

有一个工具, undocker, 这使该过程自动化,但我不确定它是否可以使用保存的tar文件的当前格式。

答案 1 :(得分:8)

在这种特定情况下,看起来ADD命令将基本映像添加到文件系统。如果您运行docker history --no-trunc docker/whalesay,则完整命令为:

/bin/sh -c #(nop) ADD file:f4d7b4b3402b5c53f266bb7fdd7e728493d9a17f9ef20c8cb1b4759b6e66b70f in /

docker history报告特定图层为188MB。让我们更详细地看一下这些层:

$ docker save docker/whalesay -o whalesay.tar
$ tar tvf whalesay.tar

...
-rw-r--r-- 0/0       197181952 2015-05-25 22:04 cc88f763e297503d2407d6b462b2b390a6fd006b30f51c8efa03dd88fa801b89/layer.tar
...

看起来像个不错的候选人!您现在可以提取该图层并从中提取文件。

$ tar xf whalesay.tar cc88f763e297503d2407d6b462b2b390a6fd006b30f51c8efa03dd88fa801b89/layer.tar
$ tar xf cc88f763e297503d2407d6b462b2b390a6fd006b30f51c8efa03dd88fa801b89/layer.tar etc/passwd

如果您想要从图层中提取特定文件,但是您不知道哪个图层,则可以执行此操作。首先,提取所有层:

$ tar xf whalesay.tar

现在你已经将所有图层作为单独的.tar文件。我们找一个文件:

$ for layer in */layer.tar; do tar -tf $layer | grep docker.cow && echo $layer; done
usr/local/share/cows/docker.cow
0523c5a0c4588dde33d61d171c41c2dc5c829db359f4d56ab896ab1c185ed936/layer.tar
cowsay/cows/docker.cow
40e8ae7bb4e5b9eaac56f5be7aa614ed50f163020c87ba59e905e01ef0af0a4f/layer.tar
cowsay/cows/docker.cow
f9bc8676543761ff3033813257937aeb77e9bc84296eaf025e27fe01643927cf/layer.tar

最后,从所需的图层中提取文件:

$ tar xf 0523c5a0c4588dde33d61d171c41c2dc5c829db359f4d56ab896ab1c185ed936/layer.tar \
      usr/local/share/cows/docker.cow

这将使用相对于当前目录的完整路径提取该文件。

$ cat usr/local/share/cows/docker.cow 
##
## Docker Cow
##
$the_cow = <<EOC;
    $thoughts
     $thoughts
      $thoughts     
                    ##        .            
              ## ## ##       ==            
           ## ## ## ##      ===            
       /""""""""""""""""\___/ ===        
  ~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===- ~~~   
       \\______ o          __/            
        \\    \\        __/             
          \\____\\______/   
EOC

答案 2 :(得分:1)

我真的不明白“提取”是什么意思,但是如果你想获得有关图像的更多信息,请运行

docker inspect <image_name>

您想要获取文件,然后从此图像运行容器。试试

docker export <container_name> > abc.tar

之后,提取 abc.tar并找到您的文件。

答案 3 :(得分:0)

Docker无法单独保存图层,但是Github上有一个名为dlgrab的工具声称可以做到这一点。 https://github.com/aidanhs/dlgrab

答案 4 :(得分:0)

虽然无法提取特定的图层,但使docker-save-last-layer命令行实用程序仅提取最后一层。与docker build --squash结合使用,可以避免导出基础层。这可能有助于实现您的目标。

它通过在可访问您主机上的映像的docker映像中使用docker守护程序的修补版本来工作。因此,在使用前不需要进行完整的docker save处理。这使得它对于大型基础图像而言表现出色。

典型用法很简单,看起来像:

pip install d-save-last

docker build --t myimage --squash .
d-save-last myimage -o ./myimage.tar