Mise en place d'une solution de load balancing hautement disponible

Gabès Jean ( 30 Jun 2009 ) blog Talk /

Nous avons vu le principe de la solution de load balancing hautement disponible, regardons désormais comment la mettre en place.

Les load balanceurs

Description

Nous allons appeler les répartiteurs de charges:

  • frontal1 (192.168.0.1)
  • frontal2 (192.168.0.2)
  • l'IP virtuelle (VIP) est 192.16.8.0.3
  • le service sera sur le port 80.

La distribution de notre exemple sera ici une Redhat entreprise 4, mais il est très facile de généraliser pour d'autres.

Les serveurs réels seront:

  • reel1 (linux) en 192.168.0.4
  • reel2 (linux) en 192.168.0.5

Les composants importants sont:

  • Heartbeat afin de faire la bascule en cas de mort d'un loadbalanceur
  • ldirector qui se charge de configurer et surveiller les serveurs réels
  • ipvsadm qui contrôle le module LVS du noyau (ip_vs)

Installation

En terme de package RPM ceci donne à installer (rpm -Uvh *rpm) :

  • heartbeat-2.0.7-1.c4.i386.rpm
  • heartbeat-ldirectord-2.0.8-2.el4.centos.i386.rpm
  • heartbeat-pils-2.0.7-1.c4.i386.rpm
  • heartbeat-stonith-2.0.7-1.c4.i386.rpm
  • ipvsadm-1.24-6.i386.rpm
  • perl-Authen-Radius-0.13-1.el4.rf.noarch.rpm
  • perl-Data-HexDump-0.02-1.2.el4.rf.noarch.rpm
  • perl-Digest-HMAC-1.01-13.noarch.rpm
  • perl-Digest-SHA1-2.07-5.i386.rpm
  • perl-IO-Socket-SSL-1.01-1.el4.rf.noarch.rpm
  • perl-Mail-POP3Client-2.17-1.c4.noarch.rpm
  • perl-MailTools-1.76-1.el4.rf.noarch.rpm
  • perl-Net-DNS-0.59-5.el4.i386.rpm
  • perl-Net-IMAP-Simple-1.16-1.c4.noarch.rpm
  • perl-Net-IMAP-Simple-SSL-1.3-1.c4.noarch.rpm
  • perl-Net-IP-1.25-3.el4.noarch.rpm
  • perl-Net_SSLeay.pm-1.25-4.el4.at.i386.rpm
  • perl-TimeDate-1.16-3_2.el4.at.noarch.rpm

Ces versions sont valables pour une RHES 4U4. Ils sont disponibles sur http://mirror.centos.org/centos/4/extras/i386/RPMS/

Une fois tous ces packages installés, il faut les configurer. Nous allons nous placer dans une configuration en mode direct.

Configuration de Heartbeat

Notre configuration commence par celle de Heartbeat. Nous allons commencer par configurer un simple cluster actif/passif d'une adresse virtuelle, 192.16.8.0.3. Elle ne sera active que sur un des frontaux à la fois. Si le maitre tombe, le second prend la main.

Le fichier de configuration principal est /etc/ha.d/ha.cf sur chaque frontal.

Ici sur le serveur frontal1 :

ucast         eth0 192.168.0.2
debugfile     /var/log/ha-debug
logfile       /var/log/ha-log
logfacility   local0

keepalive     2
deadtime      10
warntime      6
initdead      60

udpport       694
node          frontal1
node          frontal2

auto_failback on

Le fichier de configuration de frontal2 ne va différer que de la première ligne :

ucast         eth0 192.168.0.1

La ligne ucast permet d'aller vérifier si l'autre noeud est toujours en vie ou non. Il est possible de spécifier une autre interface que eth0 si on possède un lien dédié à cette communication. Ici par soucis de facilité, nous utiliserons le lien LAN normal.

Le fichier /etc/ha.d/haresources qui décrit les services mis en place par HeartBeat. Pour l'instant, nous nous contentons de l'adresse virtuelle :

frontal1 IPaddr::192.168.0.3

IPaddr est un script dans /etc/ha.d/resource.d qui permet de monter une adresse sur un alias d'interface. Ici il va créer eth0:0 avec comme IP 192.168.0.3. Il est important de comprendre que ce script est appelé avec start sur le maitre, stop sur l'esclave.

Lorsqu'une bascule s'opère, c'est tout simplement l'inverse et donc le neoud secondaire prends l'IP.

Les deux noeuds ont besoin de s'authentifier. Pour cela, il faut éditer le fichier /etc/ha.d/authkeys qui décrit comment communiquent les deux noeuds :

auth 2
1 md5 "vive ipvs"
2 crc

Faire un :

chmod 600 /etc/ha.d/authkeys

Il faut ajouter le lancement de heartbeat au démarrage des deux frontaux :

chkconfig --add heartbeat
chkconfig heartbeat on

Lancer les services sur les deux frontaux avec :

/etc/init.d/heartbeat start

Vous pouvez vérifier que vosu avec un alias de monté sur le noeud maitre et pas sur le noeud secondaire :

eth0      Link encap:Ethernet  HWaddr 00:50:57:85:5C:96
inet addr:192.168.0.1  Bcast:192.168.0.255  Mask:255.255.255.0
[...]
eth0:0    Link encap:Ethernet  HWaddr 00:50:57:85:5C:96
inet addr:192.168.0.3  Bcast:192.168.0.255  Mask:255.255.255.0
[...]

On remarque que eth0 est toujours disponible, mais que eth0:0 est apparu avec notre VIP.

Configuration de Ldirectord

Une fois HeartBeat de configuré, penchant nous sur la mise en place de ldirectord qui va gérer les règles de load balancing.

Ldirectord utilise des fichiers de conf situé dans /etc/ha.d/conf, soit dans la configuration de Heartbeat. C'est en effet ce dernier qui le lancera sur le noeud primaire uniquement. Le mieux concernant ldirectord est de faire un fichier de conf par service. Ici nous prendrons le fichier /etc/ha.d/conf/www.cf :

virtual = 192.168.0.3:80
protocol = tcp
scheduler = wlc
real = 192.168.0.4:80 gate 1
real = 192.168.0.5:80 gate 1
checktype = connect
quiescent = no
persistent = 3600
fallback = 127.0.0.1:80

Les paramètres sont :

  • gate : mode direct
  • 1 : poids du nœud par rapport aux autres
  • scheduler : algorithme de détermination du serveur réel a qui envoyer le client
  • checktype : mode de supervision, ici simple ouverture de port
  • quiescent : si mis à no, le serveur réel est retiré de la liste lorsqu'il est mort. S'il revient, il est automatiquement ajouté
  • persistent : durée des sessions
  • fallback : serveur qui prends le relai lorsque tous les serveurs réels sont morts. typiquement c'est juste un 404.html avec un message d'erreur.

Configuration de la synchronisation de la table des sessions

La table des sessions sur le frontal1 peut (doit!) être synchronisée sur le frontal2 de temps en temps (toutes les 30secondes environs).

En effet, en cas de tombée du serveur1, lorsque le 2 arrive, s'il n'a pas déjà la table des sessions, les utilisateurs vont devoir se reconnecter. Un système existe afin de synchroniser les serveurs.

Pour cela, créer le fichier /etc/init.d/lvsstate sur les deux frontaux :

#!/bin/sh
#
#  Created 2000-01-03 by naparuba@gmail.com
#
# lvsstate      This shell script takes care of starting and stopping
#               sessions managers for IPVS.
#
# chkconfig: -  80 30
# description: ipvs_syncmaster is a daemon for syncronising sessions\
#              between two IPVS.
# processname: ipvs_syncmaster
# config: /none.cfg

case "$1" in
 start)
    /sbin/ipvsadm --start-daemon backup --syncid=1
    /sbin/ipvsadm --start-daemon master --syncid=1
 ;;
 stop)
    /sbin/ipvsadm --stop-daemon=backup
    /sbin/ipvsadm --stop-daemon=master
 ;;
 restart)
    $0 stop
    $0 start
 ;;
 status)
    ipvsadm -L --daemon
 ;;
 *)
    echo "Usage: $0 {start|stop|restart|status}"
esac

exit 0

Attention, il y a la paramètre syncid qui permet de ne pas entrechoquer plusieurs LVS sur le réseau. On peut définir par exemple :

  • 3 = TEST
  • 2 = QUALIF
  • 1 = PROD
  • 0 = non configuré!

Ainsi, si le service est en mode heartbeat primaire, il est en mode master lvs, et en mode heartbeat secondaire, il est backup dans le mode lvs. Pour info, seules les sessions en état ESTABLISHED sont transférées. Les sessions mortes ou non encore actives ne sont pas transmises. De plus, les deux noeuds doivent avoir la syncronisation active en même temps. Les deux peuvent avoir de lancé le backup et le master, ce ci ne pose pas de soucis.

Puis on les met au démarrage de la machine :

chkconfig --add lvsstate
chkconfig lvsstate on
/etc/init.d/lvsstate start

Une fois ceci réalisé, il est temps d'ajouter ldirectord dans les ressources HeartBeat afin qu'il soit lancer sur le noeud maitre et que le noeud secondaire prenne la main si besoin.

Dans le fichier /etc/ha.d/haresources :

frontal1 IPaddr::192.168.0.3 ldirectord::www.cf

La règle dans haressources est simple : on lancer de gauche à droite, et on arrète de droite à gauche. Donc ici, on montera bien la VIP avant de lancer le load balancing.

On peux vérifier que c'est bien lancé avec :

ipvsadm -L

Les serveurs réels

Nous avons vu dans le post précédent que les serveurs réels dans le cas du mode direct on besoin de la VIP, mais ne doivent pas répondre à l'ARP sur cette VIP. L'astuce ici est de configurer un alias d'interface avec la VIP (ici 192.168.0.3) et de bloquer les requêtes ARP sur cette adresse (car seul le loadbalanceur doit répondre pour cette VIP).

Il faut monter un alias d'interface en tant que VIP. Nous considérons ici que seule l'interface eth0 est active pour le serveur. Nous allons donc créer l'alias eth0:0. Cependant, il ne faut pas que l'interface réponde à l'ARP, ne serait-ce qu'une seule réponse!

On demande au noyau de ne pas répondre sur les alias d'interfaces : Dans le fichier /etc/sysctl.conf :

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

Pour les paramètres: arp_annonce : détermine les adresse ip source annoncée dans les requêtes ARP émises. * 1 : utilise une IP source qui correspond au sous réseau cible sur une interface primaire ou secondaire/aliasée * 2 : seules les interfaces primaires peuvent répondre

arp_ignore : détermine l'adresse MAC à retourner en réponse ARP * 0 : adresse MAC quelconque de la machine * 1 : utilise l'ARP seulement si elle est configurée avec l'ip cible de la requête * 8 : inhibe l'ARP totalement

L'alias va être monté sur lo0. Pour cela, il faut créer le fichier /etc/sysconfig/network-scripts/ifcfg-lo:1 :

DEVICE=lo:1
IPADDR=192.168.0.3
NETMASK=255.255.255.255
NETWORK=192.168.0.0
ONBOOT=yes
ARP=no

Il faut s'assurer que le programme loadbalancé ouvre bien sur l'ensemble des interfaces son port, ou à défaut au moins sur la VIP.

Le Sorry Server

Le Sorry Server est en fait un serveur de repli lorsque tous les serveurs réels sont tombés. C'est la clause fallback = 127.0.0.1:80 du fichier de configuration dans ldirectord. La situation la plus courante est de le placer directement sur le loadbalanceur afin d'afficher un message comme quoi l'application est en maintenance (on est gentils, on ne va pas dire qu'elle s'est encore plantée...).

Nous allons donc mettre un Apache minimum sur les frontaux qui ne va servir que pour une page. Il faut éditer le fichier /etc/httpd/conf/httpd.conf :

ErrorDocument 404 /error/404.html

Puis générer le fichier /var/www/error/404.html comme souhaité (sympa quoi) puis lier l'index pour être plus propre :

ln -s /var/www/error/404.html /var/www/html/index.html

Dans le fichier de conf d'apache, on va limiter le nombre de processus. Dans le module IfModule prefork.c :

StartServers 2
MinSpareServers 2
MaxSpareServer 10

Et encore, ces valeurs sont un peu élevées, mais bon.

En conclusion

Et voila, vous avez entre les mains une solution fonctionnelle et performante pour faire de la répartition de charge hautement disponible. Nous verrons dans un prochain post comment l'administrer et surtout la superviser.


Archives