Docker it is a Client-Server architecture application. It is officially called Docker Engine. Docker is just a nickname for Docker Engine. Of course, Docker has other meanings, such as the name of a company. For simplicity, Docker in this article is equivalent to Docker Engine.
When it comes to Docker, we must know that it contains three parts:
the following figure clearly shows the relationship between them:
Docker Machine it is a tool for installing and managing Docker. It has its own command line tool: docker-machine.
now that Docker clients want to communicate with Docker daemon through REST API, let's see what methods they can use:
Systemd socket activation
we can simply understand 1 and 2 as one way, that is, inter-process communication on the same host. As for 3, it is easy to understand: cross-network communication through tcp protocol.
Since 1 and 2 are used for inter-process communication on the same machine, we can guess that Docker clients and Docker daemon installed on the same host communicate in this way. This is also the case. You can view the Docker daemon startup configuration that is added by default when Docker is installed. Open the file/etc/systemd/system/multi-user.target.wants/docker.service:
in the figure,-H is used to specify the socket of the Docker Daemon listener. The type specified here is system socket activation. To use type 1 and type 2 for communication, the process must have the root permission. This is the main reason why a user and user group with root permissions are automatically created during Docker installation. The newly created users and user groups are named docker. We recommend that you add all users who need to operate Docker to this group. Otherwise, you will encounter the following problems when running commands:
you can also specify multiple-H parameters to allow Docker daemon to listen to different socket types at the same time. For example, to add a listener for TCP port 2376, you can use the following command line parameters:
$ sudo dockerd -H fd:// -H tcp://0.0.0.0:2376
run the preceding command to view the listening port of the local machine:
then we can access port 2376 of the host from the Docker client on the remote host.
by default, the Docker client is configured to access the local Docker daemon. After you specify the DOCKER_HOST variable, the Docker client accesses the Docker daemon specified in this variable. Let's review the docker-machine env command:
the $eval $(docker-machine env krdevdb) command we executed in the previous article is to set the DOCKER_HOST environment variable.
our Docker daemon listened to the tcp port. Unfortunately, we did not take any protection measures at this time. Therefore, any Docker client can interact with our Docker daemon through the tcp port, which is obviously unacceptable. The solution is to enable the TLS certificate authentication mechanism for both the Docker daemon and Docker clients. In this way, the communication between the Docker daemon and the Docker client is encrypted, and only the client with a specific certificate installed can interact with the corresponding Docker daemon.
At this point, the foreshadowing part of this article is finally over. Next, we will discuss Docker Machine related contents.
depending on the Docker Machine driver, the create Command performs different operations, but there are two steps that we are concerned about here:
docker-machine performs the following operations on the specified host:
install Docker and configure it.
Generate a certificate to protect Docker.
there is no secret in the Docker installation process. We will not go into details here. We focus on the configuration of Docker daemon. After careful observation, we can find that docker installed through Docker-machine has an additional Docker-related directory in the/etc/systemd/system directory: docker.service.d. There is only one file 10-machine.conf in this directory:
well,-H tcp:// 0.0.0.0:2376 does not surprise us. After a lot of foreshadowing, you should take it for granted. -- The parameters starting with tls are mainly related to certificates. We will describe them in detail in the following security settings. What makes people somewhat confused is/usr/bin/docker in the above figure. The Docker Machine of the latest version is still being set Docker daemon in the old way. We hope that it will be updated in the next version.
This configuration file is critical because it overwrites the configuration file used when Docker is installed by default, so that the Docker Machine is started in the way specified by the Docker daemon. Now we have a Docker daemon that can be accessed remotely.
Generate a certificate
in the Docker daemon configuration file, we see four parameters starting with -- tls: -- tlsverify, -- tlscacert, -- tlscert, and-tlskey. -- tlsverify indicates that the Docker daemon needs to use TLS to verify the remote client. The other three parameters respectively specify the path of a pem file. Check the path of the file according to the path they specify:
if you compare the manually installed Docker files, you will find that these three files do not exist in the/etc/docker directory. There is no doubt that they are generated Docker Machine, mainly to Enable TLS authentication for Docker daemon. As for TLS, the author slightly mentioned it in the article "local area network deployment Docker Registry". At that time, it was a manually configured certificate. If you are interested, please refer to it.
Now let's go back to the host where the Docker Machine is installed.
View/home/nick/.docker/machines/krdevdb Directory, found some files with the same name (ca.pem, server-key.pem, and server.pem), compare with the files on the host drdevdb, and find that they are the same!
Let's take a look at this picture again:
in addition to the DOCKER_HOST that we have followed, there are three other environment variables. DOCKER_TLS_VERIFY indicates that the Docker client needs to enable TLS authentication. DOCKER_CERT_PATH specifies the Directory of the files on which TLS authentication depends. This directory is exactly the/home/nick/.docker/machines/krdevdb directory we looked at earlier.
At this point, the security problem that troubled us was finally explained: Docker Machine generated a series of key and digital certificate (*.pem) files to ensure security during the execution of the create Command. These files are stored on the local Docker host and the remote Docker host respectively. The local Docker client is used to configure the Docker daemon, and the remote Docker host is used to configure TLS authentication marks on both sides, this ensures secure communication.