L’équilibrage de charge sous Linux avec LVS (mise en pratique)

Source de l'image : Wikimédia Foundation

Source de l’image : Wikimédia Foundation

Je continue mes expériences à propos de l’équilibrage de charge sous Linux avec LVS dans le cadre de mon projet de fin d’année. Après avoir un peu étudié la théorie LVS, il reste donc à mettre tout cela en pratique.

Vous allez voir qu’encore une fois nous allons utiliser des outils vraiment puissants, avec un gros potentiel et pourtant d’une simplicité d’utilisation déconcertante.

Mise en place de LVS-DR

Du fait de l’organisation de mon projet qui est « coupé » entre deux machines (la mienne et celle de mon coéquipier) et à cause de restrictions matérielles, nous n’avons pas pu mettre en place de LVS-NAT sur notre proof-of-concept. Pourtant, cela aurait été l’idéal : un LVS public gérant le trafic entrant / sortant vers et depuis la batterie de serveurs hébergeant l’API afin que ceux-ci restent cachés aux yeux du monde…

Bref inutile de rentrer dans les détails, pour le poc, ça sera du LVS-DR. Voici donc comment je me suis débrouillé.

Rappels sur l’infrastructure

Voici un petit schéma pour résumer ce que je vais faire.

Schémas LVS projet

Vous remarquerez que toutes mes machines sont sur le même sous-réseau, y compris le client. Dans la pratique, serveurs réels et clients sont bien séparés…

Les deux machines API-01 et API-02 sont des machines Debian 7.2 Stable avec juste le couple Apache / PHP d’installé. La troisième machine, le directeur, est lui aussi une Debian 7.2 Stable fraîchement installée.

Configuration du directeur (installation et configuration de LVS)

Sur le directeur, la première étape est bien évidemment l’installation du paquet ipvsadm.

apt-get install ipvsadm

Configuration de la VIP sur le directeur

Il va ensuite falloir déclarer l’adresse IP virtuelle sur l’adaptateur correspondant au sous-réseau associé. Je n’ai pas à me poser la question puisque mon directeur n’a qu’un adaptateur… La création de la VIP se fait sur un alias dudit adaptateur, toujours via le fichier /etc/network/interfaces.

auto bond0:0
iface bond0:0 inet static
	address 192.168.24.142
	netmask 255.255.255.255
	broadcast 192.168.24.255
	network 192.168.24.0

Si vous vous posez la question à propos du bonding…

Un petit démarrage de l’adaptateur :

ifup bond0:0

et on vérifie la configuration :

ip addr show bond0
6: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
    link/ether 00:50:56:21:7d:a8 brd ff:ff:ff:ff:ff:ff
    inet 192.168.24.141/24 brd 192.168.24.255 scope global bond0
    inet 192.168.24.142/32 brd 192.168.24.255 scope global bond0:0
       valid_lft forever preferred_lft forever

bond0:0 est bien déclaré !

STOP ! Pourquoi un masque en /32 ?

Nous le verrons un peu plus tard, notre IP virtuelle va être partagée en le directeur et les serveurs réels, or seul le directeur devra répondre aux requêtes adressées à la VIP. Il est donc cohérent d’utiliser un masque en /32, laissant la possibilité d’avoir un seul hôte sur le sous réseau.

Déclaration de la VIP

L’adresse IP virtuelle utilisée par notre LVS se déclare très facilement avec l’utilitaire ipvsadm :

ipvsadm -A -t 192.168.24.142:80 -s rr

Où :

  • -A : ajoute un service,
  • -t : de type TCP suivi de l’IP du service et de son port,
  • -s : avec la méthode de répartition round-robin.

Déclaration des serveurs réels

L’ajout des serveurs réels se fait aussi avec l’utilitaire ipvsadm :

ipvsadm -a -t 192.168.24.142:80 -r 192.168.24.121:80 -g -w 1

Où :

  • -a : ajoute un serveur réel, toujours de type -t TCP suivi de l’IP:PORT sur service.
  • -r : et du couple IP:PORT du serveur réel à ajouter.
  • -g : correspond au mode gateway (Direct Routing).
  • -w : et enfin le poids attribué au serveur réel.

J’ajoute la deuxième machine de la même manière :

ipvsadm -a -t 192.168.24.142:80 -r 192.168.24.122:80 -g -w 1

Vérification de la configuration

Si tout s’est bien passé, la commande suivante devrait vous apporter quelques informations à propos de votre LVS :

ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.24.142:80 rr
  -> 192.168.24.121:80            Route   1      0          0         
  -> 192.168.24.122:80            Route   1      0          0

Ici on voit bien que mon service de type TCP sur le port 80 de l’adresse 192.168.24.142 est bien déclaré. La colonne Forward indique bien que le mode Direct Routing est utilisé (Route).

Maintenant que le directeur est correctement configuré, nous pouvons passer aux serveurs réels, sur lesquels il va aussi falloir déclarer la VIP.

Configuration des serveurs réels

Le problème ARP

Je vous le disais un peu plus, l’adresse IP virtuelle utilisée par notre LVS va être partagée en le directeur et n serveurs réels. Très vite un problème se pose : toutes les requêtes doivent absolument être traitées par le directeur et non l’un des serveurs réels. Comment s’assurer alors que lorsque je contacte l’adresse IP 192.168.24.142 je contacte bien le directeur ?

La solution est de configurer le serveurs réels afin qu’ils ne répondent pas aux requêtes ARP qui leur sont adressées. Comment ?

Historiquement, la VIP était déclarée sur l’interface de loopback car les noyaux 2.0 ne résolvaient pas, par défaut, les requêtes ARP sur lo. Ce n’est plus le cas depuis le noyau 2.2, mais l’habitude a été conservée de configurer la VIP en loopback.

Autre particularité de l’interface de loopback : elle répond par défaut à toutes les requêtes reçues d’hôtes figurant sur les mêmes sous-réseaux qu’elle. C’est ici que se justifie l’utilisation du masque en /32. Il ne faut surtout pas que nos serveurs réels répondent aux requêtes de qui que ce soit sur le sous-réseau 192.168.24.0, hormis celles venant du directeur dont l’IP est… la VIP !

Mais comme l’interface de loopback répond aujourd’hui aux requêtes ARP qu’elle reçoit, il va falloir aller faire un tour dans le fichier /etc/sysctl.conf et l’éditer comme suit :

net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.all.arp_announce=2
net.ipv4.conf.lo.arp_ignore=1
net.ipv4.conf.lo.arp_announce=2

Rechargez la configuration avec :

sysctl -p

Configuration des interfaces et de la VIP

La configuration s’effectue ensuite de manière classique, toujours sur un alias, dans /etc/network/intefaces :

auto lo:0
iface lo:0 inet static
	address 192.168.24.142
	netmask 255.255.255.255

Ici contrairement au mode LVS-NAT le directeur ne peut pas faire office de passerelle par défaut, il faut donc en configurer une autre (celle de votre sous réseau) pour que votre serveur réel puisse contacter vos clients.

Test du LVS

Ici comme nous sommes sur un service web, un simple navigateur suffit !

Enregistrement de la configuration

Pensez à enregistrer votre travail une fois terminé sinon vous risquez d’avoir une mauvaise surprise au redémarrage du directeur…

ipvsadm -Sn > /etc/ipvsadm_rules

ipvsadm_rules est normalement automatiquement rechargé au démarrage de Debian, en tout cas sur ma version.

Amusez-vous bien avec LVS ! Et n’oubliez pas, les commentaires sont là en cas de problème 🙂

Cet article vous a plu ? Partagez-le sur les réseaux sociaux !

Twitter Facebook Google Plus email