Docker Machine: Add an existing Docker Host

Docker is a quite handy technology for developers and operators to test and deploy applications. Since Docker emerged in 2013 a lot of various tools were created to help developers and operators create, deploy and monitor Docker powered apps. One of these tools is Docker Machine.

Docker Machine is a quite handy commandline tool to setup Docker and deploy container stacks. Machine supports a set of target hosts like Virtualbox, bare metal and different cloud providers. It helps booth to manage local development setups and production environments. Machine can automatically setup Docker on the target host including Docker Swarm. Once a host (or a machine) is set up, docker-machine can be used to control and monitor the Docker service on the host and deploy stacks.

Docker-machine keeps track of all remote hosts it created on the client and communicates with the Docker daemon on the host over TLS. The necessary certificates for the host, the client and a certificate authority are created by machine when running the docker-machine create command. This comes quite handy because it is easy and fast, the developer doesn’t have to create and sign certificates and distribute them to the host and client.

This works very well as long as a single docker-machine client is used to manage a remote machine. As soon as more than one client wants to access the host with docker-machine the problems start to rain down. Assuming Schneider did create a new remote machine called ferdinand by running the docker-machine create command on his client, then he has automatically set up all certificates required for secure communications with the remote docker daemon. If docker machine was used the first time it created a new CA, client certificate and client key. From now on they will be used whenever a new machine is created. They are located in ~/.docker/machine/certs/.

By running the create command, the certificates, keys and a configuration file for the remote machine are created in ~/.docker/machine/machines/ferdinand/. Taking a look at those file you can see that the ca and client certificate and key are a copy of the files in the certs/ directory. Schneider might create some more machines and if you take a close look at their configuration and certificate files you will see that they use a copy of the same certificates. The server certificate will be the only certificate that differs as docker machine always create a new certificate for the remote docker machine.

Some time has passed and another developer Tobi has joined Schneider for the project and needs access to the docker host. Because docker-machine is such a nice tool he wants to use it to manage and deploy to the development server ferdinand. And there is the problem. Despite the strong wishes of the community Docker Inc did not implement a consistent way to add an existing docker machine on another host. If Tobi would run docker-machine create for ferdinand on his client, his docker-machine would create a new CA and tries to provision the remote machine with those. If Tobi forces the provisioning he would regenerate the certificates on the remote host and Schneider would no longer be able to access it with docker-machine from his client.

Now what is the solution?

At this time there is only one feaseable and consistent way to still use docker-machine with more than one client. When Schneider provisioned the machine his local client created a CA, a client certificate, a server certificate and a configuration file. The simplest way to go would be to just copy the whole machine directory to Tobi’s client machine. Then Tobi would have an exact copy of the certificates and keys required to access ferdinand with docker-machine. But this would include copying his private key and the CA’s key which in most cases would be very bad.

Luckily docker-machine create can take a set of optional arguments including an existing CA and a client certificate and - hidden from the world - it can take a none-driver. The none driver is intended for testing purposes and not production use but it can be used to solve our problem.

https://frank.sauerburger.io/2018/08/01/create-docker-machine-with-custom-certificates.html

https://stackoverflow.com/questions/46338037/how-to-set-tls-certificates-for-a-machine-in-docker-machine

https://docs.docker.com/machine/overview/