📍 Article principal du cluster : HashiCorp Consul Associate (003) — guide pratique de la certification 2026
Ce tutoriel fait partie du cluster certification Consul Associate. Pour la vue d’ensemble, lisez d’abord le pilier.
Introduction
Vous préparez la certification Consul Associate 003 et il vous faut un environnement de pratique réel — pas un docker-compose qui meurt à chaque redémarrage. Ce tutoriel monte un cluster Consul de production : 3 serveurs en consensus Raft, 2 clients qui hébergent des services applicatifs, le tout sur un VPS Hostinger Premium en utilisant des conteneurs LXC Incus pour simuler 5 machines indépendantes. À la fin, vous aurez un cluster qui survit à la perte d’un serveur, un quorum vérifiable, et un terrain de jeu identique à ce que vous trouverez en entreprise. Toutes les commandes sont testées sur Ubuntu 24.04 LTS avec Consul 1.20.
Prérequis
- Un VPS Hostinger Premium Web Hosting ou supérieur (4 Go RAM minimum, 50 Go SSD) sous Ubuntu 24.04
- Accès SSH root via `ssh root@VOTRE_IP`
- Notions de base Linux (cd, ls, systemctl, journalctl, vim ou nano)
- Une heure devant vous pour la première installation, puis 30 minutes pour les vérifications
- Aucun nom de domaine requis pour cette étape — adresses IP locales suffisent
Étape 1 — Préparer le VPS et installer Incus
Avant de déployer Consul, on monte cinq conteneurs LXC qui jouent le rôle de cinq machines indépendantes. Incus est le successeur communautaire de LXD, beaucoup plus léger qu’un hyperviseur complet et parfait pour simuler des topologies réseau réalistes sur un seul VPS. Cette approche est largement supérieure à un docker-compose pour préparer Consul Associate parce qu’elle expose les vrais flux réseau (gossip, RPC, DNS) entre des hôtes distincts.
# Mise à jour système et outillage de base
apt update && apt upgrade -y
apt install -y curl wget gnupg2 software-properties-common jq unzip
# Installation Incus depuis le dépôt Zabbly stable
curl -fsSL https://pkgs.zabbly.com/key.asc -o /etc/apt/keyrings/zabbly.asc
sh -c 'cat <<EOF > /etc/apt/sources.list.d/zabbly-incus-stable.sources
Enabled: yes
Types: deb
URIs: https://pkgs.zabbly.com/incus/stable
Suites: $(. /etc/os-release && echo ${VERSION_CODENAME})
Components: main
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/zabbly.asc
EOF'
apt update && apt install -y incus
# Initialisation Incus en mode automatique avec stockage ZFS
incus admin init --auto
L’initialisation crée un pool de stockage `default` (sur ZFS si disponible, sinon sur dir), un bridge réseau `incusbr0` avec sous-réseau privé, et configure le démon. Si vous obtenez une erreur de permissions, c’est que `subuid`/`subgid` ne sont pas configurés — relancez `dpkg-reconfigure incus` puis recommencez. Vérifiez avec `incus list` qui doit afficher un tableau vide.
Étape 2 — Créer les cinq conteneurs Consul
On monte trois serveurs Consul (consul-srv-1 à 3) qui formeront le quorum Raft, et deux clients (consul-cli-1 et 2) qui hébergeront des services applicatifs plus tard. Chaque conteneur est une instance Ubuntu 24.04 minimaliste avec 1 Go RAM et 5 Go disque — largement suffisant pour cet exercice.
for i in 1 2 3; do
incus launch images:ubuntu/24.04 consul-srv-$i \
-c limits.memory=1GiB -c limits.cpu=1
done
for i in 1 2; do
incus launch images:ubuntu/24.04 consul-cli-$i \
-c limits.memory=1GiB -c limits.cpu=1
done
# Vérifier que tous les conteneurs sont RUNNING avec une IP
incus list
La sortie doit lister 5 conteneurs en état `RUNNING` avec chacun une IP IPv4 dans la plage `10.x.x.x`. Notez ces IP — vous en aurez besoin pour la configuration Consul. Si un conteneur reste en état `STOPPED`, lancez `incus start consul-srv-1` manuellement et inspectez `incus info consul-srv-1` pour les erreurs.
Étape 3 — Installer Consul 1.20 sur les cinq conteneurs
L’installation se fait depuis le dépôt APT officiel HashiCorp. Cette méthode pratiquet la signature des paquets, simplifie les mises à jour, et installe systemd unit prête à l’emploi. On utilise une fonction shell pour répéter l’opération sur les 5 conteneurs sans copier-coller.
install_consul() {
local target=$1
incus exec $target -- bash -c "
apt update && apt install -y wget gpg coreutils
wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo \"deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com \$(lsb_release -cs) main\" > /etc/apt/sources.list.d/hashicorp.list
apt update && apt install -y consul
consul --version
"
}
for c in consul-srv-1 consul-srv-2 consul-srv-3 consul-cli-1 consul-cli-2; do
install_consul $c
done
Chaque appel doit se terminer par `Consul v1.20.x`. Si une commande échoue avec « certificate verification failed », c’est que le conteneur n’a pas encore d’horloge synchronisée — exécutez `incus exec consul-srv-1 — timedatectl set-ntp true` puis relancez. La signature du dépôt HashiCorp est vérifiée à chaque `apt update` grâce à la clé GPG installée localement.
Étape 4 — Générer la clé de chiffrement gossip
Le chiffrement gossip protège les communications peer-to-peer entre tous les agents Consul. Sans cette clé, n’importe quel hôte du réseau pourrait écouter les événements de membership et la propagation d’état. Pour l’examen et pour la production, c’est un paramètre obligatoire — pas optionnel.
# Générer une clé symétrique 32 octets base64 (depuis l'hôte)
incus exec consul-srv-1 -- consul keygen
# Exemple de sortie : 7XbQyy7YVOC74S3Gh4WJlXjMq7p0xv/ZYx9j8ThLD5o=
GOSSIP_KEY=$(incus exec consul-srv-1 -- consul keygen)
echo "GOSSIP_KEY=$GOSSIP_KEY"
Conservez cette clé en lieu sûr — elle sera identique sur les 5 nœuds. Toute rotation ultérieure devra utiliser `consul keyring -install` pour propager la nouvelle clé sans interrompre le cluster, puis `consul keyring -use` pour activer la nouvelle clé, et enfin `consul keyring -remove` pour supprimer l’ancienne. Ce flow de rotation est précisément ce qui tombe en domaine 10 du syllabus.
Étape 5 — Configurer le serveur Consul #1 (bootstrap)
Le premier serveur démarre avec `bootstrap_expect = 3`, ce qui indique à Consul d’attendre 3 serveurs avant d’élire un leader. C’est le pattern recommandé en production : on évite ainsi un split-brain initial où chaque serveur se croirait seul. Récupérez d’abord les IP de chaque serveur avec `incus list`, puis adaptez la configuration.
SRV1_IP=$(incus list consul-srv-1 -c 4 -f csv | cut -d' ' -f1)
SRV2_IP=$(incus list consul-srv-2 -c 4 -f csv | cut -d' ' -f1)
SRV3_IP=$(incus list consul-srv-3 -c 4 -f csv | cut -d' ' -f1)
echo "Serveurs : $SRV1_IP, $SRV2_IP, $SRV3_IP"
incus exec consul-srv-1 -- bash -c "cat > /etc/consul.d/consul.hcl <<EOF
datacenter = \"dc1\"
data_dir = \"/opt/consul\"
encrypt = \"$GOSSIP_KEY\"
server = true
bootstrap_expect = 3
bind_addr = \"$SRV1_IP\"
client_addr = \"0.0.0.0\"
retry_join = [\"$SRV2_IP\", \"$SRV3_IP\"]
ui_config { enabled = true }
EOF"
incus exec consul-srv-1 -- chown -R consul:consul /etc/consul.d /opt/consul
incus exec consul-srv-1 -- systemctl enable --now consul
incus exec consul-srv-1 -- systemctl status consul --no-pager | head -15
La sortie doit montrer `Active: active (running)`. À ce stade, le serveur tourne mais ne peut pas élire de leader puisque les deux autres serveurs ne sont pas encore configurés — c’est normal. Inspectez les logs avec `incus exec consul-srv-1 — journalctl -u consul -f` dans un autre terminal pour suivre l’évolution dans la suite du tutoriel.
Étape 6 — Configurer les serveurs Consul #2 et #3
Les deux autres serveurs reçoivent une configuration identique au premier sauf pour leur IP de bind et la liste `retry_join`. Une fois ces deux serveurs démarrés, le cluster atteint `bootstrap_expect = 3` et peut élire un leader.
configure_server() {
local name=$1 ip=$2 join1=$3 join2=$4
incus exec $name -- bash -c "cat > /etc/consul.d/consul.hcl <<EOF
datacenter = \"dc1\"
data_dir = \"/opt/consul\"
encrypt = \"$GOSSIP_KEY\"
server = true
bootstrap_expect = 3
bind_addr = \"$ip\"
client_addr = \"0.0.0.0\"
retry_join = [\"$join1\", \"$join2\"]
ui_config { enabled = true }
EOF"
incus exec $name -- chown -R consul:consul /etc/consul.d /opt/consul
incus exec $name -- systemctl enable --now consul
}
configure_server consul-srv-2 $SRV2_IP $SRV1_IP $SRV3_IP
configure_server consul-srv-3 $SRV3_IP $SRV1_IP $SRV2_IP
# Attendre quelques secondes puis vérifier l'état du cluster
sleep 10
incus exec consul-srv-1 -- consul members
La commande `consul members` doit afficher trois lignes en état `alive`, role `server`. Si vous voyez « failed », vérifiez que les conteneurs peuvent se pinguer mutuellement avec `incus exec consul-srv-1 — ping -c 2 $SRV2_IP`. Le quorum Raft est désormais établi et un leader a été élu — vérifiez-le avec `incus exec consul-srv-1 — consul operator raft list-peers`.
Étape 7 — Joindre les clients au cluster
Les agents clients ne participent pas au consensus Raft. Ils servent de relais entre les services applicatifs locaux et le pool de serveurs. Leur configuration est plus simple : pas de `bootstrap_expect`, pas de `server = true`, juste un `retry_join` vers les trois serveurs.
configure_client() {
local name=$1
local ip=$(incus list $name -c 4 -f csv | cut -d' ' -f1)
incus exec $name -- bash -c "cat > /etc/consul.d/consul.hcl <<EOF
datacenter = \"dc1\"
data_dir = \"/opt/consul\"
encrypt = \"$GOSSIP_KEY\"
server = false
bind_addr = \"$ip\"
client_addr = \"127.0.0.1\"
retry_join = [\"$SRV1_IP\", \"$SRV2_IP\", \"$SRV3_IP\"]
EOF"
incus exec $name -- chown -R consul:consul /etc/consul.d /opt/consul
incus exec $name -- systemctl enable --now consul
}
configure_client consul-cli-1
configure_client consul-cli-2
sleep 5
incus exec consul-srv-1 -- consul members
Vous devez maintenant voir cinq lignes : trois serveurs et deux clients, tous en état `alive`. Notez que les clients écoutent sur `127.0.0.1` côté API HTTP — c’est la pratique standard, on ne les expose jamais sur l’extérieur. Les services applicatifs locaux parlent à l’API HTTP du client agent local en localhost.
Étape 8 — Activer l’interface Web Consul
L’interface Web est précieuse pour visualiser l’état du cluster pendant les révisions. Elle est embarquée dans le binaire Consul (option `ui_config.enabled = true` déjà ajoutée) et écoute sur le port 8500 du serveur. Pour y accéder depuis votre navigateur, on crée un proxy via SSH local.
# Depuis votre poste (pas le VPS), ouvrez un tunnel SSH vers le serveur 1
ssh -L 8500:$SRV1_IP:8500 root@VOTRE_VPS_IP
# Puis ouvrez http://localhost:8500/ui dans votre navigateur
L’UI affiche les nœuds, les services, les ACL et les key/value. C’est l’outil de référence pour interpréter visuellement l’état du cluster — beaucoup de questions de l’examen exploitent cette UI mentalement (« quel onglet montre les health checks d’un service ? »). Familiarisez-vous avec elle dès maintenant pour gagner du temps en révision.
Étape 9 — Vérification finale et tests de résilience
Le cluster est opérationnel. On effectue trois vérifications qui doivent toutes passer pour qu’on puisse considérer l’environnement prêt pour les exercices avancés du syllabus.
# Vérif 1 — Quorum Raft et leader actuel
incus exec consul-srv-1 -- consul operator raft list-peers
# Vérif 2 — Membres du cluster (5 alive)
incus exec consul-srv-1 -- consul members
# Vérif 3 — Test de résilience : éteindre un serveur, vérifier que le quorum tient
incus stop consul-srv-2
sleep 10
incus exec consul-srv-1 -- consul members
incus exec consul-srv-1 -- consul operator raft list-peers
# Le leader doit toujours être identifié, le cluster reste opérationnel
incus start consul-srv-2
sleep 10
incus exec consul-srv-1 -- consul members # srv-2 doit revenir alive
Si le cluster tient le coup avec un seul serveur en panne (2 sur 3 = quorum maintenu), votre topologie est correcte. Si vous éteignez deux serveurs simultanément, le cluster perd le quorum et bascule en lecture seule — c’est le comportement attendu et c’est exactement ce qu’on attend qu’un candidat Consul Associate sache expliquer en domaine 2b.
Comprendre Raft en pratique — ce que vous venez de monter
Le cluster que vous venez de bootstrapper repose sur l’algorithme de consensus Raft. C’est un point souvent mal compris des candidats Consul Associate : Raft n’est pas un protocole de réplication maître-esclave, c’est un protocole d’élection et de réplication d’un journal de commandes. Concrètement, à chaque écriture sur le catalogue Consul (un nouveau service enregistré, une intention créée, une clé KV modifiée), le leader élu transforme cette opération en une entrée de log, la propage à tous les followers, attend l’acquittement de la majorité (au moins 2 sur 3 dans votre cas), puis applique la commande à sa propre machine d’état avant de répondre au client. Ce protocole garantit que tous les serveurs convergent vers le même état tant que la majorité fonctionne.
Trois propriétés à retenir pour l’examen. Premièrement, une seule lettre élue à la fois dans le cluster — pas de double leader possible grâce à l’incrément du « term » Raft à chaque élection. Deuxièmement, les écritures passent toujours par le leader, jamais par un follower, sinon elles sont redirigées via RPC. Troisièmement, les lectures peuvent être servies par n’importe quel serveur avec différents niveaux de cohérence (`default`, `consistent`, `stale`) que vous configurez côté client. Cette dernière distinction tombe régulièrement en domaine 4d du syllabus.
Pour visualiser le comportement, lancez `consul operator raft list-peers` après avoir éteint le serveur 1, puis observez l’élection automatique d’un nouveau leader parmi les serveurs 2 et 3. Le délai d’élection par défaut est de 1 seconde — durant cette fenêtre, le cluster est en lecture seule. Si vous augmentez ce paramètre via `raft_protocol` ou les délais Raft custom, vous gagnez en stabilité face aux flaps réseau mais vous augmentez le temps de basculement.
Pourquoi Incus plutôt que Docker ou Vagrant pour ce labo
Trois alternatives s’offrent à vous pour monter un labo Consul multi-nœuds : Incus (ce tutoriel), Docker Compose, et Vagrant avec VirtualBox. Le choix d’Incus n’est pas anodin et mérite d’être justifié, parce qu’il colore directement la qualité de votre apprentissage.
Docker Compose est attractif à première vue car il s’installe rapidement et tient sur un fichier YAML. Mais il agrège tous les conteneurs dans un même namespace réseau Linux, ce qui simule très mal une vraie topologie. Plus grave encore, le NAT par défaut masque les vrais flux UDP/TCP entre nœuds et complique le debug avec tcpdump. C’est pédagogiquement médiocre pour Consul Associate où la compréhension fine des ports gossip et RPC est testée.
Vagrant + VirtualBox donne des VMs complètes avec des piles réseau totalement indépendantes — c’est le plus proche d’une vraie production. Mais le coût en ressources est énorme : 5 VMs Ubuntu 24.04 mangent 10 Go de RAM minimum et plusieurs gigas de disque chacune. Sur un VPS Hostinger Premium à 4 Go RAM, c’est intenable.
Incus est le compromis idéal : conteneurs LXC légers (système Linux complet par conteneur, pas un namespace partagé comme Docker), pile réseau totalement indépendante par conteneur (vrais bridges, vraies tables de routage, vraies règles iptables visibles), et empreinte mémoire minime (1 Go par conteneur suffit pour Consul). Vous avez l’isolation pédagogique d’une VM avec le coût opérationnel d’un conteneur. C’est la même technologie que Canonical utilise dans ses tests internes et que Linux Containers maintient officiellement depuis le fork de LXD en 2023.
Erreurs fréquentes
| Erreur | Cause | Solution |
|---|---|---|
| `consul members` ne montre que le serveur local | Pare-feu UFW bloque les ports 8300-8302 | `incus exec consul-srv-1 — ufw allow from 10.0.0.0/8` ou désactiver UFW dans les conteneurs de test |
| « No cluster leader » dans les logs | Moins de 3 serveurs joints, `bootstrap_expect` non atteint | Vérifier que les 3 serveurs voient les 2 autres dans `retry_join` |
| Mismatch de gossip key | Clé différente sur un serveur | Comparer `/etc/consul.d/consul.hcl` sur les 5 nœuds — la valeur `encrypt` doit être identique |
| Service consul ne démarre pas | Permissions sur `/opt/consul` ou `/etc/consul.d` | `chown -R consul:consul /opt/consul /etc/consul.d` puis `systemctl restart consul` |
| Pas d’élection de leader après 30 secondes | Horloges désynchronisées entre conteneurs | Vérifier `timedatectl status` sur chaque conteneur, activer NTP partout |
Adaptation au contexte ouest-africain
Pour les apprenants à Dakar, Abidjan ou Bamako, l’utilisation d’un VPS Hostinger Premium pour ce labo présente plusieurs avantages concrets : tarif à 2,99 USD/mois payable en carte CFA Visa internationale (compatible Wave/Orange Money via virement), facturation en euros qui évite la double conversion, et data center européens avec latence d’environ 80-110 ms depuis l’Afrique de l’Ouest — largement suffisante pour SSH et travail à distance. Si votre connexion Internet est instable, lancez le tunnel SSH avec `mosh` plutôt qu’OpenSSH classique : la session survit aux coupures de quelques minutes.
Une approche alternative pour les apprenants qui ont un PC fixe relativement puissant (8 Go RAM minimum, processeur récent) : installer Incus directement sur Ubuntu 24.04 en local, avec les cinq conteneurs sur la machine de travail. Cette option supprime le coût VPS mais demande un PC qui reste allumé pendant les sessions de pratique — peu pratique avec des coupures électriques fréquentes. Pour la phase ACL et service mesh des satellites suivants, le VPS reste préférable.
Tutoriels frères
- Service discovery et health checks Consul — du JSON à la résolution DNS
- ACL Consul en profondeur — bootstrap, policies, tokens et rotation
Pour aller plus loin
- 🔝 Retour au pilier : HashiCorp Consul Associate (003) — guide pratique de la certification 2026
- Documentation officielle d’installation : developer.hashicorp.com/consul/docs/install
- Référence des paramètres `agent.hcl` : developer.hashicorp.com/consul/docs/agent/config
- Suggestion suivante : enregistrez vos premiers services et health checks avec le tutoriel service discovery
FAQ
Pourquoi 3 serveurs et pas 5 ?
Trois serveurs tolèrent la perte d’un nœud sans perdre le quorum. Cinq serveurs tolèrent la perte de deux nœuds. Pour un environnement d’apprentissage ou un cluster PME, trois est le standard suffisant. Cinq est recommandé en production critique multi-zone, mais demande plus de ressources et une bande passante WAN plus généreuse.
Peut-on tester ce labo sur Docker plutôt qu’Incus ?
Techniquement oui, mais Docker mélange réseaux et namespaces de manière qui obscurcit les flux Consul. Incus expose des conteneurs LXC qui se comportent comme de vraies machines — vous voyez clairement gossip vs RPC vs DNS sur des hôtes distincts. Pour préparer la certification, Incus est nettement supérieur.
Le `retry_join` est-il vraiment nécessaire si on utilise un cloud auto-discovery ?
Sur AWS, Azure ou GCP en production, on peut remplacer `retry_join` par `retry_join_ec2` ou similaire qui utilise les tags de l’instance pour découvrir les serveurs. Pour l’examen et pour ce labo VPS, le `retry_join` statique est obligatoire.
Faut-il sécuriser TLS et ACL dès cette étape ?
Non. La pédagogie de ce cluster est d’isoler chaque concept. Vous ajouterez TLS et ACL dans le satellite « ACL en profondeur ». Pour le moment, votre cluster est en mode insecure mais isolé dans des conteneurs privés — acceptable pour l’apprentissage uniquement.
Mots-clés secondaires : consul installation tutoriel, cluster raft 3 serveurs, hostinger consul, incus lxc consul, gossip encryption setup, consul 1.20 ubuntu 24.04, bootstrap_expect, consul members alive