I once configured RabbitMQ
cluster as a single Docker Swarm service. Time has come to share this way with the world.
If you later find this article useful take a look at the disclaimer for information on how to thank me.
Introduction
I’ll assume you know what RabbitMQ
is and why we need to configure its cluster.
Several years ago, I had to write a script which configures RabbitMQ
cluster. RabbitMQ
was deployed as a containerized workload orchestrated by Docker Swarm
. The script had to handle various use cases: first deployment, redeployment, reboot of VMs, adding one restarted replica to the cluster, adding 2 replicas, etc… It’s important to note that the service was part of PaaS
where all services were deployed using deployment script wrapping docker stack
cli. We’ll call it deployer.sh
. So to deploy RabbitMQ
, one had to run ./deployer.sh -deploy rabbitmq.
One of the main challenges was creating a single Docker Swarm
service. Interestingly, developers I knew proposed to configure several services like rabbitmq-1
, rabbitmq-2
, rabbitmq-3
. Moreover, some open-source repositories showed how to do it. I even heard that someone did that in the industry in the past. Regardless, it just didn’t make sense to me. We’ll see below why and how I eventually managed to configure it.
First we’ll discuss why to configure RabbitMQ cluster as a single service. Then I’ll show how to configure it.
Why to configure RabbitMQ cluster as a single Docker Swarm service
In short, because you want to treat RabbitMQ
service as a single unit. That might be needed while scaling the service, for example. If you have 3 services like rabbitmq-1
, rabbitmq-2
, rabbitmq-3
how do you scale them? I would call their automatic management messy to say the least.
The same applies to deployment using deployer.sh
. How would you deploy, undeploy, redeploy RabbitMQ
when you have 3 services? The answer is obvious. However, it’s just a bad way to manage a single service.
Reasoning and implementation should treat RabbitMQ
as a single service. It will just have 3 replicas and cluster configured inside the containers. Let’s now see a basic demo on how to do it.
RabbitMQ cluster as a single Docker Swarm service demo
Demo Prerequisites
Install and configure on your machine:
- docker
- docker-swarm
- git
The tutorial assumes familiarity with basic git, docker and docker-compose commands.
Demo
Firstly, clone rabbitmq_cluster repository from my GitHub. Next follow below steps:
- Create docker config:
docker config create rabbitmq-config rabbitmq.conf
- Create swarm network:
docker network create --driver overlay prod-net
- Deploy rabbitmq cluster as docker swarm service:
docker stack deploy -c docker-compose.yml cluster
- Find virtual ip of each container
docker exec -i [container_ip] hostname -i
- Modify
/etc/hosts
of each container to contain entries of other 2 containers:
For example for cluster_rabbitmq.1...
container run:
docker exec -it [rabbitmq1_container_ip] bash
bash-5.0# echo "10.0.1.9 rabbitmq-2" >> /etc/hosts
bash-5.0# echo "10.0.1.10 rabbitmq-3" >> /etc/hosts
- Verify cluster is configured by running in any container:
docker exec -it [rabbitmq1_container_ip] bash
bash-5.0# rabbitmqctl cluster_status
You should see 3 nodes in cluster:
...
Running Nodes
rabbit@rabbitmq-1
rabbit@rabbitmq-2
rabbit@rabbitmq-3
...
RabbitMQ cluster configuration summary
RabbitMQ cluster is configured using classic_config
in rabbitmq.conf
.
See details here
cluster_formation.classic_config.nodes.1 = rabbit@rabbitmq-1
cluster_formation.classic_config.nodes.2 = rabbit@rabbitmq-2
cluster_formation.classic_config.nodes.3 = rabbit@rabbitmq-3
rabbitmq-*
became the container name thanks to the service template"rabbitmq-{{.Task.Slot}}"
. See details about service-templates here.rabbit@rabbitmq-*
is the expected node name from the point of view of RabbitMQ cluster.
Summary
So, to implement the above idea I automated it using bash script. Today, of course, I’d use Kubernetes
instead of Docker Swarm
. Moreover, Kubernetes
operator would replace the script. Maybe, you did it already and want to share your project? Feel free to do so in the comments.
That’s it about configuring RabbitMQ cluster as a single Docker Swarm service. As always, feel free to share. If you found this article useful, take a look at the disclaimer for information on how to thank me.
Bonus: Recommended RabbitMQ courses on Pluralsight:
Scaling Applications with Microservices, MassTransit, and RabbitMQ
Sign up using this link to get exclusive discounts like 50% off your first month or 15% off an annual subscription)
Recommended books on Amazon: