This blog post covers the topic Docker Swarm and how to create a minimal cluster running a Nginx service. Normally, a Docker Swarm consists of several nodes. These nodes can be real, physical machines but also virtual machines.
In the following example, we will use two virtual machines to create a minimal cluster. We need one machine to act as the manager and one to join the swarm as a worker. With the following commands, we can easily create virtual machines in VirtualBox:
$ docker-machine create --driver virtualbox vm01 $ docker-machine create --driver virtualbox vm02
On Mac it is possible to use xhyve instead of VirtualBox. Xhyve is based on the OS X hypervisor.framework.
Once the machines are created, we can list them to see their IP addresses with this command:
$ docker-machine ls # Output NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS runner - virtualbox Saved Unknown vm01 - virtualbox Running tcp://192.168.99.100:2376 v18.06.1-ce vm02 - virtualbox Running tcp://192.168.99.101:2376 v18.06.1-ce
What we now want is, to enable swarm mode on our vm01. Our vm01 should become a swarm manager. To do this, we use ‘docker-machine ssh’ to send commands to our virtual machine. Thus, we need the IP address of our vm01.
$ docker-machine ssh vm01 "docker swarm init --advertise-addr 192.168.99.100:2377" #Output: Swarm initialized: current node (uxj5zyc2mqkoawufuom812dz1) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-07fcb01hxwtstpj2f5zvhlbuqjdje1q6pwkatdyzpqtcpsjrn1-aqojwifpjtfgnrah40rmvdd6a 192.168.99.100:2377
To add a manager to this swarm, run ‘docker swarm join-token manager’ and follow the instructions. We need to provide the IP of our machine, otherwise other nodes in the swarm are not able to connect to our node. As we can see, we explicitly use the port 2377. Otherwise the port 2376 will be used per default, which may cause problems because the port 2376 is used as the Docker daemon port.
The output tells us, what we can do next. It provides us with two different commands. The first command provided is a command to add a worker to the created swarm. Additionally, the output states that the current node is a manager. With the second command provided by the output, we can also add another manager to this swarm.
On vm02 we use the following command to join the swarm as a worker:
$ docker-machine ssh vm02 "docker swarm join --token SWMTKN-1-1z9el6rbwq0f7qt8mtapx22vrmxsumrj7o6xc37fprmoz9mn4i-6krhg8ra8rsxshfo44gbusltd 192.168.99.100:2377" # Output This node joined a swarm as a worker.
To view the nodes in the swarm we use the following command:
$ docker-machine ssh vm01 "docker node ls" # Output ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 53jd99awzo8pexcpkusz97hyp * vm01 Ready Active Leader 18.06.1-ce mpei1m7lgq9zmvm7bxhsnub7k vm02 Ready Active 18.06.1-ce
Note that we can only execute Docker commands on the manager. Worker nodes are just for capacity.
Our cluster is ready and we can deploy our service. A service is created with ‘docker service create name_of_image’. We want to start a Ngnix service on our swarm. For the service to be reachable, we must publish the service at port 8080. We again apply the command through ssh on our vm01:
$ docker-machine ssh vm01 "docker service create --name nginx --publish published=8080,target=80 nginx"
Our service can now be accessed via the IP of either vm01 or vm02.
$ curl 192.168.99.100:8080 $ curl 192.168.99.101:8080
To instruct our vm02 to leave the swarm we can use the command below:
$ docker-machine ssh vm02 "docker swarm leave --force"
To delete the docker machines the following command is used:
$ docker-machine rm vm01 vm02