Stockage : réplication en temps réel avec DRBD

DRBD (Distributed Replicated Block Device) est une architecture de stockage distribuée pour GNU/Linux, pour parler rapidement on peut dire qu’il s’agit d’une sorte de RAID 1 au niveau du réseau. Cela permet d’avoir deux machines avec réplication de données de l’une vers l’autre, l’une étant désignée primaire et l’autre secondaire (mais il existe un mode primaire/primaire également). Il s’agit d’un logiciel libre développé par la société Linbit qui par ailleurs offre un service de support.

DRBD réplique au niveau des périphériques de bloc, pour plus d’informations sur son fonctionnement, je vous renvoie à la page Wikipedia de DRBD.

Pré-requis

Ce tutoriel est réalisé avec deux machines sous CentOS 6, celles-ci sont respectivement nommées centos-ha1 (IP : 192.168.1.10) et centos-ha2 (IP : 192.168.1.11), le terme de nœud sera utilisé pour les désigner.
SELinux est désactivé et le port 7789 ouvert au niveau du firewall.

DRBD fonctionnant au niveau bloc, il faut un disque ou une partition dédiée à cela. Dans l’exemple de ce billet, on part d’un groupe de volumes LVM nommé vg_storage avec un unique volume logique lv_storage qui est libre pour créer notre ressource DRBD. Un volume logique étant un périphérique de bloc aux yeux de Linux, cela convient parfaitement. Celui-ci n’a pas besoin (et ne doit pas) d’être formatté.

Installation

Depuis CentOS 6, les paquets DRBD ne sont plus dans les dépots de base, il faut donc ajouter ceux de atRPMS. Pour ce faire, ajouter le fichier atrpms.repo sous /etc/yum.repos.d contenant ceci :

[atrpms]
name=CentOS $releasever - $basearch - ATrpms
baseurl=http://dl.atrpms.net/el$releasever-$basearch/atrpms/stable
gpgkey=http://atrpms.net/RPM-GPG-KEY.atrpms
gpgcheck=1

Vérification de la présence de paquets relatifs à DRBD :

# yum search drbd
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: ftp.plusline.de
* extras: ftp.plusline.de
* updates: mirrors.prometeus.net
========================================= Matched: drbd =========================================
drbd.i686 : Distributed Replicated Block Device.
drbd-kmdl-2.6.32-131.0.15.el6.i686.i686 : Distributed Redundant Block Device.
drbd-kmdl-2.6.32-131.12.1.el6.i686.i686 : Distributed Redundant Block Device.
drbd-kmdl-2.6.32-131.2.1.el6.i686.i686 : Distributed Redundant Block Device.
drbd-kmdl-2.6.32-131.4.1.el6.i686.i686 : Distributed Redundant Block Device.
drbd-kmdl-2.6.32-131.6.1.el6.i686.i686 : Distributed Redundant Block Device.
drbd-kmdl-2.6.32-71.14.1.el6.i686.i686 : Distributed Redundant Block Device.
drbd-kmdl-2.6.32-71.18.1.el6.i686.i686 : Distributed Redundant Block Device.
drbd-kmdl-2.6.32-71.18.2.el6.i686.i686 : Distributed Redundant Block Device.
drbd-kmdl-2.6.32-71.24.1.el6.i686.i686 : Distributed Redundant Block Device.
drbd-kmdl-2.6.32-71.29.1.el6.centos.plus.i686.i686 : Distributed Redundant Block Device.
drbd-kmdl-2.6.32-71.29.1.el6.i686.i686 : Distributed Redundant Block Device.
drbd-kmdl-2.6.32-71.7.1.el6.i686.i686 : Distributed Redundant Block Device.

Nous pouvons installer le paquet drbd ainsi que le module du noyau correspondant au noyau en cours. Je vérifie quel noyau j’ai sur mon système :

# uname -r
2.6.32-71.29.1.el6.i686

J’installe le module correspondant :

# yum install drbd drbd-kmdl-2.6.32-71.29.1.el6.i686.i686

Il faut charger le nouveau module dans le noyau :

# modprobe drbd

Et bien sur on veut qu’il se charge au démarrage de la machine, on ajoute donc cette ligne au fichier /etc/rc.local.

Configuration

La configuration de DRBD se situe sous /etc/drbd.conf, mais pour plus de lisibilité, ce fichier fait appel à ceux situés sous /etc/drbd.d/, la configuration se fait donc d’une part dans global_common.conf pour la configuration commune et dans un fichier r0.res que nous allons créer pour notre nouvelle ressource. Ce nom r0 est arbitraire.
Donc pour commencer, vérifier que le fichier global_common.conf possède les options suivantes :

global {
  usage-count yes;
}
common {
  net {
    protocol C;
    verify-alg sha1;
    csums-alg sha1;
  }
}

L’option protocol C signifie que la réplication s’effectue de façon synchrone. Avec ce mode de fonctionnement synchrone, l’écriture de données n’est considérée terminée que lorsque le nœud secondaire a terminé d’écrire, validant ainsi l’opération. verify-alg sha1 vérifie l’intégrité des données bloc par bloc entre les nœuds. csums-alg sha1 active la synchronisation avec somme de contrôle (checksum). Comme expliqué dans la documentation, la synchronisation n’est pas la même chose que la réplication des périphériques. La seconde se fait en temps réel, c’est le fonctionnement normal de DRBD, alors que la première s’effectue lorsqu’il y a eu perte d’un des deux nœuds (pour quelque raison que ce soit) et une (re)synchronisation est nécessaire.

Il est temps de créer la vraie ressource dans un nouveau fichier r0.res contenant ces informations :

resource r0 {
	on mailsrv-ha1 {
    	address   192.168.1.10:7789;
    	device    /dev/drbd1;
		disk      /dev/mapper/vg_storage-lv_storage;
		meta-disk internal;
  	}
  	on mailsrv-ha2 {
    	address   192.168.1.11:7789;
    	device    /dev/drbd1;
		disk      /dev/mapper/vg_storage-lv_storage;
		meta-disk internal;
  	}
}

Petite explication sur la configuration de cette ressource qui dans son ensemble parle d’elle-même. On définit les deux nœuds avec le mot-clé on suivi du nom de l’hôte. On spécifie l’IP du nœud et le port utilisé – ici 7789. Le périphérique de bloc logique est définit par device suivi du chemin vers celui-ci. Ensuite il faut indiquer la partition de bas niveau sur laquelle le périphérique de bloc logique se posera grace au mot-clé disk suivi de son chemin. meta-disk internal indique que la zone réservée aux données de contrôle sera sur la même partition, toujours au niveau bloc (plus d’informations sur ce sujet sur la documentation officielle).

On voit que certaines options (presque toutes sauf l’IP) sont les mêmes, on peut donc simplifier notre fichier r0.res comme ceci :

resource r0 {
	device    /dev/drbd1;
    disk      /dev/mapper/vg_storage-lv_storage;
    meta-disk internal;
	on mailsrv-ha1 {
    	address   192.168.137.201:7789;
  	}
  	on mailsrv-ha2 {
    	address   192.168.137.203:7789;
  	}
}

Activation de la ressource

Voilà, tout est bien configuré, on peut activer la ressource. Je répète que le système de fichiers de bas niveau /dev/mapper/vg_storage-lv_storage doit être démonté et ne doit pas être formatté. Si tel est le cas, son contenu va de toutes façons être perdu.

On commence par créer les meta-données du périphérique :

# drbdadm create-md r0

Si des erreurs sont retournées, c’est que le système de fichiers existe, on le détruit donc :

# dd if=/dev/zero of=/dev/mapper/vg_storage-lv_storage bs=1M count=128

On relance la commande de création des meta-données. Tout devrait bien se passer, on peut activer la ressource :

# drbdadm up r0

Il faut faire de même sur l’autre nœud. Lorsque la deuxième machine est prête on initialise la première synchronisation par cette commande :

# drbdadm primary --force r0

Alors que se passe-t-il? Lorsque la ressource est activée, les deux nœuds sont marquées comme secondaires, une première synchronisation est nécessaire, on va donc forcer (avec l’option --force) cette opération sur le nœud que l’on veut primaire.

A ce stade, il est possible de vérifier l’état de DRBD par la commande :

# drbd-overview 
  1:r0/0  SyncSource Primary/Secondary UpToDate/Inconsistent C r----- 
	[>....................] sync'ed:  0.6% (53340/53652)M

On voit que la ressource est en cours de synchronisation, suivant la taille de la partition, cela peut être long. On a plus d’info avec :

# cat /proc/drbd 
version: 8.4.0 (api:1/proto:86-100)
GIT-hash: 28753f559ab51b549d16bcf487fe625d5919c49c build by gardner@, 2011-08-26 23:24:30

 1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r-----
    ns:1482108 nr:0 dw:0 dr:1487544 al:0 bm:90 lo:0 pe:2 ua:5 ap:0 ep:1 wo:b oos:53461324
	[>....................] sync'ed:  2.7% (52208/53652)M
	finish: 0:41:59 speed: 21,216 (22,100) K/sec

On voit que le processus de synchronisation est en cours (cs:SyncSource), que le nœud primaire est à jour mais le secondaire est encore dans un étant incohérent (ds:UpToDate/Inconsistent).
Il n’est pas nécessaire d’attendre la fin de la synchronisation pour créer le système de fichiers, donc allons-y, créons un système de fichiers ext4 et montons-le :

mkfs.ext4 -L storage /dev/drbd1
mkdir /mnt/storage
mount /dev/drbd1 /mnt/storage

Le système de fichiers est maintenant utilisable et va être répliqué en temps réel. On peut vérifier l’état de synchronisation :

# cat /proc/drbd 
version: 8.4.0 (api:1/proto:86-100)
GIT-hash: 28753f559ab51b549d16bcf487fe625d5919c49c build by gardner@, 2011-08-26 23:24:30

 1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
    ns:56499808 nr:36 dw:1557816 dr:54944894 al:422 bm:3354 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0

Voilà, c’est fini, notre resource est connectée (cs:Connected), on est sur le noeud primaire (ro:Primary/Secondary) et elle est à jour des deux cotés (ds:UpToDate/UpToDate). Avec drbd-overview on obtient plus d’informations, en particulier sur la taille du stockage :

# drbd-overview 
  1:r0/0  Connected Primary/Secondary UpToDate/UpToDate C r----- /mnt/storage ext4 52G 730M 49G 2%

Toute modification sur la ressource peut se faire en temps réel, après un changement, il faut copier le fichier de configuration sur le second nœud et opérer cette commande (sur les deux nœuds) :

# drbdadm adjust r0

Vérification en ligne automatique

Nous avons vu que l’option verify-alg permet de vérifier l’intégrité des données en ligne, pour faire ce test il suffit d’invoquer la commande :

# drbdadm verify r0

DRBD commence alors la vérification et s’il détecte des blocs non synchronisés, il les marque comme tel et l’inscrit dans le log du noyau. Il est bon d’automatiser cette tâche en l’ajoutant dans le cron. Pour ce faire, ajouter un fichier /etc/cron.d/drbd-verify avec – par exemple – ce contenu :

42 0 * * 0    root    /sbin/drbdadm verify r0

Par ailleurs, si des blocs non synchronisés ont été détectés, il faut les re-synchroniser comme ceci :

drbdadm disconnect r0
drbdadm connect r0

Restauration manuelle après un split-brain

Un split-brain se produit lorsque pour une raison quelconque les deux nœuds se retrouvent déconnectés, lorsque la connectivité revient, DRBD détecte que les 2 nœuds sont en mode primaire, DRBD rompt alors immédiatement la connexion de réplication par sécurité. Après le split-brain, un nœud passe en mode StandAlone et l’autre passe soit en mode secondaire ou en WFConnection. Il est temps d’intervenir.

Pour repartir sans corrompre les données – pour que le primaire sache qu’il est « maitre » – il faut aller sur le (futur) nœud secondaire et le déclarer comme tel, puis on connecte la ressource en lui disant d’oublier ses données :

drbdadm secondary r0
drbdadm connect --discard-my-data r0

On passe sur le primaire que l’on connecte et que l’on déclare primaire :

drbdadm connect r0
drbdadm primary r0

Notre ressource r0 est repartie.

Tester la réplication

Il est temps de tester un peu le fonctionnement de la réplication. Créons un fichier quelconque de 500Mo sous /mnt/storage :

# dd if=/dev/zero of=/mnt/storage/toto.dat bs=10M count=50
50+0 records in
50+0 records out
524288000 bytes (524 MB) copied, 31.4183 s, 16.7 MB/s
# ls -l /mnt/storage/
-rw-r--r--  1 root root 524288000 Sep 22 11:04 toto.dat

Celui-ci devrait maintenant exister également sur centos-ha2, pour le vérifier il faut suivre les étapes suivantes, sur le primaire : démonter le système de fichiers, le passer en secondaire, et sur le secondaire : le passer en primaire et monter le système de fichiers. Cela donne :

[centos-ha1 ~]# umount /mnt/storage
[centos-ha1 ~]# drbdadm secondary r0

[centos-ha2 ~]# drbdadm primary r0
[centos-ha2 ~]# mount /dev/drbd1 /mnt/storage
[centos-ha2 ~]# ls -l /mnt/storage
-rw-r--r--  1 root root 524288000 Sep 22 11:04 toto.dat

Tout est parfait, même si cela semble un peu long. Il ne faut pas oublier que le système de fichiers sur le nœud secondaire n’est pas accessible en l’état (il n’est d’ailleurs pas monté). Dans un environnement de production, la manipulation est un peu fastidieuse, c’est pourquoi il vaut mieux utiliser un CRM (Cluster Resource management) – comme Pacemaker – qui fera ce travail automatiquement. Ce sera l’objet d’un prochain article.

^.^


Ressources :

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *