Installation et configuration d'un cluster
Publié le jeudi 09 mai 2013, 16:12 - modifié le 07/07/16 - Bidouilles - Lien permanent
- Article
- |
- Commentaires (2)
- |
- Annexes (2)
Cluster ! Le mot est lancé et il fait peur !! Mot compliqué et lié à des termes abscons comme Node
ou Concentrateur
. Et puis, sur le marché, ça fait sérieux et ça coute cher, donc c'est clairement pas le truc à refiler à des débutants !!
... Enfin, c'est l'idée que j'en avais, car au final, c'est pas si compliqué que ça ; tout ce qu'il faut, ce sont des bonnes connaissances en réseau.
Qu'est-ce que j'appelle ici Cluster ?
Il s'agit d'un mécanisme double, permettant l'accès à une information quel que soit l'état de mes ressources. Ainsi, je veux pouvoir être en état d'accéder à ce que je souhaite même si la moitié de mon infra est morte. Pour cela, trois notions sont habitellement associés :
- Le cluster failover qui permet de basculer sur une ressource secondaire si le serveur primaire en down
- Le load balancer qui permet de répartir équitablement l'usage des ressources pour ne pas laisser tout s'executer sur la même (ce qui permet d'une part, de ne pas la faire flancher trop rapidement et, d'autre part, d'avoir de meilleures perfs)
- La redondance d'information entre les ressources constituant le cluster afin de ne pas perdre de données en cas de bascule (légérement hors-sujet, je dois l'avouer, mais fortement lié à l'architecture désirée)
Un peu de vocabulaire
- On appelle node, le serveur effectuant la tâche demandé par le client. C'est sur ce serveur que l'applicatif désiré par le client se trouve.Un peu de vocabulaire
- On appelle node, le serveur effectuant la tâche demandé par le client. C'est sur ce serveur que l'applicatif désiré par le client se trouve.
- On appelle concentrateur (on voit aussi le terme de directeur, parfois), le serveur prenant en charge la requête du client et la répartie en fonction de la charge (load balancer) ou de l'état des Nodes (failover).
On le voit ici (et également dans le schéma ci-dessous), le concentrateur ne fait juste office de passerelle intelligente
se s'occupe que de router les paquets sur les nodes les plus adaptés. Pour l'utilisateur, c'est transparent (car il se connecte toujours via la même IP) mais il est fort probable que les divers traitements demandés soient gérés par des serveurs différents.
- On appelle concentrateur (on voit aussi le terme de directeur, parfois), le serveur prenant en charge la requête du client et la répartie en fonction de la charge (load balancer) ou de l'état des Nodes (failover).
On le voit ici (et également dans le schéma ci-dessous), le concentrateur ne fait juste office de passerelle intelligente
se s'occupe que de router les paquets sur les nodes les plus adaptés.
0. Présentation de l'infrastructure
Ce que je souhaite réaliser ici est l'un des usages les plus communs pour un cluster : un serveur Web doit être up 100% du temps. Pour ce faire, on monte un cluster avec 2 nodes strictement identiques dans leur configuration : même serveur Apache, même version, et même SGBDR (Car dès lors que l'on a un petit site Web, on a forcément besoin d'une base de données). La difficulté ici, est que si un node tombe,comment se passera le stockage dans le base de données ? Même question pour quand le node remontera ? Ici, on a beaucoup de chances, car MySQL gère un type de connexion Maître/Maître qui permet la mise-à-jour du cluster quel que soit le node sur lequel les données ont été écrites.
Au regard du schéma, je sens poindre une question : Oui, mais si le concentrateur tombe, comment qu'on fait ?
Question très judicieuse mais qui ne sera pas abordé ici (sachez toutefois que des solutions existent). Dans le cas présent, j'ai postulé que le Concentrateur, c'est le petit frère de Rambo, il a fait le Viet-Nam, la Thailande, la Corée du Nord, alors merde, c'est pas une petit coupure de courant qui va le faire chier !!
N'ayant pas des masses de matos, j'ai cloné 2 fois la même VM sur VirtualBox de façon à avoir des machines strictement identiques. Tout juste ai-je rajouté MySQL et Apache sur les deux nodes.
1. Autoriser le transfert des paquets sur Concentrateur
Pour ceux qui ont déjà monté des gateway, cette opération devrait déjà être réalisé Il s'agit juste d'autoriser le transfert des paquets du sous-réseau des nodes, vers le réseau global. En effet, comme le montre le schéma au-dessus, le concentrateur a deux interfaces pour permettre le NAT entre les deux réseaux. Du coup, il suffit d'autoriser le transfert de paquet et de rajouter une règle de NAT à iptables :
echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
A noter que, dans mon cas, l'interface vers le réseau public étant eth0
, ma règle iptables route les paquets vers cette interface.
2. Préparation des nodes
Dès lors que le forwarding des paquets a été autorisés, on peut tenter d'accéder au réseau global à partir des nodes (en reconfigurant /etc/resolv.conf, vous pouvez même faire vos mises à jour ).
ping 192.168.1.1
Si le ping répond comme il faut, il ne reste plus qu'à bloquer le transfert de paquets SUR cette machine, puis créer une page bidon pour tester Apache (j'ai utilisé ip addr show
car l'IP apparaît bien, mais n'importe quoi fera l'affaire)
echo 0 > /proc/sys/net/ipv4/ip_forward ip addr show > /var/www/html/index.html service httpd restart
3. Installation load balancer
Pour la mise en place de ma solution de load balancing, comme souvent, de nombreuses possibilités s'offraient à moi. Dans le cas présent, j'ai décidé d'utiliser LVS car c'est un projet récent, sympa et bien supporté. En plus, les RPMs existent et sont déjà diffusés par Red Hat
[root@localhost ~]# yum install ipvsadm
Une fois LVS, installé, il faut charger ses modules dnas le noyau mais attention ! Des modules supplémentaires doivent être défini. En effet, ce qui rend un Concentrateur spécial et qui fait de lui plus qu'une gateway est sa capacité à définir sur quel node doit être envoyé les informations transmises. Pour cela, plusieurs algorithmes de décisions existent tels que le Round Robin (RR, accès séquentiel) ou le Weighted Round Robin (WRR, accès séquentiel ou une node de poids double est deux fois plus sollicité que les autres). Dans mon cas, j'ai décidé de rester sur du Round Robin classique.
[root@localhost ~]# modprobe ip_vs [root@localhost ~]# modprobe ip_vs_rr [root@localhost ~]# ipvsadm -A -t 192.168.1.35:80 -s rr [root@localhost ~]# ipvsadm -a -t 192.168.1.35:80 -r 192.168.0.2:80 -m -w 1 [root@localhost ~]# ipvsadm -a -t 192.168.1.35:80 -r 192.168.0.3:80 -m -w 1
Je charge donc les modules nécessaires et précise à ipvsadm que l'algorithme de décision sur le port 80 (puisqu'on tente de faire un cluster avec un serveur Web) se fera sur la base de Round Robin. Ensuite, j'ajoute des serveurs à cette règle de clusters en faisant du NAT vers les ports 80 de mes deux nodes avec un poids de 1.
Comme on ne fait que du Round Robin, on n'a, a priori, pas besoin de spécifier un poids quelconque. Toutefois, par défault, LVS ne prendra pas en compte un node de poids 0 (ce qui, d'ailleurs, se tient)
4. Test avec le poste client
Il ne reste donc plus qu'à tester le fonctionnement. Pour cela, à partir du poste client (une machine hors du cluster), je lance plusieurs curl 192.168.1.35 vers le concentrateur qui redirige tout ça vers les différents nodes. Un résultat équivalent à celui ci-dessous devraient confirmer le bon fonctionnement du cluster :
iMac-de-Jean-Baptiste-Langlois:~ mithweth$ curl 192.168.1.35 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 08:00:27:d3:5b:e9 brd ff:ff:ff:ff:ff:ff inet 192.168.0.2/24 brd 192.168.0.255 scope global eth0 inet6 fe80::a00:27ff:fed3:5be9/64 scope link valid_lft forever preferred_lft forever iMac-de-Jean-Baptiste-Langlois:~ mithweth$ curl 192.168.1.35 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 08:00:27:6c:73:0a brd ff:ff:ff:ff:ff:ff inet 192.168.0.3/24 brd 192.168.0.255 scope global eth0 inet6 fe80::a00:27ff:fe6c:730a/64 scope link valid_lft forever preferred_lft forever
On voit bien que, alors qu'on effectue le même appel, la valeur affichée est différente.
5. Haute disponibilité
A faire APRES conf du load balancer : En effet, l'idée est d'ajouter ou supprimer des enresgistrements à ipvsadm en fonction de l'état des serveurs, donc il faut qu'auparavant ipvsadm soit correctement configuré.
Pour installer MON, on peut très bien télécharger et recompiler les sources, mais j'ai trouvé des packages RPM de la dernière version (mon-1.2.0-8.el6.i686.rpm ou mon-1.2.0-8.el6.x86_64.rpm) que j'ai attaché à ce post. Toutefois, comme les RPMs semblent avoir été compilé avec les pieds, voici comment installer le RPM qui va bien sur votre RedHat de vos rêves ; Ne vous inquiétez pas, ça marche !! (Au moins avec ma CentOS 6.4 ).
yum -y install perl-CPAN make gcc pam-devel # Installe pkg de dev perl -MCPAN -e 'install "Time::HiRes"; install "Time::Period"; install "Convert::BER"; install "Authen::PAM"' rpm -ivh --nodeps mon-1.2.0-8.el6.x86_64.rpm # ne pas oublier le --nodeps yum -y remove make gcc pam-devel # desInstalle pkg de dev
Mon est désormais bien installé. Il ne reste plus qu'à configurer le fichier de configuration de Mon /etc/mon/mon.cf
. Copier ainsi le fichier ci-dessous, en changeant l'IP des ondes à la ligne hostgroup
cfbasedir = /etc/mon pidfile = /var/run/mon.pid statedir = /var/lib/mon/state.d logdir = /var/lib/mon/log.d dtlogfile = /var/lib/mon/log.d/downtime.log alertdir = /usr/lib64/mon/alert.d mondir = /usr/lib64/mon/mon.d maxprocs = 20 histlength = 100 randstart = 60s authtype = pam userfile = /etc/mon/userfile hostgroup servers 192.168.0.2 192.168.0.3 watch servers service http interval 5s monitor http.monitor period wd {Sun-Sat} upalert ha.alert alert ha.alert
En fait, la partie importante est situé dans watch <hostgroup_name>
. Ici, la configuration précise de faire le test d'état du port 80 toutes les 5 secondes du Dimanche à Samedi sur les serveurs du hostgroup et qu'en cas d'erreur lancer le script ha.alert
. En cas de rétablissement après une panne, il faudra relancer le script ha.alert
.
En fait, en cas de rétablissement d'un service, le script indiqué est toujours exécuté avec le paramètre -u
, ce qui permet de différencier les actions à effectuer dans un seul et même script.
ha.alertn'apparait toutefois pas dans le répertoire
/usr/lib64/mon/alert.d
pour la simple et bonne réponse que c'est un script que j'ai fait moi-même : si un des daemons générant une réponse sur le port 80 (Apache) le script désactive l'enregistrement de ipvsadm permettant le routage vers le mode concerné. Cette désactivation consiste à changer le poids de ce routage de 1 à 0 et vice versa en cas de rétablissement du daemon.
#!/bin/sh read SERVER WEIGHT=0 while getopts "s:g:h:t:l:u" opt; do case $opt in u) WEIGHT=1;; s) SERVICE=$OPTARG;; *) ;; esac done GW=`grep GATEWAY /etc/sysconfig/network | cut -d = -f 2` IFACE=`netstat -rn | grep $GW | awk '{print $NF;}'` DFTIP=`grep IPADDR /etc/sysconfig/network-scripts/ifcfg-$IFACE | cut -d = -f 2` logger -i -p local3.info -t mon "node $SERVER weight is now $WEIGHT" ipvsadm -e -t $DFTIP:$SERVICE -r $SERVER:$SERVICE -m -w $WEIGHT
Il faut donc copier le script ci-dessus, le nommer ha.alert
, lui donner les droits d'exécution et redémarrer mon.
chmod a+x /usr/lib64/mon/alert.d/ha.alert service mon restart
6. Réplication de MySQL
Comme indiqué plus haut, peu importe le serveur Apache avec lequel on communique, il faut que les données échangées avec la base de données soient les mêmes pour donner l'illusion qu'un unique serveur est à l'oeuvre. Pour cela, la réplication de Maitre à Maitre de MySQL va nous aider. Tout comme Apache, il faut que la configuration des nodes concernés soit strictement la même, ainsi la configuration suivante est à reporter sur chacun des nodes.
Node 1
Ajouter la ligne suivante dans /etc/sysconfig/iptables
-A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT
Ajouter les lignes suivantes dans le fichier /etc/my.cnf
(Configuration MySQL)
server-id=2 log-bin=mysql-bin
On redémarre alors iptables, mysqld et on se connecte au serveur MySQL où on va créer un utilisateur spécifiquement pour la réplication (changer le <mot de passe>
par le mot de passe de votre choix)
mysql> grant replication slave on *.* to 'replication'@'%' identified by '<mot de passe>'; mysql> change master to master_host='192.168.0.2', master_port=3306, master_user='replication', master_password='<mot de passe>'; mysql> slave start;
Node 2
Ajouter la ligne suivante dans /etc/sysconfig/iptables
-A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT
Ajouter les lignes suivantes dans le fichier /etc/my.cnf
(Configuration MySQL)
server-id=3 log-bin=mysql-bin
On redémarre alors iptables, mysqld et on se connecte au serveur MySQL où on va créer un utilisateur spécifiquement pour la réplication (changer le <mot de passe>
par le mot de passe de votre choix)
mysql> grant replication slave on *.* to 'replication'@'%' identified by '<mot de passe>'; mysql> change master to master_host='192.168.0.3', master_port=3306, master_user='replication', master_password='<mot de passe>'; mysql> slave start;
La réplication est enfin configurée ! Pour le vérifier il suffit de taper, dans la console MySQL, la commande suivante :
mysql> show slave status\G
Si, parmi les instructions retournés, les deux lignes suivantes apparaissent, c'est que la réplication est fonctionnelle.
Slave_IO_Running: Yes Slave_SQL_Running: Yes
- Kam · 15 octobre 2022, 03:38
-
I am regular reader, how are you everybody? This piece of writing posted at this website is
truly good. - {cartucho · 15 octobre 2022, 10:24
-
Me recomendaram este website e me informaram que o tema era
sempre conversado em alto nível. Acessei e pude perceber
exatamente isso . Muito bom pelo artigo!