Cluster RabbitMQ avec Docker Swarm
⚠️ Important ! Cet article reste en ligne pour partager certaines informations mais techniquement il n'est plus possible de l'appliquer dans le sens où le dépôt des sources de l'image Docker a été supprimé définitivement.
RabbitMQ est un logiciel open source d'agent de message, qui implémente le procotole AMQP (Advanced Message Queuing Protocol) et est écrit en Erlang (source: wikipedia). Les bibliothèques client à interface sont disponibles dans beaucoup de language (Python, Perl, PHP, ...), je ne vais pas rester sur l'outil, vous trouverez plein de choses sur le net.
L'installation de RabbitMQ n'a rien de très compliqué en soit (y'a juste un package à installer dans le meilleur des cas) mais ça reste insuffisant pour avoir de la haute dispo, ce qu'on cherche dans la plupart des cas. Cet article vise donc le déploiement d'une stack RabbitMQ (et Consul) via Docker Swarm 😃. Je pars du principe que vous avez au minimum vos noeuds (managers/workers) de déployés (je prépare aussi un article sur le sujet avec Terraform/Scaleway).
L'idée ici étant de déployer une stack RabbitMQ sur vos noeuds avec X réplicas, par exemple avoir un total de 20 instances RabbitMQ sur 4 noeuds (ça fait 5/noeud) afin de profiter d'une haute dispo, biensûr le RabbitMQ est dans un mode de clustering automatique. Vous pouvez donc passer de 20 à 60 instances, cela sera ajouté automatiquement au cluster, même fonctionnement à l'inverse, sur ce niveau, vous vous occupez de rien !
On commence par cloner le dépôt :
git clone https://github.com/djerfy/Dockerfiles.git
cd Dockerfiles/rabbitmq-autocluster
Maintenant il ne reste plus à adapter la configuration et à déployer la stack ! Dans un premier temps ouvrez le fichier docker-stack.yml
pour l'ajustement des valeurs (ex: PlaceHereYourSecretErlangCookie
pour le secret du cluster, PlaceHereYourAdminPassword
pour le password d'admin) :
version: "3"
services:
consul:
image: "consul:latest"
labels: [app=amqp-consul]
ports:
- "8500:8500"
networks:
- amqp
environment:
- 'CONSUL_BIND_INTERFACE=eth1'
- 'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt": true}'
command: agent -server -ui -client=0.0.0.0 -bootstrap-expect=2 -retry-join=consul
deploy:
replicas: 2
placement:
constraints: [node.role == manager]
resources:
reservations:
memory: 128M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
update_config:
parallelism: 1
delay: 10s
failure_action: continue
rabbitmq:
image: "djerfy/rabbitmq-autocluster:latest"
labels: [app=amqp-rabbitmq]
ports:
- "5672:5672"
- "15672:15672"
networks:
- amqp
environment:
- 'AUTOCLUSTER_TYPE=consul'
- 'AUTOCLUSTER_CLEANUP=true'
- 'AUTOCLUSTER_DEREGISTER_AFTER=60'
- 'AUTOCLUSTER_DELAY=20'
- 'CLEANUP_WARN_ONLY=false'
- 'CONSUL_HOST=consul'
- 'CONSUL_PORT=8500'
- 'CONSUL_SVC=rabbitmq'
- 'CONSUL_SVC_ADDR_AUTO=true'
- 'RABBIMQ_ERLANG_COOKIE=PlaceHereYourSecretErlangCookie'
- 'RABBITMQ_DEFAULT_VHOST=/'
- 'RABBITMQ_DEFAULT_USER=admin'
- 'RABBITMQ_DEFAULT_PASS=PlaceHereYourAdminPassword'
command: rabbitmq-server
deploy:
replicas: 4
resources:
reservations:
memory: 256M
restart_policy:
condition: on-failure
delay: 15s
max_attempts: 3
window: 120s
update_config:
parallelism: 2
delay: 20s
failure_action: continue
networks:
amqp:
Lorsque tout ça est bien adapté à vos besoins, vous pouvez déployer la stack :
docker stack deploy -c docker-stack.yml amqp
Un docker service ls
doit vous afficher vos 2 services, Consul et RabbitMQ :
ID NAME MODE REPLICAS IMAGE PORTS
yigqvai7slc5 amqp_consul replicated 2/2 consul:latest *:18500->8500/tcp
fx3vhp6bhxrr amqp_rabbitmq replicated 4/4 <your_name>/rabbitmq-autocluster:latest *:5672->5672/tcp,*:15672->15672/tcp
Rendez-vous sur l'interface de management du RabbitMQ (IP de l'hôte sur le port 15672) et utiliser le compte d'admin configuré dans le docker-stack.yml
. Vous devriez voir vos noeuds de cette manière :
Et sur Consul (IP de l'hôte sur le port 8500) ceci :
Avec la liste des services enregistrés (consul et rabbitmq):
Après c'est à vous de scaler le RabbitMQ selon vos besoins, l'entrée/sortie dans le cluster sera automatique, c'est pas beau ça ? 😋
docker service update --replicas=50 amqp_rabbitmq
Il y a d'autres articles en préparation concernant le clustering RabbitMQ, soyez donc patient pour voir la suite (abonnez-vous au flux RSS, ce sera plus simple) !
Enjoy!
XorHak
PS n°1 : vos noeuds seront automatiquement ajoutés au cluster mais le fonctionnement n'est pas optimale par défaut (c'est à dire que les queues ne sont pas répliqués sur chaque noeud par défaut). Connectez-vous sur l'un des noeuds (le premier c'est bien) puis ajoutez cette policy : rabbitmqctl set_policy ha-all "" '{"ha-mode":"all","ha-sync-mode":"automatic"}'
PS n°2 : le Consul est en cluster mais limité à 2 uniquement (sinon changer aussi la valeur de l'option -bootstrap-expect
.
PS n°3 : vous remarquerez qu'il n'y a plus le Dockerfile
dans le dépôt car au final j'ai simplement repris un existant dont les sources Github sont ici.
PS n°4 : ce fonctionnement est limité aux versions 3.6.x
de RabbitMQ