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

 

Docker Swarm

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.

Worker1;
docker-machine ssh worker1
 docker swarm join --token SWMTKN-1-1wnbtjri957qc5hzcu51oxhcl6w7yb3xp9whkfdzq8yo3s44a0-dg9r6bvn01use7pbmwqnhhldm 172.27.168.249:2377
Worker2;
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 8.8.8.8 (Google DNS). This container should be deployed to each node in the cluster.

$ docker service create --name pinger --replicas 3 alpine ping 8.8.8.8
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!


Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.