Docker: extracting a layer from an image

Take whale images as an example. docker history shows the following:

 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 

I would like to extract a layer that says ADD file:bla . Is there any way / way to do this?

+8
source share
5 answers

It seems that other people would also like to have this feature, but unfortunately now it does not seem to exist.

See also this question and here is the related request which was rejected.

If it’s good for you to save the full docker save and then extract the tarball with your layer, then this is possible:

 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 

Now foobar.tar will contain file system states from different times. Checking this tarball shows, in my case, the repositories file with

 {"foobar":{"latest":"fdf43d96e691c57e9afb4b85dba2e6745146a7ca9076c7284c6b2e1f93434562"}} 

which indicates that the last level is fdf43... You can get tarball with the contents of this level file system with

 tar -x fdf43d96e691c57e9afb4b85dba2e6745146a7ca9076c7284c6b2e1f93434562/layer.tar -f foobar.tar 

There is a detach tool that automated this process, but I'm not sure if it will work with the current format of the saved tar file.

+8
source

In this particular case, it looks like the ADD command has added the base image to the file system. If you run docker history --no-trunc docker/whalesay , the full command:

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

docker history reports that the specific tier is 188 MB. Let's look at these layers in more detail:

 $ 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 ... 

Looks like a pretty good candidate! Now you can extract this layer and pull the files out of it.

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

If you want to pull a specific file from a layer, but you don’t know which layer, you can do it. First, extract all the layers:

 $ tar xf whalesay.tar 

Now you have all the layers as separate .tar files. Find the file:

 $ 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 

Finally, extract the file from the desired layer:

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

This will extract the file with the full path relative to the current directory.

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

I really don't understand what you mean by "extract", but if you want more information about the image, run

 docker inspect <image_name> 

You want to get the file, then run the container from this image. Try

 docker export <container_name> > abc.tar 

After that, extract abc.tar and find the file.

+1
source

Docker is not capable of storing layers separately, however on Github there is a dlgrab tool that claims to do this. https://github.com/aidanhs/dlgrab

0
source

The docker-save-last-layer command-line utility is not intended to extract a specific level, but is intended to extract only the last level. In combination with docker build --squash you can avoid exporting base layers. This can help achieve your goals.

It works using a fixed version of the docker daemon inside the docker image, which can access images on your host machine. Thus, it does not require a full docker save before using it. This makes it effective for large base images.

Typical use is simple and looks like this:

 pip install d-save-last docker build --t myimage --squash . d-save-last myimage -o ./myimage.tar 
0
source

Source: https://habr.com/ru/post/1259688/


All Articles