Main components of Docker
Installing Docker is actually installing a series of components, such as Docker client, Dockerd and so on, which are more important in the following sections.
Docker CLI (Docker)
The Docker program is a client-side tool that sends a user's request to Docker Daemon (dockerd). The installation path for this program is:
/usr/bin/docker
Dockerd
Docker Daemon (dockerd) is also commonly referred to as Docker engine. The installation path for this program is:
/usr/bin/dockerd
Containerd
For more information, please refer to "Containerd profile". The installation path for this program is:
/usr/bin/docker-containerd
Containerd-shim
It is the Containerd component, the runtime carrier of the container, and the shim we see on the Docker host is the Docker container that is launched by calling Containerd. The installation path for this program is:
/usr/bin/docker-containerd-shim
Runc
For more information, please refer to "Runc profile". The installation path for this program is:
/usr/bin/docker-runc
Starting with Hello World
Docker is very thoughtful to provide us with a hello-world image to verify the success of the installation, but we can see more information through this image:
$ Docker Run Hello-world
The above output indicates that the operation of the Hello-world container has undergone the following four steps:
- Docker client sends request to Docker daemon
- Docker Daemon pull mirror from Docker Hub
- Docker Daemon uses a mirror to run a container and produce output
- Docker daemon sends the output to the Docker client
This is a very abstract and container-aware process, but we also want to know more: How does Docker daemon Create and run containers?
In fact, the operation and management of the container parts are dockerd outsourced to Containerd, describing the relationship between the components when running a container:
Docker Engine API
In essence, Docker is an application of a client/server architecture. Dockerd provides services externally as an engine API (REST), and the engine API describes all requests supported by Dockerd. The Docker client communicates with Dockerd in the form of REST. In Ubuntu 16.04, dockerd default is not listening to the TCP port, in order to facilitate the demonstration, we let Dockerd listen to the TCP port. This allows you to use curl instead of a Docker client to send a request to dockerd. To do this, first modify the/lib/systemd/system/docker.service file, comment out the default Execstart, and add a new Execstart configuration:
# execstart=/usr/bin/dockerd-h Fd://execstart=/usr/bin/dockerd-h tcp://0.0.0.0:2375-h Unix:///var/run/docker.sock
Then restart Docker.service:
$ sudo systemctl daemon-reload$ sudo systemctl restart Docker.service
This dockerd starts listening on TCP port 2375:
The interaction between Docker and Dockerd
The Docker client communicates with Dockerd in the form of REST. We've already let Dockerd listen to the TCP port, so we can use curl instead of the Docker client. Here we simply demonstrate how to request the Dockerd to download the Hello-world image from the Docker hub:
$ Curl ' 127.0.0.1:2375/v1.37/images/create?fromimage=hello-world&tag=latest '-x POST
If you look at the Engine API, you will find that other requests are also sent in a similar way, is not very simple ah!
Create a container
The download of the container image is done by Dockerd, but the creation and operation of the container requires Containerd (Docker-containerd) to complete. Between Dockerd and Docker-containerd is communicated through the GRPC protocol. When Docker-containerd receives a request to Dockerd to start the container, it does some initialization work, then starts the Docker-containerd-shim process and passes the relevant configuration as a parameter to it. Docker-containerd is responsible for managing all of the native running containers, while a docker-containerd-shim process is only responsible for managing a running container, which is equivalent to a DOCKER-RUNC package that acts as Docker-containerd and Docker-runc between the bridge, Docker-runc able to give Docker-runc to do, docker-runc do not put it here to do. Below we run a container with an Ubuntu image:
$ docker run-id Ubuntu bash
The Yellow line is framed by several major processes, which have a parent-child relationship (SYSTEMD does not appear):
SYSTEMD---dockerd---docker-containerd---docker-containerd-shim---bash
Careful friend must have found, there is no docker-runc process, this is why?
In fact, during container initiation, the DOCKER-RUNC process exists as a docker-containerd-shim child process. The Docker-runc process finds the container's rootfs based on the configuration and creates a child process bash as the first process in the container. When this is all done, the docker-runc process exits, and then the container process bash is taken over by Docker-runc's parent process Docker-containerd-shim.
Why do I need Docker-containerd-shim?
Perhaps you will ask, why do you need a docker-containerd-shim process in the process of starting or running a container? It will be more concise and more graceful to remove the entire architecture! In fact, the existence of Docker-containerd-shim is very necessary, its purpose is as follows:
- It allows the container runtime (that is, Runc) to exit after the container is started, simply by not having to run a container runtime (runc) for each container.
- The container's standard IO and other file descriptors are available even if both Containerd and Dockerd are dead
- Report the container's exit status to Containerd
The first two points are especially important, and with them you can upgrade or restart the Dockerd without interrupting the container operation (which is significant for the production environment). Here you can see some explanations of the containerd-shim.
Sparkdev Source: http://www.cnblogs.com/sparkdev/
Main components of Docker