Retour au blog
linux22 min de lecture9 juin 2026

Clusters Linux : haute disponibilité de A à Z

HAProxy, Keepalived/VRRP, Pacemaker, Corosync, Galera Cluster, NFS partagé : construisez une infrastructure zéro downtime avec des outils open source éprouvés.

Un cluster est un ensemble de serveurs qui travaillent ensemble pour former un système unique plus fiable, plus performant ou plus puissant. En infrastructure Linux, on distingue trois grandes familles : les clusters de haute disponibilité (HA) qui éliminent les points de défaillance uniques, les clusters de répartition de charge (Load Balancing) qui distribuent le trafic, et les clusters HPC (High Performance Computing) pour le calcul intensif. Ce guide couvre les architectures, outils et configurations concrets pour les deux premiers types.

Concepts fondamentaux

Pourquoi un cluster ?

L'objectif est simple : si un serveur tombe, le service continue. Les métriques clés sont :

  • Disponibilité (Availability) : exprimée en pourcentage du temps d'uptime (99.9% = 8h d'indispo/an, 99.99% = 52 min/an, 99.999% = 5 min/an)
  • RTO (Recovery Time Objective) : temps maximum acceptable pour restaurer le service après une panne
  • RPO (Recovery Point Objective) : perte de données maximale acceptable (en temps)
  • SPOF (Single Point of Failure) : composant dont la panne provoque l'arrêt complet du service

Types de clustering

  • Active/Passive (HA) : un nœud actif + un nœud en veille. Failover automatique en cas de panne. Ressources doublées mais non utilisées.
  • Active/Active (Load Balancing) : tous les nœuds traitent du trafic simultanément. Meilleure utilisation des ressources.
  • N+1 : N nœuds actifs + 1 de secours. Compromis entre coût et disponibilité.
  • HPC (High Performance Computing) : calcul distribué sur des dizaines ou milliers de nœuds (Slurm, PBS, OpenMPI).

Un cluster n'est pas une solution de sauvegarde. Si une corruption de données se propage sur tous les nœuds, votre cluster 'hautement disponible' est entièrement corrompu. Cluster ≠ backup.

Architecture typique d'un cluster HA web

bash
# Architecture 3 nœuds : Load Balancer + 2 serveurs web
#
#   Internet
#      │
#      ▼
#  ┌──────────────────┐
#  │  Load Balancer   │  ← HAProxy (actif)
#  │  IP: 10.0.0.1    │    +
#  │  VIP: 10.0.0.100 │  ← Keepalived (IP virtuelle)
#  └────────┬─────────┘
#           │
#    ┌──────┴──────┐
#    ▼             ▼
# ┌──────┐      ┌──────┐
# │ Web1 │      │ Web2 │   ← Serveurs Apache/Nginx
# │10.0.0.2│    │10.0.0.3│   ← Partagent le même storage
# └──────┘      └──────┘
#                  │
#              ┌───┴───┐
#              │  DB   │   ← MariaDB (ou Galera Cluster)
#              │10.0.0.4│
#              └───────┘

HAProxy — Load Balancer de référence

HAProxy (High Availability Proxy) est le standard de facto pour la répartition de charge HTTP/TCP. Il est utilisé par GitHub, Twitter, Airbnb et des milliers d'autres entreprises.

Installation

bash
apt install -y haproxy

# Version
haproxy -v
# HAProxy version 2.x

# Activer le démarrage auto
systemctl enable haproxy

Configuration haproxy.cfg

La configuration HAProxy est divisée en sections : global (paramètres du processus), defaults, frontend (accepte le trafic), backend (groupe de serveurs) et listen (raccourci frontend+backend).

bash
# Sauvegarder la config par défaut
cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak

nano /etc/haproxy/haproxy.cfg
ini
#---------------------------------------------------------------------
# Section GLOBAL — paramètres du processus HAProxy
#---------------------------------------------------------------------
global
    log         /dev/log local0
    log         /dev/log local1 notice
    chroot      /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
    stats timeout 30s
    user        haproxy
    group       haproxy
    daemon

    # SSL/TLS : Performances et sécurité
    ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
    ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384
    ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets
    tune.ssl.default-dh-param 2048

#---------------------------------------------------------------------
# Section DEFAULTS — valeurs par défaut héritées par toutes les sections
#---------------------------------------------------------------------
defaults
    log         global
    mode        http           # Mode HTTP (ou tcp pour non-HTTP)
    option      httplog
    option      dontlognull    # Ne pas logger les connexions sans requête
    option      http-server-close
    option      forwardfor except 127.0.0.0/8  # Transmettre la vraie IP client
    option      redispatch     # Réessayer sur un autre serveur si connexion échoue
    retries     3
    timeout connect 5s
    timeout client  50s
    timeout server  50s
    errorfile 400 /etc/haproxy/errors/400.http
    errorfile 503 /etc/haproxy/errors/503.http

#---------------------------------------------------------------------
# Section FRONTEND — point d'entrée du trafic
#---------------------------------------------------------------------
frontend http_in
    bind *:80
    default_backend web_servers

    # Redirection HTTP → HTTPS
    redirect scheme https code 301 if !{ ssl_fc }

frontend https_in
    bind *:443 ssl crt /etc/haproxy/certs/monsite.com.pem alpn h2,http/1.1
    default_backend web_servers

    # ACL pour router selon le sous-domaine
    acl is_api hdr(host) -i api.monsite.com
    acl is_app hdr(host) -i app.monsite.com

    use_backend api_servers if is_api
    use_backend app_servers if is_app
    default_backend web_servers

    # Headers de sécurité
    http-response set-header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
    http-response set-header X-Frame-Options "DENY"

#---------------------------------------------------------------------
# Section BACKEND — groupe de serveurs web
#---------------------------------------------------------------------
backend web_servers
    balance roundrobin         # Algorithme : round-robin, leastconn, source (sticky)
    option  httpchk GET /health  # Health check HTTP (doit retourner 200)
    http-check expect status 200

    # Cookies de session sticky (même client → même serveur)
    cookie SERVERID insert indirect nocache

    server web1 10.0.0.2:80 check inter 2s fall 3 rise 2 weight 1 cookie web1
    server web2 10.0.0.3:80 check inter 2s fall 3 rise 2 weight 1 cookie web2
    # check    : activer le health check
    # inter 2s : vérifier toutes les 2 secondes
    # fall 3   : considérer comme down après 3 échecs
    # rise 2   : considérer comme up après 2 succès

backend api_servers
    balance leastconn          # Connexion la moins chargée (bon pour API)
    option  httpchk GET /api/health
    server api1 10.0.0.5:8080 check
    server api2 10.0.0.6:8080 check

#---------------------------------------------------------------------
# Interface de statistiques HAProxy
#---------------------------------------------------------------------
listen stats
    bind *:8404
    stats enable
    stats uri /stats
    stats refresh 10s
    stats auth admin:MotDePasseStats
    stats hide-version
bash
# Vérifier la syntaxe
haproxy -c -f /etc/haproxy/haproxy.cfg

# Démarrer/recharger
systemctl restart haproxy
systemctl reload haproxy   # Rechargement sans coupure (graceful)

# Surveiller en temps réel (socket d'administration)
echo "show info" | socat stdio /run/haproxy/admin.sock
echo "show stat" | socat stdio /run/haproxy/admin.sock | column -t -s ','

# Désactiver temporairement un serveur (maintenance)
echo "disable server web_servers/web1" | socat stdio /run/haproxy/admin.sock

# Réactiver
echo "enable server web_servers/web1" | socat stdio /run/haproxy/admin.sock

Keepalived — IP virtuelle flottante (VIP)

Keepalived implémente le protocole VRRP (Virtual Router Redundancy Protocol). Il permet à plusieurs serveurs de partager une IP virtuelle (VIP) — si le serveur MASTER tombe, le BACKUP prend la VIP en quelques secondes.

bash
# Sur les DEUX serveurs load balancer
apt install -y keepalived

# Activer le forwarding IP (nécessaire pour VRRP)
echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
sysctl -p

Configuration du nœud MASTER

bash
# /etc/keepalived/keepalived.conf (MASTER — LB1)
cat > /etc/keepalived/keepalived.conf << 'EOF'
global_defs {
    router_id LB1            # Identifiant unique du routeur
    script_user root
    enable_script_security
}

# Script de vérification de santé HAProxy
vrrp_script check_haproxy {
    script "killall -0 haproxy"   # Retourne 0 si HAProxy tourne
    interval 2                     # Vérifier toutes les 2 secondes
    weight -20                     # Si échoue : baisser la priorité de 20
    fall 2                         # Nombre d'échecs avant de décrémenter
    rise 2                         # Nombre de succès pour remonter
}

vrrp_instance VI_1 {
    state MASTER                   # Ce nœud est MASTER au démarrage
    interface eth0                 # Interface réseau de la VIP
    virtual_router_id 51           # Doit être identique sur MASTER et BACKUP (1-255)
    priority 100                   # Priorité MASTER > BACKUP (100 > 90)
    advert_int 1                   # Intervalle d'annonce VRRP (secondes)

    authentication {
        auth_type PASS
        auth_pass Sup3rS3cret!    # Mot de passe partagé MASTER/BACKUP
    }

    virtual_ipaddress {
        10.0.0.100/24 dev eth0    # L'IP virtuelle flottante
    }

    track_script {
        check_haproxy             # Lier la priorité à l'état de HAProxy
    }
}
EOF

Configuration du nœud BACKUP

bash
# /etc/keepalived/keepalived.conf (BACKUP — LB2)
cat > /etc/keepalived/keepalived.conf << 'EOF'
global_defs {
    router_id LB2
    script_user root
    enable_script_security
}

vrrp_script check_haproxy {
    script "killall -0 haproxy"
    interval 2
    weight -20
    fall 2
    rise 2
}

vrrp_instance VI_1 {
    state BACKUP                   # Ce nœud est BACKUP au démarrage
    interface eth0
    virtual_router_id 51           # Identique au MASTER
    priority 90                    # Priorité inférieure au MASTER
    advert_int 1

    authentication {
        auth_type PASS
        auth_pass Sup3rS3cret!    # Identique au MASTER
    }

    virtual_ipaddress {
        10.0.0.100/24 dev eth0    # Même VIP que le MASTER
    }

    track_script {
        check_haproxy
    }
}
EOF
bash
# Démarrer Keepalived sur les deux nœuds
systemctl enable keepalived
systemctl start keepalived

# Vérifier l'état et quel nœud a la VIP
ip addr show eth0 | grep "10.0.0.100"   # Doit apparaître sur le MASTER uniquement

# Surveiller les logs VRRP
journalctl -u keepalived -f

# Simuler une panne (arrêter HAProxy sur le MASTER)
systemctl stop haproxy
# → Keepalived détecte l'échec du script → réduit la priorité sous 90 → BACKUP prend la VIP

# Observer le basculement sur le BACKUP
# ip addr show eth0 | grep "10.0.0.100"  # Apparaît maintenant sur LB2

Pacemaker + Corosync — Cluster manager avancé

Pour des clusters plus complexes (bases de données, NFS, services avec état), Pacemaker (gestionnaire de ressources) + Corosync (communication inter-nœuds) forment la stack HA de référence sous Linux.

bash
# Sur tous les nœuds du cluster
apt install -y pacemaker corosync pcs fence-agents

# Définir un mot de passe pour l'utilisateur hacluster (identique sur tous les nœuds)
passwd hacluster
# Nouveau mot de passe: ••••••••

systemctl enable pacemaker corosync
systemctl start pcsd   # Service PCS (interface de gestion)

# Depuis le nœud 1 : authentifier les nœuds entre eux
pcs host auth node1.local node2.local   -u hacluster -p MotDePasseHaCluster

# Créer le cluster
pcs cluster setup MONCLUSTER node1.local node2.local

# Démarrer le cluster sur tous les nœuds
pcs cluster start --all
pcs cluster enable --all
bash
# Vérifier l'état du cluster
pcs status
# Cluster name: MONCLUSTER
# Cluster Summary:
#   * Stack: corosync
#   * Current DC: node1.local (version ...) - partition with quorum
#   * 2 nodes configured
#   * 0 resource instances configured
#
# Node List:
#   * Online: [ node1.local node2.local ]

# Désactiver le STONITH en lab (PAS en production !)
pcs property set stonith-enabled=false

# Désactiver le quorum policy en cluster 2 nœuds
pcs property set no-quorum-policy=ignore

Ajouter des ressources au cluster

bash
# Ressource VIP (IP virtuelle)
pcs resource create VirtualIP IPaddr2   ip=10.0.0.100 cidr_netmask=24 nic=eth0   op monitor interval=30s

# Ressource Apache
pcs resource create ApacheHTTP apache   configfile=/etc/apache2/apache2.conf   statusurl="http://127.0.0.1/server-status"   op monitor interval=20s

# Contrainte : VirtualIP doit tourner sur le même nœud qu'Apache
pcs constraint colocation add ApacheHTTP with VirtualIP INFINITY

# Contrainte : VirtualIP doit démarrer avant Apache
pcs constraint order VirtualIP then ApacheHTTP

# Vérifier les ressources
pcs status resources
# * VirtualIP  (ocf::heartbeat:IPaddr2): Started node1.local
# * ApacheHTTP (ocf::heartbeat:apache):  Started node1.local

STONITH (Shoot The Other Node In The Head) est crucial en production. Sans lui, si un nœud perd la communication réseau mais continue à fonctionner, les deux nœuds peuvent réclamer la VIP simultanément — c'est le 'split-brain', qui cause des corruptions de données. Configurez toujours un agent STONITH (IPMI, iLO, iDRAC, fence_aws, fence_gce) en production.

Galera Cluster — Base de données en cluster

Galera est un cluster de réplication synchrone multi-maître pour MariaDB/MySQL. Tous les nœuds acceptent des lectures ET des écritures. Un commit n'est validé que quand tous les nœuds l'ont accepté.

bash
# Sur tous les nœuds (Debian/Ubuntu)
apt install -y mariadb-server galera-4

# Configuration identique sur tous les nœuds (/etc/mysql/mariadb.conf.d/60-galera.cnf)
cat > /etc/mysql/mariadb.conf.d/60-galera.cnf << 'EOF'
[galera]
wsrep_on                 = ON
wsrep_provider           = /usr/lib/galera/libgalera_smm.so
wsrep_cluster_name       = "GaleraCluster"
wsrep_cluster_address    = "gcomm://10.0.0.10,10.0.0.11,10.0.0.12"
wsrep_node_address       = "10.0.0.10"   # IP de CE nœud (différent sur chaque nœud)
wsrep_node_name          = "db1"         # Nom unique de ce nœud

# Méthode de transfert d'état initial (IST/SST)
wsrep_sst_method         = rsync

# Synchronisation binlog
binlog_format            = ROW
default_storage_engine   = InnoDB
innodb_autoinc_lock_mode = 2
innodb_flush_log_at_trx_commit = 0

# Performance
wsrep_slave_threads      = 4
wsrep_max_ws_size        = 2G
EOF

# Démarrage du PREMIER nœud (bootstrap)
galera_new_cluster

# Vérifier l'état du cluster Galera
mysql -e "SHOW STATUS LIKE 'wsrep%';" | grep -E "wsrep_cluster_size|wsrep_connected|wsrep_ready"
# wsrep_cluster_size : 1 (d'abord), puis 2, puis 3 au démarrage des autres nœuds
# wsrep_connected    : ON
# wsrep_ready        : ON

# Sur les autres nœuds (pas de galera_new_cluster, juste start)
systemctl start mariadb

Stockage partagé avec NFS

Dans un cluster de serveurs web, tous les nœuds doivent accéder aux mêmes fichiers (code source, médias uploadés). NFS est la solution classique pour partager ce stockage.

bash
# ── Sur le serveur NFS ──
apt install -y nfs-kernel-server

mkdir -p /srv/nfs/webapp
chown www-data:www-data /srv/nfs/webapp

# Configurer les exports NFS
cat >> /etc/exports << 'EOF'
/srv/nfs/webapp 10.0.0.0/24(rw,sync,no_subtree_check,no_root_squash)
EOF

exportfs -ra
systemctl restart nfs-kernel-server

# Vérifier les exports
showmount -e localhost

# ── Sur chaque nœud web ──
apt install -y nfs-common

# Montage temporaire
mount -t nfs 10.0.0.20:/srv/nfs/webapp /var/www/html

# Montage permanent dans /etc/fstab
echo "10.0.0.20:/srv/nfs/webapp /var/www/html nfs rw,sync,hard,intr,rsize=8192,wsize=8192,_netdev 0 0" >> /etc/fstab
mount -a

Surveiller l'état du cluster

bash
# ── Pacemaker ──
pcs status            # État général
pcs status resources  # État des ressources
pcs status nodes      # État des nœuds
crm_mon -1            # Snapshot (alternatif)
crm_mon -r            # Mise à jour continue

# ── Corosync ──
corosync-cfgtool -s   # Anneaux de communication
corosync-quorumtool   # État du quorum

# ── HAProxy ──
# Interface web : http://10.0.0.1:8404/stats

# En ligne de commande
watch -n1 'echo "show stat" | socat stdio /run/haproxy/admin.sock | cut -d, -f1,2,18,19,48'

# ── Galera ──
mysql -e "SHOW STATUS LIKE 'wsrep_cluster_size';"
mysql -e "SHOW STATUS LIKE 'wsrep_local_state_comment';"
# wsrep_local_state_comment : Synced = tout va bien
# wsrep_cluster_size : doit être le nombre de nœuds attendus

Tester la résilience (chaos testing)

Ne découvrez jamais une panne pour la première fois en production. Testez régulièrement vos failovers en environnement de staging.

bash
# ── Test 1 : Panne du nœud actif HAProxy/Keepalived ──
# Sur LB1 (MASTER) :
systemctl stop haproxy
# Observation : LB2 doit prendre la VIP en <3 secondes
# Vérification : ip addr show eth0 sur LB2 doit montrer 10.0.0.100
# Trafic : curl -I http://10.0.0.100 doit continuer à répondre

# ── Test 2 : Panne d'un serveur web backend ──
# Sur web1 :
systemctl stop apache2
# HAProxy détecte l'échec du health check en ~6s (3 × inter 2s)
# Tout le trafic bascule sur web2
# curl -k https://10.0.0.100 doit continuer à répondre
# Vérification dans les stats HAProxy : web1 apparaît DOWN (rouge)

# ── Test 3 : Panne d'un nœud Galera ──
# Sur db2 :
systemctl stop mariadb
# Galera : cluster_size passe de 3 à 2
# Les requêtes continuent sur db1 et db3
# Au redémarrage de db2, il resynchronise automatiquement (IST ou SST)
systemctl start mariadb
mysql -e "SHOW STATUS LIKE 'wsrep_local_state_comment';"  # → Synced

# ── Test 4 : Network partition (simuler un split-brain) ──
# Sur node1 :
iptables -I INPUT -s 10.0.0.11 -j DROP
iptables -I OUTPUT -d 10.0.0.11 -j DROP
# Le cluster doit rester actif sur le nœud avec le quorum
# STONITH doit shooter l'autre nœud (si configuré)
# Cleanup :
iptables -D INPUT -s 10.0.0.11 -j DROP
iptables -D OUTPUT -d 10.0.0.11 -j DROP

Checklist de mise en production

  1. 1Synchronisation NTP sur tous les nœuds (chrony ou timesyncd) — essentiel pour Galera et Corosync
  2. 2Firewall : ports Corosync (UDP 5404-5405), Galera (4444, 4567, 4568), HAProxy stats, NFS ouverts entre nœuds
  3. 3STONITH configuré et testé — jamais de cluster HA en production sans fencing
  4. 4Monitoring des ressources cluster (Prometheus + blackbox_exporter, Grafana)
  5. 5Alerting sur : nœud DOWN, cluster_size < expected, quorum perdu
  6. 6Procédure de failover documentée et testée par l'équipe
  7. 7Plan de reprise : que faire si tous les nœuds tombent simultanément ?
  8. 8Tests chaos réguliers en staging (au moins trimestriels)
  9. 9Sauvegardes indépendantes du cluster (le cluster n'est PAS un backup)

Pour les clusters Kubernetes (K8s), les concepts sont similaires mais l'outillage change : etcd remplace Corosync pour le consensus, le scheduler K8s remplace Pacemaker pour la gestion des ressources, et les PersistentVolumes remplacent le NFS partagé. La courbe d'apprentissage est plus raide mais la flexibilité bien supérieure pour les microservices.

Sources & références

  1. 1
    HAProxy Documentation

    Documentation complète de référence HAProxy 2.8

  2. 2
    Keepalived User Guide

    Documentation officielle Keepalived avec exemples VRRP

  3. 3
    Pacemaker Documentation — ClusterLabs

    Guide officiel Pacemaker : configuration, ressources, STONITH

  4. 4
    Galera Cluster for MySQL — Documentation

    Documentation complète Galera : architecture, SST, IST, tuning

  5. 5
    Linux-HA Project

    Projet fondateur du clustering HA sous Linux

#cluster#haute-disponibilité#haproxy#keepalived#pacemaker#galera#vrrp

Testez vos configurations

Xytherion Tools propose des outils gratuits pour vérifier vos DNS, auditer votre SSL, tester SPF/DKIM/DMARC et bien plus — directement depuis votre navigateur.

Clusters Linux : haute disponibilité de A à Z — Xytherion Tools