#liste_articles {display:block}

Linux Virtual Server

mercredi 25 août 2004

 

Comment monter une solution de load-balancing avec linux

Le but de cet article est de présenter une utilisation de LVS. LVS (Linux Virtual Server) désigne un module dans le kernel Linux ainsi que des outils qui vont avec.

Ce projet a pour but de proposer des solutions sous Linux pour pouvoir faire de la répartition de charge entre plusieurs machines de manière transparente pour l’utilisateur.

Ce qui veux dire d’un point de vue utilisateur, qu’il y a un serveur qui rend un service. Mais physiquement, il y a plusieurs machines qui peuvent faire le travail. Le serveur vu par le client est dit "virtuel".

Dans notre étude de cas, nous avons 2 machines physiques. Sur chaque machine, nous avons le service "daytime" activé. Le service "daytime" est un service qui ne fait que renvoyer la date.

Cela n’a pas d’intérêt mais sert d’exemple. Au final, on visent des services comme un proxy HTTP, un serveur web... Par contre ce qu’il faut c’est que les différentes machines impliquées soient capable de rendre le même service (ce qui convient bien pour un proxy HTTP, pour un serveur web, il faudra que les données soient identiques ou centralisées).

Nous avons donc 2 serveurs avec les services "daytime" activés.

Voici un exemple d’utilisation du service daytime sur une de ces machines :

[root@server1 root]# telnet localhost 13
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
20 AUG 2004 17:02:14 CEST
Connection closed by foreign host.

Dans notre étude nous avons donc 2 serveurs qui font du "daytime" et 1 machine cliente. Voici le schéma de notre réseau :

Elles ont pour adresses 192.168.0.115 et 192.168.0.128 et se trouvent sur le même réseau 192.168.0.0/24 (c’est important sinon cela ne fonctionnera pas).

L’adresse virtuelle vu par le client sera 192.168.0.110 et elle servira à accéder au service daytime qui sera traité soit par 192.168.0.115, soit par 192.168.0.128.

Pour cela, la machine 192.168.0.115 doit configurer LVS. La machine 192.168.0.128 doit aussi être modifié pour accepter le traffic de 192.168.0.110 (adresse virtuelle).

Nos 2 serveurs sont des Fedora Core 2. L’important c’est qu’il faut que LVS soit disponible pour la distribution et notre exemple ne fonctionnera que pour les kernels 2.6.x.

Configuration du redirecteur

Première chose, il faut installer le package ipvsadm-1.24-4.2.ipvs120.i386.rpm sur la machine 192.168.0.115.

Sur 192.168.0.115, l’interface réseau est eth0. Il faut alors créer un alias IP sur cette interface (mettre une deuxième adresse IP sur la même interface physique). Pour faire cela correctement sur la Fedora, il faut créer le fichier /etc/sysconfig/network-scripts/ifcfg-eth0:0 avec le contenu suivant :

DEVICE=eth0:0
IPADDR=192.168.0.110
NETMASK=255.255.255.0
NETWORK=192.168.0.0
BROADCAST=192.168.0.255
ONBOOT=yes

Après, il faut redémarré le service réseau à l’aide de la commande service network restart.

Vous pouvez alors vérifier que vous avez 3 interfaces (lo, eth0 et eth0:0 qui est l’alias sur eth0) :

[root@server1 network-scripts]# ifconfig
eth0      Lien encap:Ethernet  HWaddr 00:0C:29:C3:ED:BF
          inet adr:192.168.0.115  Bcast:192.168.0.255  Masque:255.255.255.0
          adr inet6: fe80::20c:29ff:fec3:edbf/64 Scope:Lien
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:824 errors:3 dropped:0 overruns:0 frame:0
          TX packets:484 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:1000
          RX bytes:80002 (78.1 Kb)  TX bytes:73541 (71.8 Kb)
          Interruption:177 Adresse de base:0x1080
 
eth0:0    Lien encap:Ethernet  HWaddr 00:0C:29:C3:ED:BF
          inet adr:192.168.0.110  Bcast:192.168.0.255  Masque:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:1000
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)
          Interruption:177 Adresse de base:0x1080
 
lo        Lien encap:Boucle locale
          inet adr:127.0.0.1  Masque:255.0.0.0
          adr inet6: ::1/128 Scope:Hôte
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:16 errors:0 dropped:0 overruns:0 frame:0
          TX packets:16 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 lg file transmission:0
          RX bytes:1019 (1019.0 b)  TX bytes:1019 (1019.0 b)

Il faut encore autoriser le routage. Pour cela, il faut éditer le fichier /etc/sysctl.conf et modifier la ligne "net.ipv4.ip_forward = 0" pour remplacer le 0 par un 1 comme dans l’exemple suivant :

# Kernel sysctl configuration file for Red Hat Linux
#
# For binary values, 0 is disabled, 1 is enabled.  See sysctl(8) and
# sysctl.conf(5) for more details.
 
# Controls IP packet forwarding
net.ipv4.ip_forward = 1
 
# Controls source route verification
net.ipv4.conf.default.rp_filter = 1
 
# Controls the System Request debugging functionality of the kernel
kernel.sysrq = 0
 
# Controls whether core dumps will append the PID to the core filename.
# Useful for debugging multi-threaded applications.
kernel.core_uses_pid = 1

Enfin, il faut que cette modification soit prise en compte, ce qui peut être fait avec la commande suivante :

[root@server1 etc]# sysctl -p /etc/sysctl.conf
net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 1
kernel.sysrq = 0
kernel.core_uses_pid = 1

Maintenant on peut passer à la configuration de LVS. Voici les commandes à taper :

[root@server1 etc]# ipvsadm -A -t 192.168.0.110:13 -s wlc
[root@server1 etc]# ipvsadm -a -t 192.168.0.110:13 -r 192.168.0.115 -g
[root@server1 etc]# ipvsadm -a -t 192.168.0.110:13 -r 192.168.0.128 -g

La première commande sert à définir le service. Il s’agit d’un service TCP (-t) sur le port 13 avec l’adresse virtuelle 192.168.0.110. L’option "-s wls" sert à choisir l’algo de répartition de charge. Il y a de nombreux algorithmes pour choisir lisez la documentation (man ipvsadm) et faite des tests de performance.

Les lignes suivantes servent à rajouter nos 2 serveurs dans la listes des machines qui font partie du service virtuelle sur 192.168.0.110.

Pour ne pas perdre ces commandes lors du prochain démarrage, sauvegardez les dans le fichier /etc/sysconfig/ipvsadm avec la commande "ipvsadm-save > /etc/sysconfig/ipvsadm" et assurez vous que le service ipvsadm sera bien démarré au prochain reboot en utilisant la commande "chkconfig ipvsadm on".

C’est fini pour la configuration du premier serveur qui fait la redirection pour lui et l’autre serveur.

Configuration du serveur secondaire

Il faut que cette machine accepte les paquets à destination de l’adresse virtuelle 192.168.0.110. Pour cela, nous allons faire un alias IP sur l’interface lo. Il faut créer le fichier /etc/sysconfig/network-scripts/ifcfg-lo:0 et y placer le contenu suivant :

DEVICE=lo:0
IPADDR=192.168.0.110
NETMASK=255.255.255.255
BROADCAST=127.255.255.255
ONBOOT=yes
ARP=no

Ensuite, il faut que l’on rajoute une route pour l’adresse 192.168.0.110 vers lo et non plus vers le réseau 192.168.0.0/24 (eth0). Pour cela, il faut créer le fichier /etc/sysconfig/network-scripts/route-lo:0 avec le contenu suivant :

192.168.0.110 dev lo

Enfin, on redémmarre le réseau pour prendre tout cela en compte :

[root@server2 etc]#service network restart

Il ne faut pas que le protocole ARP se perde dans tout cela. En effet, nous avons 2 machines qui ont la même IP (192.168.0.110) mais des adresses Ethernet différente. Nous ne voulons pas que le server 2 répondent lorsque ARP demande qui à l’adresse MAC qui correspond à 192.168.0.110. Donc nous allons partiellement désactiver ARP sur cette machine.

Pour cela, il faut modifier le fichier /etc/sysctl.conf et rajouter les 4 dernières lignes :

# Kernel sysctl configuration file for Red Hat Linux
#
# For binary values, 0 is disabled, 1 is enabled.  See sysctl(8) and
# sysctl.conf(5) for more details.
 
# Controls IP packet forwarding
net.ipv4.ip_forward = 0
 
# Controls source route verification
net.ipv4.conf.default.rp_filter = 1
 
# Controls the System Request debugging functionality of the kernel
kernel.sysrq = 0
 
# Controls whether core dumps will append the PID to the core filename.
# Useful for debugging multi-threaded applications.
kernel.core_uses_pid = 1
 
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2

Et pour prendre en compte ces modifications, utiliser la commande :

[root@server2 etc]# sysctl -p /etc/sysctl.conf
...

Voilà notre service daytime se trouve maintenant load-balancé entre 2 machines et on y accéde comme suit :

[user@client user]$ telnet 192.168.0.110 13
Trying 192.168.0.110...
Connected to 192.168.0.110.
Escape character is '^]'.
20 AUG 2004 18:21:06 CEST
Connection closed by foreign host.

Pour vérifier que l’on passe bien par une machine ou par une autre, il vous suffit changer la date sur un des serveurs. Vous verrez alors que des fois vous avez la bonne date et des fois la mauvaise.

Principe

Le but de cet article n’est pas d’entrer dans les détails mais juste d’avoir une idée du fonctionnement. LVS a 3 modes de fonctionnement nous utilisons le mode "DR-Routing". Dans ce cas, les machines doivent être dans le même domaine à collisions.

Pourquoi ? Parce que sur un réseau Ethernet, les paquets utilisent des adresses MAC pour indiquer la source et le destinataire. Or nous travaillons avec des adresses IP. C’est le protocole ARP qui fait la correspondance en demandant tout simplement à tout le monde s’ils ont l’adresse MAC qui correspond à l’IP connue.

Dans notre cas, c’est le serveur de redirection qui va répondre avoir l’adresse IP virtuelle et donc recevoir les paquets. Après VLS prend la suite. Si le paquet doit être redirigé, on ne touche pas à la partie IP mais on change l’adresse MAC du destinataire par celle du deuxième serveur et le paquet repart sur le réseau.

Le deuxième serveur ayant aussi la route pour l’adresse IP virtuelle, il se l’envoie à lui même en loopback.

La seule chose c’est qu’il faut que personne (à part le redirecteur) sache que la deuxième machine a aussi l’adresse virtuelle. C’est pour cela que l’on change certain paramètres du fonctionnement de ARP.

Voici un schéma qui montre la redirection qui se fait au niveau Ethernet :

Les références

Description Adresse
Site du projet LVS http://www.linuxvirtualserver.org/
Exemple de DRouting http://www.linuxvirtualserver.org/V...
Les problèmes avec ARP et LVS http://www.austintek.com/LVS/LVS-HO...

Documents :

par Daniel Lacroix