1. Modèle Active/Passive
Comprendre la base de la haute disponibilité : un nœud actif, un nœud de secours.
Concept
Le modèle Active/Passive est une stratégie fondamentale de haute disponibilité où un serveur (le nœud actif) gère toutes les requêtes entrantes, tandis qu'un autre serveur (le nœud passif ou de secours) est en veille, prêt à prendre le relais en cas de défaillance du nœud actif. L'objectif est de minimiser les temps d'arrêt en assurant une transition rapide et automatique (failover) vers le nœud passif.
Ce modèle est plus simple à mettre en œuvre que l'Active/Active car il évite les problèmes de cohérence des données et de répartition de charge complexes, mais il utilise moins efficacement les ressources matérielles (le nœud passif est sous-utilisé en temps normal).
Exemple HAProxy
Dans une architecture Active/Passive, HAProxy est déployé sur les deux nœuds. La configuration de HAProxy est généralement identique sur les deux machines. C'est un mécanisme externe (comme Keepalived) qui va déterminer quel HAProxy est actif et possède l'adresse IP virtuelle.
# /etc/haproxy/haproxy.cfg (sur les deux nœuds)
global
log /dev/log daemon
maxconn 2000
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
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend http_front
bind *:80
default_backend http_back
backend http_back
balance roundrobin
server app1 192.168.1.10:80 check
server app2 192.168.1.11:80 checkLe rôle de HAProxy ici est de router le trafic vers les backends. La haute disponibilité de HAProxy lui-même est assurée par le mécanisme de failover de l'IP virtuelle.
Exemple Traefik
Similairement à HAProxy, Traefik est installé et configuré de manière identique sur les deux nœuds. Le nœud actif sera celui qui détient l'adresse IP virtuelle, gérée par un outil comme Keepalived.
# /etc/traefik/traefik.yml (sur les deux nœuds)
entryPoints:
web:
address: ":80"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
api:
dashboard: true
# Exemple de service Docker avec labels Traefik
# (Ce service serait déployé sur les backends, pas sur les nœuds Traefik eux-mêmes)
# services:
# my-app:
# image: my-app:latest
# labels:
# - "traefik.enable=true"
# - "traefik.http.routers.my-app.rule=Host(`myapp.example.com`)"
# - "traefik.http.services.my-app.loadbalancer.server.port=80"Traefik écoute sur le port 80 de l'IP virtuelle. En cas de bascule, le second nœud Traefik prendra le contrôle de l'IP et continuera à router le trafic sans interruption côté client (si la synchronisation de session est gérée).
2. Modèle Active/Active
Plusieurs nœuds traitent le trafic simultanément pour une scalabilité maximale.
Concept
Dans le modèle Active/Active, tous les nœuds du cluster sont opérationnels et traitent les requêtes en même temps. La charge est répartie entre eux par un mécanisme externe (DNS Round Robin, GSLB, ou un Load Balancer Cloud).
Cette approche permet une meilleure utilisation des ressources et une scalabilité horizontale. Cependant, elle impose que l'application soit stateless ou que les sessions soient partagées/centralisées dans un cache externe (Redis/Memcached).
Exemple HAProxy
En mode Active/Active, HAProxy est souvent placé derrière un répartiteur de charge Cloud (comme un AWS NLB) qui distribue les connexions TCP vers les multiples instances HAProxy réparties dans plusieurs zones.
Exemple Traefik
Traefik est conçu nativement pour l'Active/Active, particulièrement dans Kubernetes. En augmentant le nombre de replicas, on distribue la charge sur plusieurs pods Traefik.
# Exemple Kubernetes Deployment pour Traefik A/A
apiVersion: apps/v1
kind: Deployment
metadata:
name: traefik
spec:
replicas: 3 # 3 nœuds actifs simultanément
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
containers:
- name: traefik
image: traefik:v3.0
ports:
- name: web
containerPort: 80
3. Comparatif : Active/Passive vs Active/Active
Critères de décision pour votre architecture HA.
Quand choisir l'Active/Passive ?
- Simplicité : Plus facile à mettre en œuvre et à débugger.
- Compatibilité : Idéal pour les applications 'stateful' (sessions locales) qui ne supportent pas le partage de données.
- Coût : Moins de ressources actives en permanence.
Quand choisir l'Active/Active ?
- Scalabilité : Si un seul serveur ne suffit pas à traiter le trafic.
- Disponibilité : Le failover est quasi instantané car tous les nœuds sont déjà 'chauds'.
- Modernisation : Indispensable pour les architectures microservices et containers.
4. VRRP avec Keepalived
Mise en œuvre d'une adresse IP virtuelle flottante pour le failover.
Concept
Le VRRP (Virtual Router Redundancy Protocol) est un protocole réseau qui permet à plusieurs routeurs (ou serveurs, dans notre cas) de partager une même adresse IP virtuelle. Un des routeurs est désigné comme 'maître' (master) et répond aux requêtes pour l'IP virtuelle, tandis que les autres sont en 'sauvegarde' (backup). En cas de défaillance du maître, un des routeurs de sauvegarde prend automatiquement le rôle de maître et l'adresse IP virtuelle.
Keepalived est une implémentation logicielle de VRRP pour Linux. Il surveille l'état des services critiques (comme HAProxy ou Traefik) et gère la bascule de l'IP virtuelle en fonction de la disponibilité de ces services.
Exemple Keepalived pour HAProxy
Voici une configuration keepalived.conf typique pour un nœud maître HAProxy. Une configuration similaire (avec state BACKUP et une priority inférieure) serait utilisée sur le nœud de secours.
# /etc/keepalived/keepalived.conf (sur le nœud MAÎTRE)
vrrp_script chk_haproxy {
script "killall -0 haproxy" # Vérifie si le processus haproxy est en cours d'exécution
interval 2 # Exécute le script toutes les 2 secondes
weight 20 # Ajoute 20 à la priorité si le script réussit
}
vrrp_instance VI_1 {
state MASTER # Ce nœud est le maître
interface eth0 # Interface réseau à surveiller
virtual_router_id 51 # ID unique pour cette instance VRRP
priority 101 # Priorité plus élevée pour le maître
advert_int 1 # Intervalle d'annonce VRRP en secondes
authentication {
auth_type PASS
auth_pass mysecret # Mot de passe partagé entre les nœuds VRRP
}
virtual_ipaddress {
192.168.1.100/24 # L'adresse IP virtuelle flottante
}
track_script {
chk_haproxy # Suivre l'état de HAProxy
}
}
Sur le nœud de secours, state serait BACKUP et priority serait 100.
Exemple Keepalived pour Traefik
La configuration Keepalived pour Traefik est très similaire, il suffit d'adapter le script de vérification pour s'assurer que le processus Traefik est bien actif.
# /etc/keepalived/keepalived.conf (sur le nœud MAÎTRE)
vrrp_script chk_traefik {
script "killall -0 traefik" # Vérifie si le processus traefik est en cours d'exécution
interval 2
weight 20
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 52
priority 101
advert_int 1
authentication {
auth_type PASS
auth_pass anothersecret
}
virtual_ipaddress {
192.168.1.100/24
}
track_script {
chk_traefik
}
}
5. Synchronisation des sessions
Maintenir l'état des utilisateurs lors d'un failover.
Concept
Lorsqu'un failover se produit dans un environnement Active/Passive, le nouveau nœud actif prend le relais. Si les applications sont stateful (c'est-à-dire qu'elles maintiennent un état spécifique à la session utilisateur, comme un panier d'achat, un statut de connexion ou des préférences), une simple bascule de l'IP virtuelle ne suffit pas. Les utilisateurs pourraient être déconnectés ou perdre leurs données en cours. La synchronisation des sessions vise à répliquer cet état entre les nœuds pour assurer une transition transparente.
Exemple HAProxy (Synchronisation des Stick Tables)
HAProxy excelle dans la gestion de la persistance de session via ses stick tables. Pour la haute disponibilité, il peut synchroniser ces tables entre les nœuds HAProxy, garantissant que les informations de session (comme l'affinité client-serveur) sont conservées même après un failover.
# /etc/haproxy/haproxy.cfg
global
# ... autres configurations ...
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
backend app_backend
balance roundrobin
# Définition de la stick table pour la persistance de session
stick-table type ip size 100k expire 30m store conn_cur,http_req_rate(10s)
stick on src table app_backend
# Configuration de la synchronisation des stick tables
# 'peer' définit l'autre nœud HAProxy
peers ha_cluster
peer haproxy_node1 192.168.1.20:1024
peer haproxy_node2 192.168.1.21:1024
# Serveurs d'application
server app1 192.168.1.10:80 check
server app2 192.168.1.11:80 check
Dans cette configuration, peers ha_cluster et les entrées peer haproxy_nodeX indiquent à HAProxy de synchroniser les données de ses stick tables avec l'autre instance. Ainsi, si le nœud maître tombe, le nœud de secours aura une copie à jour des informations de session et pourra maintenir la persistance.
Exemple Traefik (Approches alternatives)
Traefik, étant plus orienté microservices et stateless par nature, n'offre pas de mécanisme de synchronisation de session intégré comme les stick tables de HAProxy. Pour gérer la persistance de session en haute disponibilité avec Traefik, plusieurs approches sont possibles :
- Session Sticky (Sticky Sessions) : Configurer le load balancer pour qu'il envoie toutes les requêtes d'un même client au même backend. Cela ne synchronise pas la session, mais assure qu'un client reste sur le même serveur tant qu'il est disponible. En cas de défaillance du backend, la session sera perdue.
- Stockage de sessions externe : Utiliser une base de données ou un cache distribué (comme Redis, Memcached) pour stocker les sessions applicatives. Les applications sont alors stateless et peuvent être redémarrées ou déplacées sans perte de session. C'est l'approche la plus robuste pour les applications modernes.
- Réplication de l'état applicatif : Pour des applications très spécifiques, la réplication de l'état peut être gérée directement au niveau de l'application ou de la base de données.
Voici un exemple de configuration Traefik pour des sessions sticky (affinité basée sur le cookie) :
# /etc/traefik/traefik.yml
http:
services:
my-app-service:
loadBalancer:
servers:
- url: "http://192.168.1.10:80"
- url: "http://192.168.1.11:80"
sticky:
cookie:
name: "_myapp_session"
secure: true
httpOnly: true
sameSite: "Lax"
Cette configuration indique à Traefik d'utiliser un cookie nommé _myapp_session pour maintenir l'affinité client-serveur. Si le serveur backend 192.168.1.10 tombe, les nouvelles requêtes seront dirigées vers 192.168.1.11, mais les sessions existantes sur 192.168.1.10 seront perdues.
Conclusion
La haute disponibilité est un équilibre entre complexité et résilience.
Choisir la bonne stratégie
La mise en place de la haute disponibilité est cruciale pour la continuité de service. Le modèle Active/Passive avec VRRP (Keepalived) est une solution éprouvée pour les couches de proxy/load balancing. Cependant, la véritable résilience dépend aussi de la capacité de vos applications à gérer leur état (sessions). HAProxy offre des mécanismes intégrés de synchronisation de stick tables, tandis que Traefik s'appuie davantage sur des architectures applicatives stateless ou des stockages de sessions externes. Le choix de la stratégie dépendra de la criticité de l'application, de sa nature (stateful/stateless) et des ressources disponibles.