2021-05-08 image difference between docker save and docker export

Posted by ted_chou12 on Thu, 17 Feb 2022 15:11:54 +0100

The difference between docker save and docker export

origin

 

Both docker save and docker export can export image packages. At first glance, there seems to be little difference. Aiming at this problem, this paper tries to find out what the functions of docker save and docker export are? What application scenarios are applicable?

*Note: users can use docker load to import image storage files to the local image library, or docker import to import a container snapshot to the local image library. The difference between the two is that the container snapshot file will discard all history and metadata information (that is, only the snapshot state of the container at that time), while the mirror storage file will save the complete record and have a large volume. In addition, metadata information such as labels can be reassigned when importing from the container snapshot file.

The docker versions tested in this article are as follows. It is not guaranteed that all versions of docker can reproduce the results of this article.

>docker version
 
Client:
 Version:      17.07.0-ce-rc1
 API version:  1.31
 Go version:   go1.8.3
 Git commit:   8c4be39
 Built:        Wed Jul 26 05:19:44 2017
 OS/Arch:      windows/amd64
 
Server:
 Version:      17.07.0-ce-rc1
 API version:  1.31 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   8c4be39
 Built:        Wed Jul 26 05:25:01 2017
 OS/Arch:      linux/amd64
 Experimental: true
Besides, I'm Windows on bash Inside operation docker,Some commands such aslsNot at all windows Command, if you want to repeat my experiment, please change to the corresponding one windows Command.

docker save

The command line interface of docker is designed elegantly. You can view the help of many commands directly by adding -- help.

The help of docker save is as follows:

>docker save --help
 
Usage:  docker save [OPTIONS] IMAGE [IMAGE...]
 
Save one or more images to a tar archive (streamed to STDOUT by default)
 
Options:
      --help            Print usage
  -o, --output string   Write to a file, instead of STDOUT

As can be seen from the command line help, docker save is a tool used to package and save one or more image s.

For example, if we want to package postgres and mongo in the image library, we can execute:

docker save -o images.tar postgres:9.6 mongo:3.4

Packaged images Tar contains two images: postgres:9.6 and mongo:3.4.

Although the command line parameter requires that image be specified, the container can also be packaged, for example:

>docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
3623943d369f        postgres:9.6        "docker-entrypoint..."   3 hours ago         Up 3 hours          5432/tcp            postgres
 
>docker save -o b.tar postgres
>docker save -o c.tar postgres:9.6
>ls -al
-rwxrwxrwx 1 root root 277886464 8 June 26-14:40 b.tar
-rwxrwxrwx 1 root root 277886464 8 June 26-14:41 c.tar

As like as two peas, you can see that b.tar and c.tar are exactly the same. This shows that if docker save specifies container, docker save will save the image behind the container.

Load the packaged image and use docker load, for example:

docker load -i images.tar

The above command will load postgres:9.6 and mongo:3.4. If these two images already exist in the local image library, they will be overwritten.

The application scenario of docker save is if your application uses docker compose Multiple image combinations arranged by YML, but the client server you want to deploy cannot be connected to the Internet. At this time, you can use docker save to package the images used, then copy them to the client server and load them with docker load.

docker export

Check the help of docker export as usual:

>docker export --help
 
Usage:  docker export [OPTIONS] CONTAINER
 
Export a container's filesystem as a tar archive
 
Options:
      --help            Print usage
  -o, --output string   Write to a file, instead of STDOUT

As can be seen from the help, docker export is used to package the file system of the container. For example:

docker export -o postgres-export.tar postgres

Container must be specified for docker export, but neither image nor container can be specified like docker save.

Load the packaged container and use docker import, for example:

docker import postgres-export.tar postgres:latest

As can be seen from the above command, the container imported by docker import will become an image instead of being restored to a container.

Another point is that docker import can specify IMAGE[:TAG], indicating that we can specify a new name for the image. If an image with the same name already exists in the local image library, the name of the original image will be stripped and assigned to the new image. The operation can only be performed through the original IMAGE ID.

The application scenario of docker export is mainly used to create a basic image. For example, you start a container from a ubuntu image, install some software and make some settings, and then use docker export to save it as a basic image. Then, distribute the image to others, such as the basic development environment.

The difference between docker save and docker export

Summarize the difference between docker save and docker export:

  1. docker save saves the image and docker export saves the container;
  2. docker load is used to load the image package and docker import is used to load the container package, but both will be restored to the image;
  3. docker load cannot rename the loaded image, while docker import can specify a new name for the image.

Brain hole

The contents mentioned above are all basic knowledge. I believe readers can know as long as they carefully look at the official documents. In this section, I'll talk about what's not on the document.

Both docker load and docker import can import tar packages as images. I can't help wondering whether docker load can import the container package of docker export and docker import can import the image package of docker save?

Start the test and prepare the following two documents:

>ls -al
-rwxrwxrwx 1 root root 271760384 8 December 26:15 postgres-export.tar
-rwxrwxrwx 1 root root 398292480 8 December 26:13 postgres-save.tar

Postgres export Tar is the container package exported through docker export, Postgres save Tar is the image package saved through docker save, both of which are based on postgres:9.6 image. From the file size, you can intuitively find that Postgres export Tar is obviously better than Postgres save Tar is less than 100 M.

Now try the docker load container package Postgres export tar:

>docker load -i postgres-export.tar
open /var/lib/docker/tmp/docker-import-082344818/bin/json: no such file or directory

Obviously, docker load cannot load container packages.

So, conversely, can docker import load the image package?

>docker import postgres-save.tar postgres
sha256:8910feec1ee2fac8c152dbdd0aaab360ba0b833af5c3ad59fcd648b9a24d4838
>docker image ls
REPOSITORY                                      TAG                 IMAGE ID            CREATED             SIZE
postgres                                        latest              8910feec1ee2        2 minutes ago       398MB

WTF, it succeeded!!!

Don't panic. Try starting a postgres container again:

>docker run postgres
C:\Program Files\Docker\Docker\resources\bin\docker.exe: Error response from daemon: No command specified.
See 'C:\Program Files\Docker\Docker\resources\bin\docker.exe run --help'.

Although it can be successfully imported as an image, this image cannot be used.

To find out what's going on, let's first look at the difference between image package and container package:

From the above, you can see the Postgres export on the right The content of tar is a file directory of linux system. I guess it is a linux image. And Postgres save What's in tar? Click a folder to see:

It's actually a layered file system. Docker image is actually superimposed by such layers of files. The files in the upper layer will overwrite the files with the same name in the lower layer. If Postgres save All layers of files in tar are merged together, basically Postgres export Contents of tar. Due to Postgres save There are many duplicate files in the layers of tar, which also explains why Postgres save Tar is better than Postgres export Tar is more than 100 M.

docker load must load a hierarchical file system, and Postgres export Tar does not have such a structure and cannot be loaded.

docker import only copies the files in the tar package, so no matter what the file structure in the tar package is, it can be loaded in, so it can be loaded into Postgres save tar. But Postgres save Tar is not a valid operating system image, so when I try to start the container with a changed image, the container does not start.

Let's take a look at the help of docker import:

Usage:  docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
 
Import the contents from a tarball to create a filesystem image
 
Options:
  -c, --change list      Apply Dockerfile instruction to the created image
      --help             Print usage
  -m, --message string   Set commit message for imported image

It seems to be similar to docker commit:

Usage:  docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
 
Create a new image from a container's changes
Options:
  -a, --author string    Author (e.g., "John Hannibal Smith
                         <hannibal@a-team.com>")
  -c, --change list      Apply Dockerfile instruction to the created image
      --help             Print usage
  -m, --message string   Commit message
  -p, --pause            Pause container during commit (default true)

It is found that both docker import and docker commit have -- change and -- message options. We can understand docker import as copying external files to form an image with only one layer of file system, while docker commit is to submit the current changes to one layer of file system and then superimpose them on the original image.

Topics: Docker export