Mp.weixin.qq.com/s/yOJZyUBdX…


This article is intended to help you understand Docker commands, the difference between a container and an image, and the difference between a container and a running container.

I found it very difficult to understand Docker commands when I was still half-understanding Docker technology. So I spent a couple of weeks learning how Docker works — or, more specifically, the Union File System — and then looking back at Docker’s commands, it all made perfect sense.

As an aside: Personally, the best way to master a technology and use it wisely is to have a deep understanding of how it works. Often, the launch of a new technology is accompanied by media hype and hype, which makes it difficult for users to see the nature of the technology. Rather, new technologies often invent new terms or metaphors to help spread the word, which is very helpful in the early stages, but it sandpaper the principles of the technology and makes it difficult for users to grasp the true meaning of the technology later.

Git is a good example. I couldn’t use Git very well before, so it took me a while to learn how Git works, and only then did I really understand how Git works. I firmly believe that only those who truly understand the inner workings of Git can master the tool.

Image Definition

An Image is a unified view of a bunch of read-only layers. If this definition is a little confusing, the following Image will help you understand the definition of an Image.

On the left we see multiple read-only layers stacked on top of each other. All but the lowest layer will have a pointer to the next layer. These layers are the implementation details inside Docker and can be accessed from the file system on the host. The Union File System technology is able to consolidate different layers into a single file system, providing a unified view of these layers, thus hiding the existence of multiple layers and, from the user’s perspective, only one file system. We can see the form of this perspective on the right side of the image.

You can find files for these layers on your host file system. Note that these layers are not visible inside a running container. On my host, I found them in /var/lib/docker-aufs.

sudo tree -L 1 /var/lib/docker/

The/var/lib/docker / ├ ─ ─ aufs ├ ─ ─ containers ├ ─ ─ graph ├ ─ ─ init ├ ─ ─ linkgraph. Db ├ ─ ─ repositories - aufs ├ ─ ─ TMP ├ ─ ─ trust └ ─ ─ volumes7  directories, 2 filesCopy the code

Container Definition

A container is almost exactly the same as an image, a unified view of a bunch of layers, the only difference being that the top layer of the container is readable and writable.

Careful readers may notice that the definition of a container makes no mention of whether the container is running, and yes, that’s intentional. It was this discovery that helped me understand a lot of the confusion.

Important: Container = image + readable layer. And the definition of the container does not say whether to run the container.

Next, we’ll talk about running containers.

Running Container Definition

A running container is defined as a unified file system that can be read and written, with separate process Spaces and processes contained within. The image below shows a container in action.

File system isolation is what makes Docker such a promising technology. A process in a container may modify, delete, or create files, and these changes apply to the Read-write layer. The graph below illustrates this behavior.

We can verify what we said above by running the following command:

docker run ubuntu touch happiness.txtCopy the code

Even if the Ubuntu container is no longer running, we can still find the new file on the host’s file system.

find / -name happiness.txt

/var/lib/docker/aufs/diff/860a7b... 889/happiness.txtCopy the code

Image Layer Definition

In order to integrate the scattered data, we put forward the concept of image layer. The image below depicts a mirror layer, and from the image we can see that a layer not only contains file system changes, but also contains other important information.

Metadata is additional information about this layer, which allows Docker to obtain not only runtime and build-time information, but also hierarchical information about the parent layer. Note that both the read-only and read-write layers contain metadata.

In addition, each layer contains a pointer to the parent layer. If a layer does not have this pointer, it is at the bottom level.

Metadata Location: I found that on my own host, the image layer Metadata is stored in a file named “JSON”, for example:

/var/lib/docker/graph/e809f156dc985... /jsonCopy the code

e809f156dc985… That’s the ID of this layer

A container metadata is divided into a lot of files, but more or less able to/var/lib/docker/containers/directory to find, is a readable layer id. The files in this directory are mostly run-time data, such as networks, logs, and so on.

The isolated It All Together

Now, let’s understand the Docker command in conjunction with the implementation details mentioned above.

docker create

The docker create command adds a read-write layer to the specified image, forming a new container. Notice that the container is not running.

docker start

The Docker start command creates a process isolation space for the container file system. Note that each container can have only one process isolation space.

docker run

A common question for readers looking at this command is what is the difference between docker start and Docker run.

As you can see from the image, the Docker run command first creates a container using the image and then runs the container. This command is very convenient and hides the details of both commands, but on the other hand, it can be misleading to users.

Digression: Continuing our previous discussion about Git, I think the Docker run command is similar to the Git pull command. Git pull is a combination of git fetch and git merge. Similarly, docker run is a combination of docker create and docker start.

docker ps

The docker ps command lists all running containers. This hides the presence of non-running containers. If we want to find these containers, we need to use the following command.

Docker ps – a

The docker ps -a command lists all containers, both running and stopped.

docker images

The docker images command lists all top-level images. In fact, there is no way to distinguish between a mirror and a read-only layer here, so we propose top-level mirroring. Only images that are used to create containers or that are pulled down directly can be called top-level images, and there are multiple layers of images hidden beneath each top-level image.

Docker images – a

The docker images -a command lists all of the images, so to speak, all of the readable layers. If you want to see all the layers under a particular image-ID, you can use Docker History to do so.

docker stop

The Docker stop command sends a SIGTERM signal to the running container and stops all processes.

docker kill

The Docker kill command sends an unfriendly SIGKILL signal to all processes running in the container.

docker pause

Docker stop and Docker kill send UNIX signals to a running process. Docker Pause uses cgroups to pause a running process. Here you can find the internal principle of concrete: https://www.kernel.org/doc/Doc… M.txt, but the disadvantage of this approach is that sending a SIGTSTP signal is not straightforward enough for a process to be able to suspend all processes.

docker rm

The docker rm command removes the read-write layer that makes up the container. Note that this command can only be executed on non-running containers.

docker rmi

The docker rmI command removes one of the read-only layers that make up the image. You can only remove the top level layer (or mirror) using docker RMI. You can also use the -f argument to force the middle read-only layer to be removed.

docker commit

The Docker commit command converts the container’s read-write layer to a read-only layer, thus turning a container into an immutable image.

docker build

The Docker build command is interesting because it executes multiple commands repeatedly.

As you can see FROM the figure above, the build command gets the image FROM the Dockerfile, and then repeats 1) run (create and start), 2) modify, and 3) commit. Each step in the loop generates a new layer, so many new layers are created.

docker exec

The Docker exec command executes a new process in the running container.

docker inspect or

The Docker inspect command extracts metadata from the top layer of the container or image.

docker save

The docker save command creates a compressed image file that can be used on another host’s Docker. Unlike the export command, this command saves metadata for each layer. This command is valid only for mirrors.

docker export

The docker export command creates a tar file and removes metadata and unnecessary layers, consolidating multiple layers into a single layer and preserving only what is currently viewed from the unified perspective. Import containers from expoxt to Docker. You can only see one image by using the Docker images-tree command. The save image is different, it can see the historical mirror of the image).

docker history

The docker history command recursively outputs a historical image of the specified image.