Pavnay

 
  • Increase font size
  • Default font size
  • Decrease font size
FrançaisEnglish

[Système] Clustering d'IP et répartiteur de charge

Imprimer
Système

Le clustering d'IP permet de mettre en oeuvre un répartiteur de charge entre différents serveurs.
Ainsi, si l'on dispose de plusieurs machines, il est possible de les faire apparaître comme une seule et même machine tout en équilibrant les ressources mais aussi en étant "imperméable" au panne.

Il est possible de monter des clusters basés sur à peu près n'importe quel protocole comme les protocoles HTTP, MySQL et SMTP par exemple.
La mise en place de tels clusters est simple et nous allons voir comment installer le socle commun à ces différents clusters puis leurs configurations.

  1. Logiciels nécessaires
  2. ipvsadm
  3. ldirectord
  4. Configuration d'un cluster HTTP
  5. Configuration d'un cluster MySQL
  6. Configuration d'un cluster SMTP
  7. Problèmes rencontrés

Logiciels nécessaires


Les logiciels que nous allons installés sont tout à fait commun dans le monde open source et tous disponibles en un seul package : UltraMonkey.
Le problème du package UltraMonkey pour Debian est qu'il n'existe que pour l'architecture 32bits et que pour la compilation, la chose n'est pas aisée.

Cependant, il et tout à fait possible de monter les clusters sans l'aide d'UltraMonkey mais en installant les logiciels un par un.

Tout d'abord l'utilitaire de clustering en lui-même : ipvsadm (du projet Linux Virtual Server (LVS) ).
Ipvsadm
permet de monter le cluster en ligne de commande.

Parce que ipvsadm ne permet "que" de gérer les clusters et les machines au sein de ces clusters, il est possible d'utiliser un logiciel permettant de veiller à ce que les machines de ces clusters soient aptes à répondre aux requêtes. Ce logiciel est ldirectord.


ipvsadm


Une fois ipvsadm installé (via la commande apt-get install ipvsadm), il est désormais possible de créer des clusters.
La création de cluster et de machine au sein de ces clusters se fait par ligne de commande :

Création du cluster :

 ipvsadm -A -t 192.168.1.225:80 -s rr 


Quelques explications :
  • La création du cluster se fait via l'option -A (Add)
  • L'option -t correspond au protocole TCP. Pour un service en protocole UDP, utilisez l'option -u. Il est possible de combiner les "redirections" avec iptables en utilisant l'option -f, auquel cas la fonctionnalité mark d'iptables sera utilisée.
  • Puis vient la définition du cluster, plus exactement du service. Ici le cluster tournera sur l'adresse IP locale 192.168.1.225 et sur le port 80.
  • La dernière option ici, -s correspond à l'algorithme de répartition de la charge entre les serveurs du cluster. Ici l'algorithme choisit est le Round-Robin (rr) mais il existe aussi le Weighted Round-Robin (wrr) le Least Connected (lc) et le Weighted Least Connected (wlc)

Ajout de machines :

ipvsadm -a -t 192.168.1.225:80 -r 192.168.1.203:80 -g 


Quelques explications :
  • L'ajout d'un serveur dans un cluster se fait par l'option -a (add)
  • Puis vient le type de service (ici TCP)
  • Puis la définition du cluster (adresse IP et port)
  • Suit la définition du serveur distant à intégrer (adresse IP et port) avec l'option  -r
  • Et ici enfin le type de connexion : -g pour gate

Suppression d'un serveur d'un cluster :

ipvsadm -d -t 192.168.1.225:80 -r 192.168.1.203:80 


Quelques explications :
  • L'option -d est le flag pour supprimer une machine d'un cluster
  • L'option -t correspond au type de service définit lors de l'ajout du serveur dans le cluster
  • 192.168.1.225:80 est ici le cluster impacté
  • -r détermine le la machine à retirer du cluster (pour remove)

Lister les clusters :

ipvsadm -ln


Quelques explications :
  • L'option -l permet de lister tous les clusters d'IP installés sur le serveur ainsi que les serveurs de chaque cluster
  • L'option -n permet de ne pas résoudre le couple port / protocole (par exemple affichera 3306 au lieu de mettre le protocole mysql)

Suppression d'un cluster :

ipvsadm -D -t 192.168.1.225:80 


Avec ces commandes, il est maintenant possible de gérer un cluster d'IP.
Mais ce n'est pas suffisant pour qu'il soit fonctionnel. En effet, la partie serveur / cluster est paramétrable mais il faut en plus configurer les machines qui seront dans le pool de connexion afin qu'elles puissent répondre au cluster.

Pour qu'une machine puisse intégrer un cluster efficacement, il faut :
  • Paramètrer le kernel soit dans le /etc/sysctl.conf ou à ajouter dans un initscript au démarrage des machines
Pour le fichier /etc/sysctl.conf :

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


Pour l'initscript :

echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore 
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce

  • Selon la méthode, il faudra soit executer les 2 commandes ou lancer un sysctl -p pour charger les paramètres.
  • Ajouter dans le /etc/network/interfaces des machines à intégrer au cluster
# Interface LoadBalancee 
auto lo:225
iface lo:225 inet static         
         address 192.168.1.225         
         netmask 255.255.255.255         
         network 192.168.1.225         
         broadcast 192.168.1.225         
         up /sbin/route add -host 192.168.1.225 dev lo         
         down /sbin/route del -host 192.168.1.225

  • Puis monter la nouvelle interface réseau : ifup lo:225
Parce que la création d'un cluster et l'ajout ou suppression d'un serveur à l'intérieur n'est pas forcément pratique en ligne de commande et parce que si une machine tombe elle restera dans le cluster et ainsi provoquera des problèmes, il convient d'utiliser une autre utilitaire : ldirectord.

ldirectord


ldirectord est diponible en téléchargement ( ici ) ou par package ( apt-get install ldirectord ).
Cet utilitaire fournit des facilités pour la création et la gestion de cluster. Il ne fonctionne que grâce à un fichier de configuration ( /etc/ha.d/ldirectord.cf ).

Une version internet de la manpage de ldirectord est disponible ici.

Le fichier de configuration de ldirectord se compose de 2 parties, la première pour les paramètres généraux puis une partie pour les clusters eux mêmes.

Première partie :

checktimeout=5 
checkinterval=10
autoreload=no
logfile="/var/log/ldirectord.log"
quiescent=no


Quelques explications :
  • checktimeout : la durée maximale d'attente pour déclarer une machine up en seconde
  • checkinterval : la durée etre deux vérifications de la validité d'une machine d'un cluster en seconde
  • autoreload : prendre les modifications  à chaud du fichier de configuration
  • logfile : fichier de log de ldirectord (ajout / suppression de machines dans les clusters)
  • quiescent : si cette option est à yes, une machine déclarée comme invalide (par exemple ne répondant pas au ping) ne sera pas retirée du cluster mais verra son poids mis à 0 et ainsi n'acceptera plus de nouvelles connexions mais continuera de répondre (si elle le peut) aux connexions déjà ouvertes.
Il existe bien d'autres options mais celles-ci me semble les plus importantes...
Toute option déclarée dans cette partie peut être surchargée dans la définition d'un cluster.

Seconde partie : les clusters

virtual=192.168.1.225:80         
           real=192.168.1.203:80 gate 1
           real=192.168.1.204:80 gate 2
           service=http
           request="/index.html"
           receive="OK"
           scheduler=wrr
           protocol=tcp
           checktype=negotiate 
           fallback=192.168.1.205:80 gate


Quelques explications :
  • virtual : le cluster en lui-même définit par l'adresse IP du cluster et son port / protocole
  • real : une machine à intégrer au cluster définit par l'adresse IP du serveur, de son port / protocole puis le mode de communication. gate permet de mettre en relation directement le client avec le serveur, masq permet de faire du masquerading entre le serveur de cluster et le serveur réel (à activer avec iptables). Enfin, le dernier paramètre de cette ligne est le poids affecté à chaque serveur réel
  • service est le service utilisé pour le cluster (par exemple http, mysql, smtp, ftp, ldap, etc...)
  • request : la requête que le cluster doit effectuer pour savoir si le serveur réel est opérationnel
  • receive : expression régulière que ldirectord utilise sur le résultat de request pour savoir si le serveur réel est opérationnel
  • scheduler : le type de répartiteur de charge (rr, wrr, lc, wlc, etc...)
  • protocol : protocole utilisé (tcp, udp)
  • checktype : type de vérification : negociate pour l'utilisation de request et receive, ping pour... un ping, external pour l'utilsation d'un script externe (par exemple un script bash personnalisé) en combinaison avec checkcommand
  • fallback : détermine un serveur réel qui n'entre dans le cluster si et seulement le cluster est vide (tous les autres serveurs ont été détectés comme inactifs). Cette option est pratique pour mettre par exemple une webapp de maintenance indiquant qu'un problème technique est survenu dû à la surcharge par exemple...
Ci dessous des exemples de la seconde partie pour des clusters fonctionnels utilisés en production.

Configuration d'un cluster HTTP


Utilisé pour le searcher SOLr

virtual=192.168.200.225:80
           real=192.168.200.201:80 gate
           real=192.168.200.203:80 gate
           service=http
           request="/solr_blogs/admin/ping"
           receive="OK"
           scheduler=wrr
           protocol=tcp
           checktype=negotiate 


Configuration d'un cluster MySQL


2 serveurs réels dans le cluster plus un serveur pour le cas où les deux premiers sortiraient. Les deux premiers serveurs sont en réplication du dernier.
Dans ce cluster, le script /root/scripts/check_mysql.sh fait une vérification d'accessibilité aux bases de données et vérifie que le retard de la réplication n'est pas trop important.

Le cluster :

virtual=192.168.1.152:3306
           real=192.168.1.102:3306 gate 100
           real=192.168.1.103:3306 gate 100
           fallback=192.168.1.101:3306 gate 1
           service=mysql
           scheduler=wrr
           checktype=external
           checkcommand="/root/scripts/check_mysql.sh"


Le script :

#!/bin/bash

VIRTUAL_SERVER=$1
VIRTUAL_PORT=$2
REAL_SERVER=$3
REAL_PORT=$4

MAX_LATE=200

OK=0
KO=1

PID=$$
FILE=/tmp/mysql_${3}.${PID}

RETURN=$KO

RES=$(mysql -umonitoring -pmonitoring -h${REAL_SERVER} -N -e "SELECT 1;")


if [ "$RES" == "1" ];
then
    LATE=$( mysql -umonitoring -pmonitoring -h$3 -e "SHOW SLAVE STATUS\G" | grep Seconds_Behind_Master | awk '{print $2}')

    if [ $LATE -lt $MAX_LATE ];
    then
            RETURN=$OK
        
           fi 
fi

if [ $RETURN -eq $OK ];
then
    echo "$REAL_SERVER OK" >> /tmp/cluster.sql
else
    echo "$REAL_SERVER NOK" >> /tmp/cluster.sql
fi

exit $RETURN


Une deuxième possibilité de cluster ne faisant pas intervenir de script externe mais une simple requête SQL :

virtual=192.168.1.152:3306
           real=192.168.1.102:3306 gate 100
           real=192.168.1.103:3306 gate 100
           fallback=192.168.1.101:3306 gate 1
           service=mysql
           login="monitoring"
           passwd="monitoring"
           scheduler=wrr
           checktype=negociate
           request="SELECT 1;"
           receive="1"
           database="pavnay"
 


Configuration d'un cluster SMTP


Ce cluster ressemble au cluster MySQL par l'utilisation d'un script externe mais qui envoie un mail.

Le cluster :
virtual=192.168.1.153:25
           real=192.168.1.50:25 gate
           real=192.168.1.51:25 gate
           real=192.168.1.53:25 gate
           checkinterval=30
           scheduler=wrr
           protocol=tcp
           checktype=external
           checkcommand="/root/scripts/check_smtp.sh"


Le script :

 #!/bin/bash

VIRTUAL_SERVER=$1
VIRTUAL_PORT=$2
REAL_SERVER=$3
REAL_PORT=25

PID=$$
FILE=/tmp/smtp_${REAL_SERVER}.${PID}

echo -n -e "HELO pavnay\r\nMAIL FROM: <webmaster@pavnay.fr>\r\nRCPT TO: <webmaster@pavnay.fr>\r\nDATA\r\nFrom: nc\r\nTo: me\r\nSubject: $3 - $(date)\r\n$(date)\r\n.\r\nQUIT\r\n" | nc -t $REAL_SERVER $REAL_PORT>$FILE

COUNT=$(tail -3 $FILE | egrep -c -e "250 ok .+ qp" )

if [ "$COUNT" == "1" ];
then
    RETURN=0
else
    RETURN=1
fi

echo "CHECK MX - $3 - $(date) $COUNT / $RETURN" >> /tmp/cluster.mx

rm $FILE 
exit $RETURN


Problèmes rencontrés


  • Mode gate et les ports :
Nous avons tenter de mettre plusieurs serveurs HTTP sur un même serveur physique en les faisant tourner sur des ports différents et de mettre ces serveurs d'application dans un cluster.
En mode gate, il n'est pas possible de jouer sur plusieurs ports vers une même adresse IP. En effet, seul le protocole définit pour le cluster est pris en compte (par exemple le protocole http dessert le port 80 et par conséquent, tous serveurs au sein de ce type de cluster seront interrogés sur le port 80.
Une possibilté est d'utiliser le mode masq mais plus compliquer à mettre en place...

  • Cluster MySQL et pool de connexion :
Nous utilisons couramment Tomcat et le pool de connexion JDBC.
Le problème qui est survenu est la durée de vie des connexions entre le pool et le cluster.
Une possibilté est d'augmenter la durée de vie des connexions du cluster grâce à l'option persistent et une durée en seconde.

Commentaires
Ajouter un nouveau
+/-
Ecrire un commentaire
Nom:
Email:
 
Titre:
 
:D:):(:0:shock::confused:8):lol::x:P:oops::cry:
:evil::twisted::roll::wink::!::?::idea::arrow:
 
mo   |2010-06-03 16:22:20
Tutoriel bien écrit, bravo. Quelques corrections pour le perfectionner

-r
détermine le la machine à retirer du cluster (pour remote) => remove

Il
existe bien d'autres options mais celle-ci me semble les plus importantes... =>
celles-ci

mais verra son poid => poids

virtual : le clsuter en lui-même =>
cluster

Ce cluster ressemble au cluster MySQL par l'utilisation d'un script
externe mais qui envoi un mail. => envoie

Nous avons tenter de mettre plusieurs
serveur HTTP => serveurs
Febbweiss   |2010-06-03 23:02:52
Merci pour ces remarques et désolé pour la gêne occasionnée par mes
fautes...

Texte corrigé
mo  - pas de soucis ...   |2010-06-08 00:01:03
... et merci pour la qualité du tutoriel :-)
ugg boots black  - ugg boots black   |2010-11-15 07:43:37
Ce cluster ressemble au cluster MySQL par l'utilisation d'un script
externe mais
qui envoi un mail. => envoieugg boots black

3.26 Copyright (C) 2008 Compojoom.com / Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved."

 

Actualités

Peinture sur figurine