rabbitmq_logo
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

Le build de l'image va télécharger 2 modules qui sont nécessaires pour le cluster automatique, rassurez-vous tout ça est transparent pour vous ! Pour construire l'image, c'est trÚs simple :

docker build -t <your_name>/rabbitmq-autocluster:0.10.0 .
docker image tag <your_name>/rabbitmq-autocluster:0.10.0 <your_name>/rabbitmq-autocluster:latest

N'oubliez pas de l'envoyer sur le registry (vous pouvez utiliser le DockerHub) pour que l'image soit disponible sur tous vos noeuds. Connectez-vous avec votre compte puis envoyer l'image (et le tag latest) :

docker login
docker image push <your_name>/rabbitmq-autocluster:0.10.0
docker image push <your_name>/rabbitmq-autocluster:latest

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: <your_name> pour l'image, 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=eth0'
            - 'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt": true}'
        command: agent -server -ui -client=0.0.0.0 -bootstrap-expect=1 -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: "<your_name>/rabbitmq-autocluster:latest"
        labels: [app=amqp-rabbitmq]
        ports:
            - "5672:5672"
            - "15672:15672"
        networks:
            - amqp
        environment:
            - 'AUTOCLUSTER_TYPE=consul'
            - 'AUTOCLUSTER_CLEANUP=true'
            - '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'
        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 :
djerfy-macbook-2017-10-21-a--19.44.03

Et sur Consul (IP de l'hĂŽte sur le port 18500) ceci :
djerfy-macbook-2017-10-21-a--19.44.38

AprĂšs c'est Ă  vous de scaler le RabbitMQ/Consul selon vos besoins, l'entrĂ©e/sortie dans le cluster sera automatique, c'est pas beau ça ? 😋

docker service update --replicas=5 amqp_consul
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 : pour les personnes qui ne souhaitent pas se prendre la tĂȘte (ou qui n'ont pas le temps), l'image djerfy/rabbitmq-autocluster:latest est disponible, vous aurez juste Ă  dĂ©finir les variables d'environnement RABBIMQ_ERLANG_COOKIE et RABBITMQ_DEFAULT_PASSWORD lors du lancement. Je dois encore terminer quelques configurations comme les descriptions, wiki, ... rien de trĂšs critique pour le fonctionnement du service.

PS n°2 : vos noeuds seront automatiquement ajoutés au cluster mais le fonctionnement n'est pas trÚs optimale par défaut (c'est à dire que les queues ne sont pas répliqués sur chaque noeud).