- Comprendre le fonctionnement d'un load balancer (répartiteur de charge)
- Déployer un load balancer avec Octavia
- Configurer des health checks pour la haute disponibilité
- Tester le basculement automatique en cas de panne
Durée estimée : 1h30
cd ~/devstack
source openrc admin admin
openstack service list | grep octaviaSi Octavia n'apparaît pas, vous devez l'activer.
Arrêter DevStack :
cd ~/devstack
./unstack.sh
./clean.shModifier local.conf :
nano local.confAjouter ces lignes :
[[local|localrc]]
HOST_IP=192.168.25.104
SERVICE_HOST=192.168.25.104
# OVN
enable_service neutron
enable_service ovn-northd
enable_service ovn-controller
enable_service q-ovn-metadata-agent
# Octavia (désactivé pour premier stack)
enable_service o-api=false
enable_service o-hk=false
enable_service o-hm=false
enable_service o-cw=false
# Floating IPs
PUBLIC_NETWORK_NAME=public
PUBLIC_SUBNET_NAME=public-subnet
PUBLIC_NETWORK_GATEWAY=192.168.100.1
# Activer Octavia
enable_service o-api=true
enable_service o-hk=true
enable_service o-hm=true
enable_service o-cw=true
OCTAVIA_MGMT_NETWORK=lb-mgmt-net
OCTAVIA_MGMT_SUBNET=lb-mgmt-subnetRelancer DevStack :
./stack.sh# Créer un réseau privé
openstack network create reseau-lb
# Créer un sous-réseau
openstack subnet create --network reseau-lb \
--subnet-range 192.168.100.0/24 \
--dns-nameserver 8.8.8.8 \
subnet-lb
# Créer un routeur
openstack router create routeur-lb
# Connecter le routeur au réseau externe
openstack router set routeur-lb --external-gateway public
# Connecter le routeur au sous-réseau privé
openstack router add subnet routeur-lb subnet-lb# Créer le groupe de sécurité
openstack security group create sg-web
# Autoriser SSH
openstack security group rule create --protocol tcp \
--dst-port 22 sg-web
# Autoriser HTTP
openstack security group rule create --protocol tcp \
--dst-port 80 sg-web
# Autoriser ICMP (ping)
openstack security group rule create --protocol icmp sg-webopenstack keypair create --public-key ~/.ssh/id_rsa.pub ma-cleSi vous n'avez pas de clé SSH :
ssh-keygen -t rsa -b 2048 -f ~/.ssh/id_rsa -N ""
openstack keypair create --public-key ~/.ssh/id_rsa.pub ma-clecat > cloud-init-nginx.sh << 'EOF'
#!/bin/bash
apt-get update
apt-get install -y nginx
HOSTNAME=$(hostname)
IP=$(hostname -I | awk '{print $1}')
cat > /var/www/html/index.html << HTML
<!DOCTYPE html>
<html>
<head>
<title>Load Balancer Test</title>
<style>
body {
font-family: Arial, sans-serif;
text-align: center;
padding: 50px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.container {
background: rgba(255,255,255,0.1);
padding: 30px;
border-radius: 10px;
backdrop-filter: blur(10px);
}
h1 { font-size: 48px; margin: 0; }
.info { font-size: 24px; margin-top: 20px; }
</style>
</head>
<body>
<div class="container">
<h1>🚀 Serveur Web</h1>
<div class="info">
<p><strong>Hostname:</strong> ${HOSTNAME}</p>
<p><strong>IP:</strong> ${IP}</p>
<p><strong>Date:</strong> <span id="date"></span></p>
</div>
</div>
<script>
document.getElementById('date').textContent = new Date().toLocaleString();
setInterval(() => {
document.getElementById('date').textContent = new Date().toLocaleString();
}, 1000);
</script>
</body>
</html>
HTML
systemctl restart nginx
EOF# Récupérer l'ID de l'image Ubuntu
IMAGE_ID=$(openstack image list -f value -c ID -c Name | grep -i ubuntu | head -1 | awk '{print $1}')
# Créer la première instance
openstack server create \
--flavor m1.small \
--image $IMAGE_ID \
--network reseau-lb \
--security-group sg-web \
--key-name ma-cle \
--user-data cloud-init-nginx.sh \
web-server-1
# Créer la deuxième instance
openstack server create \
--flavor m1.small \
--image $IMAGE_ID \
--network reseau-lb \
--security-group sg-web \
--key-name ma-cle \
--user-data cloud-init-nginx.sh \
web-server-2# Vérifier l'état des instances
watch -n 5 'openstack server list'Attendez que les deux instances soient en statut ACTIVE (Ctrl+C pour quitter).
# Vérifier que nginx est démarré (attendre 2-3 minutes)
sleep 180# Lister les serveurs avec leurs IPs
openstack server list --name web-server
# Récupérer les IPs dans des variables
SERVER1_IP=$(openstack server show web-server-1 -f value -c addresses | cut -d'=' -f2)
SERVER2_IP=$(openstack server show web-server-2 -f value -c addresses | cut -d'=' -f2)
echo "Serveur 1 : $SERVER1_IP"
echo "Serveur 2 : $SERVER2_IP"openstack loadbalancer create \
--name mon-load-balancer \
--vip-subnet-id subnet-lbNote : La création du load balancer prend quelques minutes.
watch -n 5 'openstack loadbalancer show mon-load-balancer -c provisioning_status -c operating_status'Attendez que le provisioning_status soit ACTIVE (Ctrl+C pour quitter).
LB_VIP=$(openstack loadbalancer show mon-load-balancer -f value -c vip_address)
echo "Adresse VIP du Load Balancer : $LB_VIP"openstack loadbalancer show mon-load-balancerObservation : Notez le vip_address, le vip_port_id, et les statuts.
openstack loadbalancer listener create \
--name listener-http \
--protocol HTTP \
--protocol-port 80 \
mon-load-balancer# Attendre que le LB soit à nouveau ACTIVE
watch -n 5 'openstack loadbalancer show mon-load-balancer -c provisioning_status'openstack loadbalancer listener show listener-httpopenstack loadbalancer pool create \
--name mon-pool-web \
--lb-algorithm ROUND_ROBIN \
--listener listener-http \
--protocol HTTPExplication des algorithmes disponibles :
ROUND_ROBIN: Distribution équitable en rotationLEAST_CONNECTIONS: Vers le serveur avec le moins de connexionsSOURCE_IP: Basé sur l'IP source (affinité de session)
watch -n 5 'openstack loadbalancer show mon-load-balancer -c provisioning_status'openstack loadbalancer pool show mon-pool-webopenstack loadbalancer member create \
--subnet-id subnet-lb \
--address $SERVER1_IP \
--protocol-port 80 \
--name member-web-1 \
mon-pool-webwatch -n 5 'openstack loadbalancer show mon-load-balancer -c provisioning_status'openstack loadbalancer member create \
--subnet-id subnet-lb \
--address $SERVER2_IP \
--protocol-port 80 \
--name member-web-2 \
mon-pool-webwatch -n 5 'openstack loadbalancer show mon-load-balancer -c provisioning_status'openstack loadbalancer member list mon-pool-webRésultat attendu : Vous devez voir vos deux membres avec leur adresse IP et leur statut.
openstack loadbalancer healthmonitor create \
--name health-check-http \
--delay 5 \
--max-retries 3 \
--timeout 5 \
--type HTTP \
--url-path / \
mon-pool-webExplication des paramètres :
--delay 5: Vérification toutes les 5 secondes--max-retries 3: 3 échecs avant de marquer le serveur DOWN--timeout 5: Timeout de 5 secondes par vérification--url-path /: Chemin à vérifier (page d'accueil)
watch -n 5 'openstack loadbalancer show mon-load-balancer -c provisioning_status'openstack loadbalancer healthmonitor show health-check-httpopenstack loadbalancer member list mon-pool-webObservation : Le operating_status des members devrait passer à ONLINE après quelques vérifications réussies.
VIP_PORT_ID=$(openstack loadbalancer show mon-load-balancer -f value -c vip_port_id)
echo "Port ID : $VIP_PORT_ID"openstack floating ip create publicFLOATING_IP=$(openstack floating ip list --status DOWN -f value -c "Floating IP Address" | head -1)
echo "IP Flottante : $FLOATING_IP"openstack floating ip set --port $VIP_PORT_ID $FLOATING_IPopenstack floating ip show $FLOATING_IPcurl http://$FLOATING_IPRésultat attendu : Vous devriez voir la page HTML avec le hostname et l'IP d'un des serveurs.
# Faire 10 requêtes
for i in {1..10}; do
echo "=== Requête $i ==="
curl -s http://$FLOATING_IP | grep -E "Hostname|IP"
sleep 1
doneObservation : Les requêtes doivent alterner entre web-server-1 et web-server-2.
Ouvrir un nouveau terminal et exécuter :
cd ~/devstack
source openrc admin admin
watch -n 2 'openstack loadbalancer member list mon-pool-web'Observation : Vous verrez les statistiques des membres (connexions actives, totales, etc.).
Dans le premier terminal :
while true; do
curl -s http://$FLOATING_IP | grep "Hostname"
sleep 1
doneLaissez tourner pour observer la distribution.
openstack loadbalancer member list mon-pool-webLes deux membres doivent être ONLINE.
Ouvrir un nouveau terminal :
cd ~/devstack
source openrc admin admin
openstack server stop web-server-1Dans le terminal de surveillance :
watch -n 2 'openstack loadbalancer member list mon-pool-web'Observation : Après 3 échecs consécutifs (environ 15-20 secondes), le member-web-1 passera à ERROR ou OFFLINE.
Le trafic doit maintenant être dirigé uniquement vers web-server-2 :
for i in {1..10}; do
echo "=== Requête $i ==="
curl -s http://$FLOATING_IP | grep "Hostname"
sleep 1
doneRésultat attendu : Toutes les requêtes vont vers web-server-2.
openstack server start web-server-1# Attendre que l'instance soit active
sleep 60
# Surveiller le health check
watch -n 2 'openstack loadbalancer member list mon-pool-web'Observation : Après quelques vérifications réussies, member-web-1 repassera à ONLINE et recevra à nouveau du trafic.
for i in {1..10}; do
echo "=== Requête $i ==="
curl -s http://$FLOATING_IP | grep "Hostname"
sleep 1
doneLe load balancing ROUND_ROBIN doit reprendre entre les deux serveurs.
# Se connecter à web-server-1
ssh ubuntu@$(openstack server show web-server-1 -f value -c addresses | cut -d'=' -f2)
# Arrêter nginx
sudo systemctl stop nginx
# Quitter
exitObserver le comportement du health check et du load balancer.
openstack loadbalancer pool set \
--lb-algorithm LEAST_CONNECTIONS \
mon-pool-webTestez la différence de comportement.
openstack loadbalancer member set \
--weight 2 \
mon-pool-web member-web-1
openstack loadbalancer member set \
--weight 1 \
mon-pool-web member-web-2Résultat : web-server-1 recevra 2x plus de trafic que web-server-2.
openstack loadbalancer delete --cascade mon-load-balancerAttention : Cela supprime le LB, le listener, le pool, les members et le health monitor.
openstack server delete web-server-1
openstack server delete web-server-2openstack floating ip delete $FLOATING_IPopenstack router remove subnet routeur-lb subnet-lb
openstack router delete routeur-lb
openstack subnet delete subnet-lb
openstack network delete reseau-lb✅ Architecture du Load Balancer :
- Load Balancer : Point d'entrée avec VIP
- Listener : Écoute sur un port/protocole
- Pool : Groupe de serveurs backend
- Members : Serveurs individuels dans le pool
- Health Monitor : Surveillance de la santé des membres
✅ Algorithmes de distribution :
ROUND_ROBIN: Rotation équitableLEAST_CONNECTIONS: Charge la moins connectéeSOURCE_IP: Affinité de session
✅ Health Checks :
- Détection automatique des pannes
- Retrait automatique des membres défaillants
- Réintégration automatique après récupération
✅ Haute Disponibilité :
- Pas d'interruption de service lors d'une panne
- Basculement automatique transparent
- Répartition de charge optimale
- Quelle est la différence entre un load balancer Layer 4 (TCP) et Layer 7 (HTTP) ?
- Pourquoi est-il important d'avoir un health monitor ?
- Quel algorithme choisir pour une application avec sessions utilisateur ?
- Comment éviter le split-brain dans un load balancer ?
- Quels sont les cas d'usage typiques d'un load balancer ?
Défi : Créer un load balancer HTTPS avec :
- Certificat SSL/TLS
- Redirection HTTP → HTTPS
- Cookie de session pour l'affinité
- Health check sur une URL spécifique (/health)
- Documentation Octavia : https://docs.openstack.org/octavia/latest/
- API Reference : https://docs.openstack.org/api-ref/load-balancer/
- Best Practices : https://docs.openstack.org/octavia/latest/user/guides/basic-cookbook.html
Félicitations ! Vous maîtrisez maintenant les load balancers avec Octavia !