
Consul est un outil open source de Hashicorp permettant de faciliter la découverte de services réseaux et leur configuration dynamique dans des environnements distribués. Il permet de connecter les applications et services entre eux, de gérer la configuration à l’échelle et d’assurer la haute disponibilité des services grâce à son mécanisme de clustering et de supervision.
1. Fonctionnement
Consul repose sur une architecture distribuée avec deux types de nœuds principaux : les serveurs et les agents clients.
Les serveurs Consul sont responsables de stocker l'état du cluster, d'exécuter l'élection du leader et de répondre aux requêtes des clients. Pour assurer un fonctionnement en mode haute disponibilité, le service Consul est mis en cluster. Pour des questions de quorum, cela exige un minimum de trois serveurs. Le protocole RAFT est utilisé par Consul pour assurer la cohérence des données entre les serveurs du cluster. Raft fonctionne en élisant un leader parmi les serveurs du cluster. Ce leader est responsable de la gestion des écritures et de la réplication des données aux autres serveurs appelés followers. Si le leader devient indisponible, un nouveau leader est automatiquement élu via un processus de vote parmi les nœuds restants.
Un des mécanismes clés de Consul est le protocole Gossip, utilisé pour la communication entre les nœuds. Il repose sur un algorithme de dissémination d’informations pair à pair, permettant aux nœuds d'échanger des informations sur leur état et de détecter les pannes rapidement. Ce protocole assure une mise à jour efficace des données dans tout le cluster et permet d’améliorer la tolérance aux pannes en évitant les points uniques de défaillance.
Les agents clients, quant à eux, s'exécutent sur chaque machine et servent d'interface entre les services et les serveurs Consul, facilitant ainsi l'enregistrement et la découverte des services.
Pour la suite de la démonstration, je vais déployer trois serveurs Consul sous Ubuntu 24.04 et deux agents.
Nom | IP | Rôle |
consul01 | 192.168.69.11 | Serveur Consul |
consul02 | 192.168.69.12 | Serveur Consul |
consul03 | 192.168.69.13 | Serveur Consul |
www01 | 192.168.69.14 | Serveur Apache |
www02 | 192.168.69.15 | Serveur Apache |
lb01 | 192.168.69.31 | Load Balancer HAProxy |
lb02 | 192.168.69.32 | Load Balancer HAProxy |
2. Installation du cluster
Hashicorp propose des paquets précompilés pour différentes distributions ainsi que des binaires. Il n’y a pas spécifiquement de dépendances. Pour une installation sous Ubuntu 24.04, c’est très simple :
Et passons maintenant à la configuration de notre serveur dans le fichier /etc/consul.d/consul.hcl. Cela implique de définir dans le retry_join, les IP des serveurs consul et dans advertise_addr, l’IP locale du serveur.
Si tout s’est bien passé, nous pouvons vérifier que notre cluster est bien formé et identifier le leader avec la commande consul operator raft list-peers.
Le fait d’avoir activé l’interface graphique permet de visualiser l’état du cluster et les services en se connectant sur le port 8500 du service (voir Figure 1).
La jonction du cluster a été jusqu’ici permise sans sécurité. Il convient donc de chiffrer le protocole Gossip. Consul permet d’utiliser une clé de chiffrement partagée pour garantir que seuls les nœuds autorisés peuvent rejoindre le cluster. Il convient donc de générer une clé :
Puis de l’ajouter au fichier de configuration de consul à la ligne :
3. Les services Consul
Les services Consul constituent des entités exposées sur le réseau dans le but d’être consommées par des applications. L’exposition de services réseaux permet de les rendre découvrables de manière dynamique pour d’autres services. La vérification de l’état de santé des services permet de gérer la disponibilité de celui-ci et éventuellement de basculer sur un autre nœud qui fournit ce même service, mais celui-ci fonctionnel.
Nous allons ajouter un premier service sur nos deux agents www01 et www02. Pour l’installation des agents, c’est la même chose avec la variable server positionnée à false. Par conséquent, il n’est pas utile de détailler le processus d’installation.
Vérifions déjà que nos nœuds ont rejoint le cluster consul avec la commande consul members :
Sur chacun de ces nœuds, j’ai déployé un service apache2 sans configuration particulière.
Sur les deux nœuds www, nous allons donc créer un fichier /etc/consul.d/service-apache.hcl contenant :
L’ID et le nom du service sont forcément uniques parmi les machines qui exposent un même service. Il en va de la logique de disponibilité du service exposé par Consul. Il peut y avoir toutefois plusieurs health checks associés à un même service, donc les délais de vérification sont à adapter à la criticité, la rapidité de bascule attendue ainsi qu’au temps d’exécution de ce health check. Pour que le health check soit pris en compte, il est nécessaire de redémarrer Consul.
En fonction des types de services à exposer, Consul propose plusieurs types de checks pour vérifier l’état du service : TCP, UDP, HTTP pour les plus basiques. De façon plus élaborée, à la manière d’une solution de supervision, il est également possible de faire appel à un script externe.
Pour exposer par exemple le service SSH sur www01, un check TCP fera l’affaire. J’ai pris l’habitude d’exposer le SSH sur mes machines, ce qui me donne un état déjà très basique de mes nodes. Cela donnerait donc :
Pour afficher les services connus :
Vérifions maintenant les nœuds exposants le service appelé service-apache :
4. Interroger Consul
Jusqu’ici nous avons utilisé les commandes consul pour configurer et interroger l’état du cluster et les services Consul. Dans le cas d’une application en micro services, Consul propose deux modes d’interrogation pour identifier les services : le DNS et une API REST.
Consul offre un service DNS sur le port 8600, dynamiquement peuplé depuis le catalogue des services. Celui-ci est donc mis à jour lors du changement d’état de ceux-ci. Les services sont exposés dans une pseudo zone service.consul :
Si on simule une panne ou une maintenance sur www01 :
On constate que consul a mis à jour les enregistrements retournés :
Pour sortir www01 de la maintenance :
Et les deux nœuds sont de retour :
D’une autre manière et comme je l’indiquais juste avant, Consul offre une API mise à jour de manière tout aussi dynamique :
5. Le KV Store de Consul : stockage clé-valeur distribué
Le KV Store de Consul est un service distribué permettant de stocker des paires clé-valeur de manière simple et scalable. Il est souvent utilisé pour stocker des configurations dynamiques que les services peuvent récupérer en temps réel, partager des métadonnées entre services ou encore conserver des secrets et informations sensibles. C’est d’ailleurs le backend historique de Hashicorp Vault.
Contrairement à une base de données traditionnelle, le KV Store de Consul fonctionne comme un registre hiérarchique, similaire à un système de fichiers, où chaque clé peut être organisée en répertoires logiques.
L'ajout d'une valeur dans le KV Store se fait via la CLI Consul :
Pour récupérer la valeur associée :
Il est également possible de récupérer toutes les clés d'un préfixe donné :
Enfin, pour la suppression :
L’un des atouts du KV Store est la possibilité de surveiller les changements en temps réel. Par exemple, un service peut être configuré pour écouter les modifications d'une clé donnée et réagir automatiquement.
En CLI :
Ou via l’API REST en envoyant une requête avec un index de modification pour être notifié uniquement si la valeur change :
6. Sauvegarde et restauration
Le fait que les données Consul soient répliquées entre les serveurs n’est pas une protection contre une perte de données en cas de défaillance. Comme tout système gérant des données, il est crucial de mettre en place un mécanisme de sauvegarde et de restauration.
La sauvegarde consul crée un snapshot des données Consul comprenant les services, les ACL, les tokens et les données du KV Store.
Pour créer une sauvegarde, il suffit d’utiliser la commande consul snapshot :
Une sauvegarde n’a de valeur que si elle est faite régulièrement, il conviendra donc d’automatiser cette tâche avec un cron job pour une sauvegarde régulière. Par exemple, pour réaliser une sauvegarde quotidienne à 2h06 du matin avec une purge à 30 jours :
En cas de panne ou de corruption des données, une restauration rapide peut être effectuée sur le node qui est le leader du cluster avec la commande :
7. Sécurisation des accès avec les ACL
Les ACL (Access Control Lists) sont essentielles pour sécuriser les accès aux services et aux données stockées dans Consul. Elles permettent d’attribuer des permissions granulaires aux utilisateurs et aux applications en fonction de rôles définis. Par défaut, les ACL sont désactivées dans Consul et jusqu’ici nous avions libre accès à l’ensemble des données Consul que ce soit en web ou en CLI.
Pour les activer, il faut modifier le fichier de configuration du serveur Consul (/etc/consul.d/consul.hcl) et ajouter le bloc ci-dessous puis redémarrer le service consul :
La stratégie par défaut est de refuser l’accès. On commence donc par générer un bootstrap token, qui aura tous les droits sur le cluster et qu’il faut donc stocker dans un espace sécurisé :
Sans authentification, il n’est plus possible d’interagir avec consul :
Sauf à utiliser le secret ID du bootstrap token, cela vaut aussi pour l’interface web :
Les ACL fonctionnent avec un système de politiques (policies) qui définissent les droits associés aux ressources consul. Les droits sont simples : read, write, list, deny. Les permissions quant à elles s’appliquent sur les ressources service, node, key, acl, etc..
Par exemple, une politique autorisant uniquement la lecture des configurations KV peut être définie comme suit dans un fichier rules.hcl :
La politique de permissions doit ensuite être créée depuis ce fichier de définition dans Consul :
Une fois la politique créée dans Consul, un jeton d’accès ayant les droits d’utiliser ces permissions doit être créé. Ce jeton d’accès (token) sera ensuite utilisé par les machines et applications pour s’authentifier et obtenir des autorisations d’accès aux données stockées dans Consul. La création d’un token associé à cette politique se fait de la manière suivante :
Le token généré devra être utilisé par les services qui doivent accéder aux données KV avec cette restriction. Il est possible d’exploiter un token directement dans la configuration de l’agent avec cette configuration :
8. Consul Template
Consul Template est un outil permettant de générer automatiquement des fichiers de configuration en fonction des données stockées dans Consul. Consul Template surveille les données stockées dans Consul et met à jour la configuration en cas de changement. La configuration devient ainsi dynamique en fonction des changements de topologie de l’infrastructure. Un cas d’usage fréquent est la mise à jour de la configuration de HAProxy.
Commençons par créer un fichier /etc/consul-template/haproxy.ctmpl contenant :
Le format est classique, c’est du Jinja2 utilisé dans les templates Ansible. Ce template boucle sur les services enregistrés dans consul appelés service-apache-80 et ajoute dynamiquement chaque instance. Une version plus évoluée utiliserait les clés du KV Store pour peupler de manière plus complète la configuration de HAProxy.
Générons un fichier de configuration pour consul-template qui se sourcera sur le template pour générer la configuration HAProxy. Je vais ici utiliser le token de bootstrap pour garder l’article concis, mais en cas réel, il est requis de mettre en place des ACL et d’utiliser un token dédié. Voici ce à quoi ressemble donc notre fichier /etc/consul-template/config.hcl :
Générons la configuration dynamique depuis consul avec consul-template :
En production, un service systemd sera à créer. Vérifions la configuration générée :
Félicitations, nous avons un HAProxy, basique certes, mais entièrement dynamique si on doit ajouter des serveurs Apache pour gérer la charge et dont aucune ligne de configuration ou playbook ansible n’a été nécessaire pour prendre en compte les changements.
Conclusion
Voici pour ce tour d’horizon sur Consul qui je l’espère aura évoqué votre intérêt. Il resterait encore beaucoup à dire comme le chiffrement des communications, les tags, détailler davantage les ACL et se plonger dans les fonctionnalités de service mesh.
