Maîtrise de l'Équilibrage de Charge et du Routage Avancé avec HAProxy

Architecture et Principes Fondamentaux

HAProxy est un proxy inverse et un répartiteur de charge open-source écrit en C. Il opère principalement aux couches 4 (TCP) et 7 (HTTP) du modèle OSI. Conçu pour les environnements à fort trafic, il gère efficacement la persistance de session et le traitement applicatif, tout en masquant l'infrastructure backend.

Algorithmes de Répartition

  • Round Robin (Tourniquet) : Distribution séquentielle et équitable des requêtes entre les nœuds.
  • Least Connections (Moins de connexions) : Dirige le trafic vers le serveur ayant le moins de connexions actives, idéal pour les requêtes longue durée.
  • Source Hash (Hachage source) : Applique une fonction de hachage sur l'IP du client pour garantir qu'un même client soit toujours dirigé vers le même serveur backend, assurant ainsi une persistance de session native.

Modèle de Flux

L'architecture repose sur des sections frontend (point d'entrée) et backend (pool de serveurs). Une section listen peut fusionner les deux pour des configurations simplifiées. Le frontend analyse les en-têtes HTTP pour appliquer des règles de routage vers les backends aprpopriés. Le trafic retour transite systématiquement par HAProxy, ce qui signifie que les serveurs backend voient l'adresse IP du proxy comme source.

Installation et Structure de Configuration

Sur une distribution basée sur RHEL/CentOS, l'installation s'effectue via le gestionnaire de paquets :

dnf install -y haproxy

Les fichiers principaux générés incluent :

  • /etc/haproxy/haproxy.cfg : Fichier de configuration central.
  • /usr/lib/systemd/system/haproxy.service : Unité de service systemd.

Structure du Fichier haproxy.cfg

global
    log         127.0.0.1 local0
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     8000
    user        haproxy
    group       haproxy
    daemon

defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 5000

frontend web_entry
    bind *:80
    default_backend app_servers

backend app_servers
    balance roundrobin
    server srv-alpha 10.0.10.11:8080 check
    server srv-beta  10.0.10.12:8080 check

Centralisation des Journaux avec Rsyslog

Par défaut, HAProxy n'écrit pas directement dans un fichier. Il délègue cette tâche au démon syslog local via le protocole UDP.

Configuration de HAProxy pour envoyer les logs via le facility local0 :

global
    log 127.0.0.1:514 local0

defaults
    log global
    option httplog

Configuration de Rsyslog dans un fichier dédié (/etc/rsyslog.d/haproxy.conf) :

$ModLoad imudp
$UDPServerRun 514

# Séparation des logs d'accès et d'erreurs
local0.info                     /var/log/haproxy/access.log
local0.warning;local0.err       /var/log/haproxy/error.log

Après modification, redémarrez les services pour appliquer les changements :

systemctl restart rsyslog haproxy

Mise en Œuvre de l'Équilibrage de Charge et Préservation de l'IP Client

Dans un environnement où les backends sont des serveurs web comme Nginx, l'IP source perçue par l'application est celle du load balancer. Pour transmettre l'IP réelle du client, HAProxy utilise l'en-tête X-Forwarded-For.

Configuration HAProxy

frontend http_front
    bind *:80
    option forwardfor except 127.0.0.0/8
    default_backend nginx_pool

backend nginx_pool
    balance leastconn
    server web-01 10.0.20.101:80 check
    server web-02 10.0.20.102:80 check

Configuration Nginx Backend

Sur les serveurs Nginx, il faut configurer le module realip pour extraire et utiliser l'en-tête injecté par le proxy :

server {
    listen 80;
    server_name app.internal;
    
    set_real_ip_from 10.0.20.0/24; # Sous-réseau du HAProxy
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;

    location / {
        root /var/www/html;
        index index.html;
    }
}

Activation du Tableau de Bord Statistiques

HAProxy intègre une interface web native pour monitorer l'état des nœuds, les taux de transfert et les files d'attente en temps réel.

listen stats_dashboard
    bind *:8404
    mode http
    stats enable
    stats uri /monitor
    stats refresh 15s
    stats realm HAProxy\ Metrics
    stats auth supervisor:SecureP@ssw0rd!
    stats admin if TRUE

L'interface est ensuite accessible via un navigateur à l'adresse http://<IP_HAPROXY>:8404/monitor.

Routage Avancé avec les Listes de Contrôle d'Accès (ACL)

Les ACL permettent d'inspecter le trafic de couche 7 et de prendre des décisions de routage dynamiques basées sur le contenu des requêtes.

Syntaxe et Opérateurs

Une règle ACL suit la structure générale : acl <nom> <critère> [drapeaux] [opérateur] <valeur>.

  • Critères : src (IP source), path (URI exacte), path_beg (début de l'URI), hdr (en-tête HTTP).
  • Drapeaux : -i (insensible à la casse), -m (correspondance regex).

Séparation du Trafic Statique et Dynamique

Exemple de routage basé sur les extensions de fichiers et les chemins d'API pour une architecture microservices :

frontend main_router
    bind *:80
    
    # Définition des règles d'inspection
    acl is_static path_end -i .css .js .png .jpg .svg
    acl is_api path_beg /api/v2/
    acl is_mobile hdr_sub(User-Agent) -i Mobile

    # Routage conditionnel vers les pools
    use_backend static_assets if is_static
    use_backend api_cluster if is_api
    use_backend mobile_app if is_mobile
    default_backend default_web

backend static_assets
    balance roundrobin
    server cdn-node-1 10.0.30.11:80 check
    server cdn-node-2 10.0.30.12:80 check

backend api_cluster
    balance source
    server api-srv-1 10.0.30.21:8080 check
    server api-srv-2 10.0.30.22:8080 check

backend mobile_app
    balance roundrobin
    server mob-1 10.0.30.31:80 check

backend default_web
    balance roundrobin
    server web-main 10.0.30.41:80 check

Contrôle d'Accès et Redirection

Les ACL peuvent également bloquer du trafic malveillant ou forcer des redirections pour sécuriser les échanges.

frontend secure_front
    bind *:80
    bind *:443 ssl crt /etc/haproxy/certs/site.pem

    # Redirection HTTP vers HTTPS
    http-request redirect scheme https code 301 if !{ ssl_fc }

    # Blocage d'IPs spécifiques
    acl blocked_ip src 198.51.100.0/24
    http-request deny deny_status 403 if blocked_ip

    # Restriction d'accès au panneau d'administration
    acl is_admin_path path_beg /admin
    acl is_internal_ip src 10.0.0.0/8
    http-request deny deny_status 403 if is_admin_path !is_internal_ip

    default_backend app_pool

Logique Booléenne dans les ACL

Les conditions peuvent être combinées directement dans les directives use_backend ou http-request sans créer de règles intermédiaires.

  • ET (AND) : use_backend bk if acl1 acl2 (les deux conditions doivent être évaluées à vrai).
  • OU (OR) : use_backend bk if acl1 or acl2 (au moins une condition doit être vraie).
  • NON (NOT) : use_backend bk if !acl1 (la condition doit être évaluée à faux).

Optimisation des Connexions TCP (Couche 4)

Pour les bases de données ou les services non-HTTP, HAProxy opère en mode TCP. Les vérifications de santé et les timeouts doivent être spécifiquement adaptés au protocole cible.

frontend db_front
    bind *:3306
    mode tcp
    option tcplog
    default_backend db_pool

backend db_pool
    mode tcp
    balance leastconn
    option mysql-check user haproxy_check
    server db-primary 10.0.40.10:3306 check
    server db-replica-1 10.0.40.11:3306 check
    server db-replica-2 10.0.40.12:3306 check

Gestion des Erreurs et Pages Personnalisées

Il est possible d'intercepter les codes d'erreur HTTP pour servir des pages statiques hébergées localement par HAProxy, améliorant ainsi l'expérience utilisateur en cas de panne complète du back end.

frontend web_front
    bind *:80
    errorfile 503 /etc/haproxy/errors/503-custom.http
    errorfile 502 /etc/haproxy/errors/502-custom.http
    default_backend web_pool

Étiquettes: HAProxy load-balancing reverse-proxy ACL rsyslog

Publié le 14 juillet à 17h29