Info16.fr

Le blog de B@rtounet

#Gnu/Linux

Mise en place d'un cluster haute disponibilité - Heartbeat - DRBD7

27 juillet 2011 Rédigé par bartounet

L'idée de se billet est de comprendre comment mettre en place un petit cluster de facon très simpliste. On part d'un cluster constitué de deux machines ou deux noeuds (node). Chaque machine va vérifier en permanence si l'autre répond toujours, elles vont en quelques sorte prendre le poul l'une et l'autre. Le but: si une machine crash pour une raison x, l'autre prend le relais de facon transparente. On accède au cluster par une adresse IP unique différentes des ip des nodes.

La surveillance des noeuds est rendue possible grace à heartbeat: il va se charger de surveiller les machines et d'appliquer une série de scripts définis par l'utilisateur si cela s'avère nécessaire.

Ne disposans de serveur à foisons, je suis parti de deux machines virtuelles hebergées sur un petit portable (pentium 4M 1.80GHz) sous Ubuntu dapper.

Node1:

<
Maître / Primaire Installation neuve de Ubuntu server 6.06.1 

IP : 192.168.1.1 Hostname : node1 Disque de 3Go

Node2

Esclave/secondaire Installation neuve de Ubuntu server 6.06.1 IP : 192.168.1.2 Hostname : node2 Disque de 3Go

Nous avons donc nos deux nodes, fraichement installés et prêts a recevoir notre petit test.

Installation de heartbeat.

sudo apt-get install heartbeat

La configuration de heartbeat repose sur 3 principaux fichiers situés dans /etc/ha.d

ha.cf haresources authkeys

sudo vi /etc/ha.d/ha.cf
bcast         eth0 debugfile     /var/log/ha-debug logfile       /var/log/ha-log logfacility   local0 keepalive     2 deadtime      10 warntime      6 initdead      60 udpport       694 node          node1 node          node2 auto_failback on

Pour l'explication des options reprenons le Wiki sur http://doc.ubuntu-fr.org/heartbeat

bcast : indique l'interface réseau par laquelle on va effectuer la prise de pouls.

debugfile : indique le fichier de déboguage à utiliser.

logfile: indique le log d'activité à utiliser.

logfacility : indique que l'on utilise la facilité syslog en plus.

keepalive : indique le délai entre deux battements de pouls. Ce délai est donné par défaut en seconde; pour utiliser les millisecondes, on ajoute le suffixe ms.

deadtime : indique le temps nécessaire avant de considérer un noeud comme étant mort. Ce temps est donné par défaut en seconde; pour utiliser les millisecondes, on ajoute le suffixe ms.

warntime : indique le délai avant d'envoyer un avertissement pour les pouls en retard. Ce délai est donné par défaut en seconde; pour utiliser les millisecondes, on ajoute le suffixe ms.

initdead : indique un deadtime spécifique pour les configurations où le réseau met un certain temps à démarrer. initdead est normalement deux fois plus grand que deadtime (au minimum). Ce délai est donné par défaut en seconde; pour utiliser les millisecondes, on ajoute le suffixe ms.

udpport : indique le port à utiliser pour la prise de pouls.

node : renseigne le nom des machines faisant partie du cluster. Ce nom doit être identique à celui retourné par la commande uname -n.

auto_failback : indique le comportement à adopter si le node maître revient dans le cluster. Si on met la valeur on, lorsque le node maître revient dans le cluster, tout est transféré sur ce dernier. Si on met la valeur off, les services continuent à tourner sur l'esclave même lorsque le maître revient dans le cluster.

Nous devons maintenant définir l'adresse IP du cluster. ceci se défini dans le fichier haresources

sudo vi /etc/ha.d/haresources
node1 IPaddr::192.168.1.10

Ici on définit donc que notre cluster utilisera l'ip 192.168.1.10 et surtout que se sera le node1 le master. (c'est sur ce noeud que vous tomberez toujours par défaut, si il n'est pas dead).

Le fichier authkeys permet aux nodes de cluster de s'identifier mutuellement.

 sudo vi /etc/ha.d/authkeys
auth 2 1 md5 "cluster node test" 2 crc

Une fois le fichier édité, n'oubliez pas de le protéger en introduisant la commande :

sudo chmod 600 /etc/ha.d/authkeys

Voila la configuration de heartbeat est terminée, j'ai juste oublié de préciser que ces 3 fichiers de configurations doivent etre rigoureusement identiques sur les deux noeuds. N'oubliez pas de lancer heartbeat sur les deux noeuds:

sudo /etc/init.d/heartbeat start

On peut passer aux tests... Plusieurs facon de tester... La première très simple: installer un serveur ssh sur chaque noeud et tenter de s'y connecter en coupant un noeud ou l'autre..

Exemple je veux me connecter au cluster:

je me connecte donc en ssh à l'ip 192.168.1.10 on voit que le prompt est:

root@node1:~#

je stop le node1 en désactivant eth0 par exemple. Et j'essaye de me reconnecter sur l'ip du cluster: 192.168.1.10 et là au miracle regardez le prompt:

root@node2:~#

On est passé directement sur le noeud 2 de facon transparente.

Je me suis amusé aussi en imaginant que l'on heberge un site en haute dispo. J'ai donc installé apache sur les 2 noeuds. et fait une petite page html affichant node1 quand on se connecte en http sur node1 et node2 quand on se connecte sur node2.

Imaginons je suis un simple surfer sur le net et je veux visiter le site http://192.168.1.10 Je ne le sais pas mais c'est un site en haute dispo et pour l'instant tous les noeuds fonctionnent correctement. Ma page s'affiche :

Entre temps y le node 1 se met à fumer et part en carafe. Moi en tant que simple internaute je ne le sait pas et je veux acceder à mon site préféré ;-) Je me connecte donc en à http://192.168.1.10 sans savoir que le serveur principal à fumé. Qu'est ce qui s'affiche sur mon navigateur ?

Je suis passé de manière transparente sur le node2. Bon là bien sur j'ai mis des pages différentes pour qu'on voit bien sur quel noeuds on est connecté, mais dans la réalité on aurait un site identique sur les deux noeuds et qui se réplique en temps réèl l'un sur l'autre, en utilisant des technologies comme drbd par exemple (Raid1 par IP).

Bon, dans la vrai vie c'est plus compliqué que ca, les gros sites en géneral utilise des systeme de HA et d'équilibrage de charge... Mais ce systeme est utilisé très souvent à un moment ou à un autre dans l'infrastructure.

Mise en place d'un serveur de fichier en HA avec Heartbeat et drbd.

Je reprend ce billet pour essayer d'aller plus loin. Maintenant qu'on à deux noeuds en cluster, j'ai décider de tenter de monter un serveur de fichier aussi en ha.

Je plante le décors:

Même configuration que tout à l'heure, j'ai toujours mes deux machines virtuelles en cluster, je veux utiliser ce cluster en tant que serveur de fichier Samba haute dispo.

Pour cela je vais utiliser drbd. Il sagit d'un module qui permet de faire du raid1 par l'ip. Autrement dit grace à lui toutes les données ecrite sur un disque du noeud 1 seront automatiquement répliqué sur le noeud2.

Si le serveur maitre (node1) "tombe", je veux que cela soit transparent pour l'utilisateur et que mon serveur de fichier soit toujours disponible, ce qui est techniquement possible puisque drbd aura copié les données du noeud 1 sur le noeud2 et heartbeat aura détecté la panne et tout basculer sur node2.

J'ai longtemps galéré pour monter cette petite plateforme mais elle fonctionne au bout du compte.

Premiere chose à faire:

drbd est une ressources associée à un périphérique mode bloc (partition)

J'ai donc ajouté une partition de 1Go pour chacune de mes VM

Petit rappel, pour cela j'ai ajouter un disque virtuel pour chaque machine virtuelle sous vmware (je vous passe les explications: clic clic sur l'interface graphique).

On relance les VM et on tappe

fdisk -l

pour visualiser nos disques On s'apercoit qu'un nouveau disque est apparu (encore heureux) /dev/hdb

Je vais creer une partition primaire qui fait la totalité du disque hdb toujours grace à fdisk:

Lancer l'interface de partitionnement fdisk en ligne de commande, en précisant le disque à modifier :

root@node1:~# fdisk -l Disk /dev/hda: 3221 MB, 3221225472 bytes 255 heads, 63 sectors/track, 391 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes    Device Boot      Start         End      Blocks   Id  System /dev/hda1   *           1         371     2980026   83  Linux /dev/hda2             372         391      160650    5  Extended /dev/hda5             372         391      160618+  82  Linux swap / Solaris Disk /dev/hdb: 1073 MB, 1073741824 bytes 16 heads, 63 sectors/track, 2080 cylinders Units = cylinders of 1008 * 512 = 516096 bytes Disk /dev/hdb doesn't contain a valid partition table

On créé alors la partion avec fdisk de la maniere suivante

root@node1:~# fdisk /dev/hdb Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel Building a new DOS disklabel. Changes will remain in memory only, until you decide to write them. After that, of course, the previous content won't be recoverable. The number of cylinders for this disk is set to 2080. There is nothing wrong with that, but this is larger than 1024, and could in certain setups cause problems with: 1) software that runs at boot time (e.g., old versions of LILO) 2) booting and partitioning software from other OSs    (e.g., DOS FDISK, OS/2 FDISK) Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite) Command (m for help): n Command action    e   extended    p   primary partition (1-4) p Partition number (1-4): 1 First cylinder (1-2080, default 1): Using default value 1 Last cylinder or +size or +sizeM or +sizeK (1-2080, default 2080): Using default value 2080 Command (m for help): w Calling ioctl() to re-read partition table. Syncing disks.

On peu vérifier avec fdisk -l qu'on à bien notre nouvelle partition de 1Go /dev/hdb1

root@node1:~# fdisk -l Disk /dev/hda: 3221 MB, 3221225472 bytes 255 heads, 63 sectors/track, 391 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes    Device Boot      Start         End      Blocks   Id  System /dev/hda1   *           1         371     2980026   83  Linux /dev/hda2             372         391      160650    5  Extended /dev/hda5             372         391      160618+  82  Linux swap / Solaris Disk /dev/hdb: 1073 MB, 1073741824 bytes 16 heads, 63 sectors/track, 2080 cylinders Units = cylinders of 1008 * 512 = 516096 bytes    Device Boot      Start         End      Blocks   Id  System /dev/hdb1               1        2080     1048288+  83  Linux

Maintenant qu'on à creer notre partition on va s'attaquer au gros du travail: installer drbd

Tout d'abord on commence par installer la version du kernel Headers et build essentiel ( tout ce fait tout seul et le chemin d'installation se trouve dans /usr/src)
#apt-get install linux-headers-$(uname -r) build-essential
Puis on installe DRBD source et utilitaire" attention la version des utilitaires doivent être de la même version que le noyau du module DRBD":Code:
#apt-get install drbd0.7-utils drbd0.7-module-source
On installe quelques paquets pour configurer le noyau et pouvoir appeler le module assistant du kernel pour installer le module DRBD
#apt-get install dpkg-dev kernel-package ncurses-dev
On se rend dans le répertoire source pour détarer les sources DRBD
#cd /usr/src #tar xfzv drbd0.7.tar.gz
Il est nécessaire d'installer le paquet contenant la version 3.4 de GCC
#apt-get install gcc-3.4
On se rend dans le dossier du kernel-headers
#cd /usr/src/linux-headers-2.6.17-2-686
et on lance le module-assistant pour intégrer le module DRBD dans le noyau courant:
#module-assistant

Une fois module-assistant lancé, allez dans SELECT, puis sélectionnez le module drbd0.7 et onTermine en faisant un BUILD puis un INSTALL.

Le module est prêt à être lancé. Utilisez la commande modprobe pour le charger
# modprobe drbd
Enfin, utilisez la commande lsmod pour verifier que le module est bien chargé
# lsmod | grep drbd
on doit voir
drbd        127412    1

DRBD étant installé, nous allons le configurer

Tout se passe dans le fichier:/etc/drbd.conf

Voici mon fichier drbd.conf à mettre sur les deux noeuds :

vi etc/drbd.conf
resource datas { protocol C; incon-degr-cmd "halt -f"; startup { wfc-timeout 240; degr-wfc-timeout 240;} disk { on-io-error panic; } syncer { rate 10M; group 1; al-extents 130; } on node1 { device /dev/drbd0; disk /dev/hdb1; address 192.168.1.1:7788; meta-disk internal; } on node2 { device /dev/drbd0; disk /dev/hdb1; address 192.168.1.2:7788; meta-disk internal;

Une ressources que j'appelle datas Je défini mes deux noeuds avec leur device virtuel /dev/drbd0 et leur device physique /dev/hdb1

dès à présent on peu redemmarer le daemon drbd et voir que les deux disques /dev/hdb1 sur node1 et /dev/hdb1 su node 2 se synchronisent. sur chaque noeud on lance drbd
 /etc/init.d/drbd start
On défini le node1 comme le noeud primaire pour drbd :
root@node1:~# drbdsetup /dev/drbd0 primary --do-what-I-say
On voit la synchro se dérouler
oot@node1:~# /etc/init.d/drbd status Unknown command 'sh-nop'. drbd driver loaded OK; device status: version: 0.7.15 (api:77/proto:74) SVN Revision: 2020 build by root@node1, 2007-08-21 17:16:52  0: cs:SyncTarget st:Secondary/Secondary ld:Inconsistent     ns:0 nr:111024 dw:111024 dr:0 al:0 bm:118 lo:728 pe:235 ua:728 ap:0         [==>.................] sync'ed: 12.1% (809104/917216)K         finish: 0:16:51 speed: 508 (2,700) K/sec 
On peut visualiser à tout moment l'état de drbd en faisant:
cat /proc/drbd
root@node1:~# cat /proc/drbd version: 0.7.15 (api:77/proto:74) SVN Revision: 2020 build by root@node1, 2007-08-21 17:16:52  0: cs:Connected st:Primary/Secondary ld:Consistent     ns:8 nr:0 dw:4 dr:21 al:0 bm:1 lo:0 pe:0 ua:0 ap:0
ici on voit bien que node 1 est le serveur primaire qu'il est synchronisé avec node2 qui est secondaire. et leur disque /dev/drbd0 est opérationnel.

On peut maintenant formater le device /dev/drbd0 Comme le tout est synchronisé, il suffit de le faire sur un seul noeud.

root@node1:~# mkfs.ext3 /dev/drbd0
On peut maintenant creer un dossier nommé drbd0 et monter le périphérique virtuel /dev/drbd0 sur ce dossier. Sur node1 ca donne:
root@node1:/# mkdir drbd0 root@node1:/# mount /dev/drbd0 /drbd0/ root@node1:/# ls bin   cdrom  drbd   etc   initrd      initrd.img.old  lost+found  mnt  proc  sbin  sys  usr  vmlinuz boot  dev    drbd0  home  initrd.img  lib             media       opt  root  srv   tmp  var  vmlinuz.old root@node1:/# cd /drbd0/ root@node1:/drbd0# ls lost+found
Pour vous prouver mes dires, je crée un dossier sur /drbd0/
root@node1:/drbd0# touch test1 root@node1:/drbd0# ls test1 root@node1:/drbd0# touch test2 root@node1:/drbd0# ls test1  test2
Bon à présent démontons /drbd0 sur le node 1 et montons le sur le node2
root@node1:/# umount /drbd0 root@node1:/# cd drbd0/ root@node1:/drbd0# ls
Maintenant sur le node2
root@node2:~# drbdsetup /dev/drbd0 primary --do-what-I-say
root@node2:~# mount /dev/drbd0 /drbd0 root@node2:~# cd /drbd0/ root@node2:/drbd0# ls test1  test2

Les fichiers qui ont été crées depuis le node1 ont bien été répliqué sur le node2 Notre DRBD fonctionne correctement.

Nous avons oublier de modifier une chose importante: le comportement de hearbeat envers DRBD si l'un des deux noeuds tombe: Pour cela nous allons modifier /etc/ha.d/haresources
root@node2:/# vi /etc/ha.d/haresources
 node1 drbddisk::datas Filesystem::/dev/drbd0::/drbd0::ext3 IPaddr::192.168.1.10

On dit donc à heartbeat:

Le node1 sera le maitre

Si un des noeuds tombe : remonter sur l'autre noeud la ressource DRBD nommée datas correspondant au périphérique /dev/drbd0 dans le dossier /drbd0

L'ip du cluster est 192.168.1.10

Résumons:

Dans l'état actuel, nous avons un cluster former de 2 noeuds: node1 et node2.

Grace à DRBD tout ce qui sera écris sur le périphérique virtuel /dev/drbd0 est répliquer en temps réèl sur chaque noeud, puisque /dev/drbd0 correspond au périphérique physique /dev/hdb1 de chaque noeud.

Grace à heartbeat si node1 tombe, toutes les ressources sont basculées sur node2. et plus particulièrement: /dev/drbd0 est remonté sur node2 dans /drbd0. Quand node1 reviens, il repasse master, /dev/drbd0 est démonté du node2 et remondé sur node1.

La preuve par l'exemple: J'ai eut l'idée d'un banal serveur de fichier sous samba: j'ai installé un serveur samba sur chaque node: je ne vous décrirai pas l'installation d'un serveur Samba, qui se retrouve sur moultes tuto: La seule chose interessante est la fin du fichier de conf de samba:
vi /etc/samba/smb.conf
 ...................................... [PARTAGE] path = /drbd0/ available = yes browseable = yes public = yes writable = yes

Et oui on s'en serait douté j'ai partagé directement /drbd0/ précisément ou /dev/drbd0 est monté.

Après avoir fait cette configuration sur les deux noeuds, j'ai tranquillment fait des test à partir d'un troisième poste sous windows Je me suis mis à la place d'un simple utilisateur windows qui veut accéder à ses fichiers sur un serveur de fichier. sans savoir qu'on a mis en place de la HA sur ce cluster.

je sais que mon serveur de fichier à l'ip 192.168.1.10 Donc je vais voir les partages sur cette IP

Mes fichiers sont là c'est cool !!! ;-)

l'utilisateur ne le sait pas, mais node1 brule:

Je vais simuler simplement en éteignant node1 :-)

On essaye d'acceder une seconde fois au cluster

En tant que simple utilisateur je retrouve mes fichiers identiques avant que node1 ne brule

Maintenant allons plus loin: Je créee un nouveau dossier dans les partages (nous sommes tjs sur node2 car node1 à fumé)

Entre temps le gentil technicien à réparé node1 et l'a relancé: Moi en tant qu'utilisateur je veux encore acceder au serveur de fichier Je vais donc sur le serveur de fichier (ip du cluster):

tout se passe bien mes fichiers sont là et même celui que j'ai crée avant l'incendie ;-) L'utilisateur s'en fiche, mais le node1 est remonté et est repassé en primaire, /dev/drbd0 à été remonté automatiquement sur ce noeud...

drbd à bien joué son role avant que node1 ne tombe, les fichiers on été répliqués en temps réèls sur node2

C'est transparent pour l'utilisateur !!!!

Ce qui interessant de constater c'est que quand je relance node1 aprè l'avoir réparé et sauver du feu tout rebascule sur lui

On peut d'ailleurs constaté en se connectant directement sur node1 par la console, qu'il est bien actif et que /dev/drbd0 à bien été remonté

root@node1:~# mount /dev/hda1 on / type ext3 (rw,errors=remount-ro) proc on /proc type proc (rw) /sys on /sys type sysfs (rw) varrun on /var/run type tmpfs (rw) varlock on /var/lock type tmpfs (rw) udev on /dev type tmpfs (rw) devpts on /dev/pts type devpts (rw,gid=5,mode=620) devshm on /dev/shm type tmpfs (rw) /dev/drbd0 on /drbd0 type ext3 (rw) root@node1:~# cd /drbd0/ root@node1:/drbd0# ls Nouveau Document Microsoft Word.doc  test1  test2 root@node1:/drbd0#

Nous avons donc bien réussi à mettre en place de la ha sur un cluster de deux noeuds, grace à heartbeat et drbd.

Cette solution n'est bien sur pas parfaite, puisque l'idéal serait de ne plus avoir de primary/secondary, mais du primary/primary

En effet je recherche en ce moment comment faire la meme chose mais en actif/actif, c'est à dire que les deux noeuds pourraient monter et écrire en même temps sur /dev/drbd0. J'imagine que c'est possible en utilisant des systeme de fichier cluster tels que lustre, ocfs2, gfs etc...

Alors si vous avez réussi à monter une telle architecture contactez moi ;-)

Information sur bartounet auteur de l'article

2 commentaires

#1 

merci beaucoup. c'est très intéressent :) Commentaire de Votre Nom

Répondre

#2 

super tuto et instructif merci Commentaire de Votre Nom

Répondre

Fil RSS des commentaires de cet article

Les commentaires sont fermés.