Docker Machine is a solution that lets you install the Docker daemon on virtual machines and let them manage with help of the docker-machine command.
Docker Machine can be used to manage you’re local Mac, Windows or Linux machine, but also other Docker node in your own datacenter or instances running on a cloud provider.
For Windows deployments Docker Machine can be configured to support two different virtualization solutions. The first options is to use VirtualBox. And because we are using Windows it is also possible to use the build-in Hyper-V functionality.
So we don’t necessarily need to install VirtualBox to run the virtual machines.
In summary in this blog post we will create a Docker Swarm consist of one Manager and two Workers. All of the virtual machines are running as an Hyper-V VM, on top of the Windows 10 machine and all this is managed by Docker-Machine.
Installing Docker Machine on Windows 10
But before we can start, we need to make sure that both Docker and Docker Machine has been installed. Follow this guide on how to install Docker and Docker Machine on your Windows 10 machine.
Creating the Hyper-V Virtual Machines
Alright, once we have completed all the pre-requirements, it’s time to create the Docker Machine nodes.
Create Docker Machine VM’s;
Start a administrative Windows PowerShell session. And execute the following commands to create the Virtual Machines.
NOTE: for the first time it could take some time (depending on the Internet connection speed) because it need to download some sources from the Internet.
$ docker-machine create --driver "hyperv" --hyperv-virtual-switch “Default Switch” --hyperv-cpu-count "1" --hyperv-memory "1024" --hyperv-disk-size "10240" manager
$ docker-machine create --driver "hyperv" --hyperv-virtual-switch “Default Switch” --hyperv-cpu-count "1" --hyperv-memory "2048" --hyperv-disk-size "10240" worker1
$ docker-machine create --driver "hyperv" --hyperv-virtual-switch “Default Switch” --hyperv-cpu-count "1" --hyperv-memory "2048" --hyperv-disk-size "10240" worker2.
Set Docker-Machine environment settings;
In order to get access to the three machines it’s necessary that the environment settings are applied, to do this execute the following commands.
$ docker-machine env manager $ docker-machine env worker1 $ docker-machine env worker2
Verify that the nodes are created;
$ docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS manager - hyperv Running tcp://172.27.168.249:2376 v17.12.1-ce worker1 - hyperv Running tcp://172.27.168.242:2376 v17.12.1-ce worker2 - hyperv Running tcp://172.27.168.251:2376 v17.12.1-ce
Once the three machines are fully deployed, it’s time to go ahead and start creating the Docker Swarm.
Initialize Docker Swarm on the Manager;
Make sure you have the IP address of the Manager node (in this example it’s: 172.27.168.249).
$ docker-machine ssh manager $ docker swarm init --advertise-addr 172.27.168.249
Once the swarm has been created and you remember the join token it’s safe to exit this node. Just type exit to quit this ssh session.
Add worker nodes to the swarm;
Depending on the amount of workers you have created in the previous steps we are going to add them to the Swarm. In this example we are going to add worker1 and worker2.
docker-machine ssh worker1 docker swarm join --token SWMTKN-1-1wnbtjri957qc5hzcu51oxhcl6w7yb3xp9whkfdzq8yo3s44a0-dg9r6bvn01use7pbmwqnhhldm 172.27.168.249:2377
docker-machine ssh worker2 docker swarm join --token SWMTKN-1-1wnbtjri957qc5hzcu51oxhcl6w7yb3xp9whkfdzq8yo3s44a0-dg9r6bvn01use7pbmwqnhhldm 172.27.168.249:2377
Get back to the Manager and verify that all nodes has been added to the swarm;
docker-machine ssh manager docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ptx8dp1eqfsdbkz3wos9ldgvb * manager Ready Active Leader 5ax5glgem5o8zulg8dlgowofh worker1 Ready Active re4setq5k3pn3drc8j1mx2xwk worker2 Ready Active
Adding services to the Swarm
Now the Docker Swarm has successfully been initialized, and the nodes has been added it’s time to deploy some services (running containers).
Deploy a test service (pinger)
To make sure all nodes can deploy the service we will deploy a small Alpine Linux based container that will do a continues ping to IP 18.104.22.168 (Google DNS). This container should be deployed to each node in the cluster.
$ docker service create --name pinger --replicas 3 alpine ping 22.214.171.124
Check if the services has been deployed successfully;
$ docker service ls ID NAME MODE REPLICAS IMAGE PORTS lt34dr5dpqtk pinger replicated 3/3 alpine:latest
As shown here above we can see 3 out of 3 replica’s has been deploy!
Show all details of the pinger services;
$ docker service ps pinger ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS u1f1mluyy4u6 pinger.1 alpine:latest worker1 Running Running about a minute ago j14xo5aoc0jh pinger.2 alpine:latest worker2 Running Running about a minute ago mswjnzfuongo pinger.3 alpine:latest manager Running Running about a minute ago
Deploy a httpd service (httpd)
Now we no that all nodes can be scheduled and have access to the outside world we should check if we can reach the services running on the Swarm. For this test we will use the httpd Docker base image, and publish it on port 80.
$ docker service create --name httpd --publish 80:80 --replicas 2 httpd
Note: as you can see in the command here above we are going to deploy 2 replica’s to the Swarm. So one of the host should not have a container running the httpd instance.
Check if the services has been deployed successfully;
$ docker service ls ID NAME MODE REPLICAS IMAGE PORTS zmo9c67pbzbs httpd replicated 2/2 httpd:latest *:80->80/tcp lt34dr5dpqtk pinger replicated 3/3 alpine:latest
Show all details of the httpd services;
$ docker service ps httpd ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS 30u49ccpggz7 httpd.1 httpd:latest worker1 Running Running 13 seconds ago rsl1ankg9m65 httpd.2 httpd:latest manager Running Running 13 seconds ago
In the detailed service overview here above we can see that the httpd instance is running on node Worker1 and Manager.
Testing the httpd service;
To round it all up we need to verify that we can access the httpd service by opening a browser on the Windows 10 machine and access all Swarm nodes by entering there corresponding IP addresses.
You could see on all nodes (including the one that does not have an active httpd container) the message It worked!
With that we have successfully setup a Docker Swarm in Docker Machine and deployed services to the Swarm!