Docker engine (engine) learning summary

        Today I will prepare container training, learn the knowledge related to docker engine, and summarize and record it.

1. Docker engine

        The Docker engine is the core software used to run and manage containers. It adopts the principle of modular design and realizes the creation and operation of containers under the cooperation of many dedicated components. The reason why I introduce this is because it is closely related to the principle.

2. Early Docker engine architecture

        When Docker was first released, the Docker engine consisted of two core components: LXC and the Docker daemon.
        A Docker daemon is a single binary file that includes things like the Docker client, Docker API, container runtime, image building, and more.
        LXC provides the ability to operate basic tools such as Namespace and CGroup, which are container virtualization technologies based on the Linux kernel.
        The figure below illustrates the interaction between Docker daemon, LXC and the operating system in the old version of Docker.

        Early architectures had the following problems:

        1. Dependence on LXC. LXC is based on Linux. This is a problem for a project that aspires to be cross-platform.
Such a core component depends on external tools, which will bring huge risks to the project and even affect its development. Therefore, the Docker company developed a self-developed tool called Libcontainer to replace LXC. The goal of Libcontainer is to be a platform-independent tool that can provide the necessary container interaction functions for the upper layer of Docker based on different kernels. 

        2. Docker daemon is too bloated. The monolithic nature of the Docker daemon created more and more problems over time. Difficult to change, slower and slower to run. Aware of these problems, the Docker company began to work hard to dismantle this large and comprehensive Docker daemon process and modularize it.

3. The current Docker engine architecture

        Significant advantages of this model:

        Removing all the logic and code for starting and managing containers from the daemon means that the container runtime is decoupled from the Docker daemon, sometimes called a "daemonless container", so, Maintenance and upgrades to the Docker daemon will not affect running containers. In the old model, all container runtime logic is implemented in the daemon, and starting and stopping the daemon will cause all running containers on the host to be killed. This is a big problem in a production environment - think of how often new versions of Docker are released! Every daemon upgrade will kill all containers on the host, which is too bad! Fortunately, this is no longer an issue.

4. Functional description of each component

components describe
/usr/bin/docker The docker client is directly oriented to operating users; docker and dockerd communicate through /var/run/docker.sock
/usr/bin/dockerd  dockerd is Docker Daemon, which is the daemon process of Docker; dockerd itself is actually the top-level encapsulation of APIs for container-related operations. The main functions of daemon include image management, image construction, REST API, authentication, security, core network, and orchestration; The socket file between dockerd and containerd is /run/containerd/containerd.sock
/usr/bin/containerd What dockerd actually calls is the API interface of containerd. containerd is an intermediate communication component between dockerd and runc; the containerd component ensures that the Docker image can be delivered to runc in the correct OCI Bundle format.
/usr/bin/containerd-shim containerd-shim is a real shim carrier of a running container, and a new docker-shim process will be started every time a container is started.
He directly calls runc through the specified three parameters: container id, boundle directory (containerd corresponds to the directory generated by a certain container, generally located at: /var/run/docker/libcontainerd/containerID), and runs the binary (runc by default). API to create a container (for example, to create a container: the final assembly command is as follows: runc create ); it has the following three functions: 1. Allow runc to exit the binary file compiled by Go
after creating & running the container . The default is static linking
, therefore, if N containers are installed on a machine, then M*N memory will be occupied, where M is the memory consumed by a runc. However, for the reasons described above, I don’t want to directly let containerd be the parent process of the container. Therefore, I need something smaller than runc to be the parent process, that is, shim.
2. Using shim as the parent process of the container instead of directly using containerd as the parent process of the container is to prevent this situation: when containerd hangs up, shim is still there, so it can ensure that the file descriptor opened by the container will not The main function of shim being turned off
is to decouple containerd from the real container (the process in it)
3. Rely on shim to collect & report the exit status of the container, so that containerd is not needed to wait for the child process
/usr/bin/containerd-shim-runc RunC is the runtime for running containers. It creates and runs containers according to oci (Open Container Organization) standards. It is responsible for running containers using resources such as files that meet the standards, but it does not include image management functions like docker. So to run the container with runC, we must first prepare the file system of the container. The so-called OCI bundle refers to the container's file system and a config.json file. With the file system of the container, we can generate the config.json file through the runc spec command.
Runc is essentially a lightweight command-line interactive tool packaged for Libcontainer
/usr/bin/docker-init We all know that in the UNIX system, process No. 1 is the init process and the parent process of all orphan processes.
When using docker, if the --init parameter is not added, the No. 1 process in the container is the given ENTRYPOINT, and after adding --init, the No. 1 process will be tini.
/usr/bin/docker-proxy It is used for port mapping between the container and the host, and the bottom layer is done using iptables.
Docker run -d -p 10010:10010 busybox sleep10000, ps aux|grep docker command can view the rules.
OCI standard Container runtime, Container runtime refers to the tool for managing and running containers. There are many current container tools, such as docker, rkt, etc., but if each container tool uses its own runtime, it is not conducive to the development of the container field,
so , some container vendors have jointly formulated the container image format and container runtime standards,
namely the OpenContainer Initiative (OCI). Docker participated in two container-related specifications that OCI set out to define: the image specification and the container runtime specification.
OCIbundle OCI Bundle refers to a series of files that meet the OCI standard. These files contain all the data needed to run the container. They are stored in a common directory, which contains the following two items: 1. config.json: Contains the configuration of the container running Data; 2. Container file system
image--OCI Bundle--runc--container

5, reference

https://jiajunhuang.com/articles/2018_12_24-docker_components_part2.md.html

http://c.biancheng.net/view/3137.html

http://events.jianshu.io/p/d08fb1f5de9d

https://www.jianshu.com/p/2e0e33dac632

https://zhuanlan.zhihu.com/p/59796137

Guess you like

Origin blog.csdn.net/weixin_39855998/article/details/126895703