Skip to main content

Command Palette

Search for a command to run...

Diving into Docker (Part 7): Docker Swarm

Step by step guide on managing multi-host, multi-service application using Docker Swarm

Published
15 min read
Diving into Docker (Part 7): Docker Swarm

If you are still following along, I must say that a few people have come this far. And let me congratulate you because it's been a long journey, and I am sure you have learned many new things so far. We went from knowing the difference between VMs and Containers to running them and deploying to the Docker Hub. We learned about docker-compose too, which is used in production to deploy multi-service applications.

But if you see, till now, we were dealing with a single host and a few containers. But in real life, that is not the case. In companies, they have so many products and services, and those services do not run on a single host. They are scattered around the world or in other places. Then you might ask, who manages those services? Is it like someone sitting in front of the display and checking all the time which services are working correctly or not?

If you think that is how they manage, you are mistaken, because managing so many services manually is not possible today. So what's the solution? Who manages it?

To answer that, you have to read this blog. But if you don't want to and just want to know, then here is the short answer:

Docker Swarm / Kubernetes

I bet you want more details than just these two words, right? And to get that, you'll have to read the blog, so, sorry, 😅 I can't give you the short answer. Because, like life, there are no shortcuts to achieving goals. Okay, enough of motivation, let's get to the real thing.


Docker Swarm

We now know how to install Docker, pull images, and work with containers. But as we discussed above, to work with that big scale, we need something that can manage these containers for us. And that's where Docker Swarm comes into the picture.

What is Docker Swarm?

Docker Swarm is a tool that helps you manage multiple Docker machines. Instead of running containers on just one computer, you can connect multiple machines and treat them like a big system. This group of machines is called a cluster.

In a Swarm cluster, each machine is called a node. A node can be a physical server, a virtual machine, a cloud server, or even a small device like a Raspberry Pi. The only thing required is that Docker must be installed, and the machines must be able to talk to each other over the network.

Types of Node

There are two types of nodes: managers and workers.

Managers control the cluster. They decide what tasks should run and which worker should run them.

Workers are the machines that actually run the containers and do the work. Managers tell them what to do, and workers follow those instructions.

Docker Swarm also keeps track of the cluster’s information, like which containers are running and which nodes are available. This information is stored on the manager nodes in a distributed database. The nice thing is that Docker sets this up automatically, so you don’t need to configure it yourself.

If you are concerned about Docker's security, then don't. Because security is built into Swarm. Communication between nodes is encrypted, and each node must prove its identity before joining the cluster. Docker also automatically manages and rotates security certificates, so the system stays secure without extra effort.

Swarm is also used to run and manage applications made of many small services called microservices. In Swarm, the main unit used to run applications is called a service. A service is similar to a container but with extra features. For example, you can easily run multiple copies of it, update it gradually without downtime, or roll back to an older version if something breaks.

There is also one tool called Kubernetes which is a competitor of Docker Swarm. They both orchestrate containerized applications. Well, it's true that Kubernetes is more popular and have more active community and ecosystem. Docker Swarm has it's own benefits too. It's a lot easier to configure and deploy. While it may not be the best solution for bigger companies, but its an excellent technology for small to medium businesses.

I think that's enough of the theory. Let's get to the practical part and see how we can implement this ourselves.


Creating our OWN Swarm Cluster

The example is highly inspired by the book (Docker Deep Dive - Nigel Poulton). The only thing missing there was that he didn't show how to implement it with a single host machine. Because hey, for just the example, we're not gonna have 10 different machines and run and test it, right? So what I did was, I implemented the same thing with the help of AWS. Let's see how we can implement it. The only prerequisite is to have an AWS account. So if you don't have one, I would suggest to make one. I am not gonna show it here otherwise the blog will become lengthy. So make one and then start from here.

Example:

So, in the example, we are going to make a secure swarm cluster with one manager nodes and two worker nodes.

As we saw earlier, that nodes can be virtual machines, physical servers, cloud instances (in our case), or Raspberry Pi systems. The only thing required on those system is to have Docker installed.

Creating 3 EC2 instances ( 1 manager, 2 worker)

Go to https://signin.aws.amazon.com/signin and sign in with the Root user. Once you are in, you will see a dashboard like this.

Now we need 3 machines, right? So let's create 3 EC2 instances. Go or search for EC2 and get in.

Now, click on Launch instance.

Creating Manager Node

Now, we need to name our machine and configure some options.

If you don't know anything about AWS EC2, I think it's the best time to learn. Because in today's time, it good to have some knowledge about it at-least if not a hands on experience. But anyways, you will not be needing to know much about it for this example as it's gonna be really simple.

Here, we are doing nothing but creating a Virtual instances (machines) for us to be able to test Docker Swarm capabilities.

Let's now finish the configuration part. Go ahead and name this instance "mgr1" (this will be our manager). Then select the Ubuntu image

After that, we need to add a key pair. This is required as we are gonna connect this instance to our laptop's terminal and use it. So go ahead and create an RSA (.pem) private key and store it somewhere safe. I named this key docker-swarm-test.

Once this is done, do nothing, just click on Launch Instance. As you can see below, we now have the running manager instance.

Now, we don't need to open these instances to the whole world, right? So what we do is we open a few ports between these instances for them to talk. We can add those ports by going into the Security section. Click on the Security Group link, it will redirect you to the new page where we can add the ports

Click the "Edit Inbound rules".

Add all the ports defined below. I've added the description for each port, what it is used for, so you can take a look at it too. Once done, save the rules, and you are good to go.

Creating Worker Nodes

Now we have one Manager node. We need two worker nodes. The process gonna be the same only except the name of the Instance. Go ahead and create wrk1 and wrk2. I am gonna show wrk1, and then you can create wrk2 on your own. It's pretty simple.

  1. Name the instance (wrk1) and select the Ubuntu image.

Select the same key pair that we created.

Now here comes the most IMPORTANT part, so make sure you don't miss it. We need to put all these instances into the SAME VPC and Subnet in order for them to work. How will you make sure? Just open the mgr1 instance (on the right in the screenshot below), go to the Networking tag, and you will see the VPC ID and Subnet ID.

On the worker node (on the left), select the same Subnet ID and VPC ID.

Once done, launch that instance.

IMPORTANT: Make sure you add all the ports like we did for the Manager node.

As you can see now, I have all three instances running on my AWS.


SSH into each instance

Now, let's open these instances in our machine. Open three separate terminals and run below commands

ssh -i ~/Downloads/docker-swarm-test.pem ubuntu@107.21.169.169

Here, make sure you provide the correct path of the key you downloaded (this is the key which gets downloaded when we created the key-pair). And then specify the Public IP Address. Which you will find in the Details tab of the instance

Once done, your terminal will turn into that instance terminal, and you'll see something like this.

Do this for all three instances, and you will have all three instances running inside your host machine in your terminal.

(Top - Manager, Bottom Left - Worker 1, Bottom Right - Worker 2)

Installing Docker on all 3 instances

In order to run Docker Swarm, we first need to install Docker inside these instances. To do that run below commands

sudo apt-get update
sudo apt-get install -y docker.io
sudo systemctl enable --now docker

Run those commands in all three terminals, and you will have Docker installed.

Initializing a new swarm

Now that we have everything in place, we can go ahead and initialize our Docker swarm. One thing to note about is that, Docker nodes that are not part of swarm are said to be in single-engine mode. Once they're added to a swarm they're automatically switched to swarm mode.

Running docker swarm init on a Docker host in single-engine mode will switch that node into swarm mode, create a new swarm, and make the node the first manager of the swarm.

And all the additional nodes can then be joined to the swarm as workers and managers. Joining a Docker host to an exisiting swarm switches them into swarm mode as part of the operation.

Let's run the below command to our manager node to initialize a new swarm.

docker swarm init --advertise-addr <manager-ip-address>

Let's understand the command:

docker swarm init - This tells Docker to initialize a new swarm and make this node the first manager. It also enables swarm mode on the node.

--advertise-addr - As the name suggests, this is the swarm API endpoint that will be advertised to other nodes in the swarm. It will be one of the node's IP address, but can be an external load balancer address.

--listen-addr - This is the IP address that the node will accept swarm traffic on. If not explicitly set, it defaults to the same value as advertise-addr.

To list the nodes in the swarm run sudo docker node ls command.

As you can see, only the mgr1 node is the only node present in the swarm. It's also listed as Leader. Now it's time to add the worker nodes to join this swarm too. To do that run below command in manager node

sudo docker swarm join-token worker

If you want another manager to join the swarm, run:

sudo docker swarm join-token manager

Now go to the worker nodes (wrk1 and wrk2) and join the swarm using the command you got above:

That's it. We've just created 3 node swarm with 1 manager and 2 workers. And you can see that by running sudo docker node ls command into the manager node. Nodes with nothing in the Manager Status are workers.

Also if you notice the asterisk (*) in front of the node ID, it says which node you are logged on to and executing commands from.

Swarm manager high availability

You must be asking, why we added managers and workers, and how they work together, and what's the point of all these?

So in real worlds, it can happen that sometimes one or more nodes can fail, but if you are using Swarm, the survivors will keep the swarm running without interrupting anything.

Right now, we have only one manager, but if you have more than one managers, only one of them is active at any given moment. This active manager is called the "Leader". And the leader is the only one that will ever issue live commands against the swarm.

(Diagram from - Docker Deep Dive book by Nigel Poulton)

Swarm Services

A service in Docker Swarm is a way to run and manage containers across a cluster of machines. It is a feature that only works when Docker is running in swarm mode. A service lets you define how your application should run, and the swarm makes sure that state is always maintained

With services, you can set many of the same options you normally use for containers. For example, you can give the service a name, choose which image to use, map ports, and connect it to networks. But services also add extra features that are useful for modern cloud applications.

You can create services by running docker service create command

docker service create --name web -p 8080:8080 --replica 5 dhruvnakum/web

For example, a command above create a service named web, map port 8080, and run 5 replicas using a specific image. After the command runs, the manager node decides where those containers should run in the cluster. Each node that receives a task downloads the image and starts a container.

Swarm also constantly watches all services. It runs a background process that checks if the actual state matches the desired state. If everything matches, nothing changes. But if something goes wrong, the swarm fixes it automatically.

For example, if one of the machines running a container fails, the number of running containers might drop from 5 to 4. Swarm will notice this and automatically start another container on a different node to bring the total back to 5. This is called self-healing, and it helps keep applications running even when failures happen.

You can see all services in the swarm using the command

docker service ls

If you want to see the containers that belong to a specific service, you can use

docker service ps

Another useful feature is scaling. If your application gets more traffic, you can increase the number of running containers. For example, if traffic doubles, you can scale the service from 5 containers to 10 using the command docker service scale

Example:

docker service scale web=10
web scaled to 10
overall progress: 10 out of 10 tasks
1/10: running
2/10: running
3/10: running
4/10: running
5/10: running
6/10: running
7/10: running
8/10: running
9/10: running
10/10: running
verify: Service converged

When scaling happens, Docker tries to spread the containers evenly across the nodes in the cluster. This helps distribute the workload.

If traffic goes down again, you can scale the service back to a smaller number of containers. For example, you can reduce it from 10 back to 5.

docker service scale web=5
web scaled to 5
overall progress: 5 out of 5 tasks
1/5: running
2/5: running
3/5: running
4/5: running
5/5: running
verify: Service converged

If you no longer need the service, you can remove it using the command docker service rm. When you do this, the service and all of its running containers will be deleted from the swarm.

docker service rm web

Conclusion

Phew!! That was a lot, right? But I hope the practical implementation, with screenshots and everything, helped you get the idea of how swarm works.

Docker Swarm is Docker's native technology for managing clusters of Docker nodes and deploying and managing cloud-native apps.

It's similar to Kubernetes. So if you understood this right now. Understanding Kubernetes will become easier for you.

That's it. I hope you learned something from this. Just want to say this, understanding this only won't make you understand everything until you try it on your own. So make sure you practise this.

See you in the next one, until then....peace

https://giphy.com/gifs/fallontonight-jimmy-fallon-peace-out-tonightshow-2nlbKhgnvAK3sR8ffw?utm_source=iframe&utm_medium=embed&utm_campaign=Embeds&utm_term=https%3A%2F%2Fdhruvnakum.xyz%2F