Cluster Debian avec DRBD et GFS2 – (Publié dans GNU/Linux France Magazine 135)

Posted by

glmf-135

Cluster Debian avec DRBD et GFS2

Julien Morot

DRBD (Distributed Replicated Block Device) est une solution de réplication de périphériques blocs via le réseau.
Un périphérique bloc peut être une partition, un périphérique LVM, RAID logiciel etc…
La réplication se fait en continu est peut être synchrone ou asynchrone.
Le module noyau est intégré désormais en standard au noyau depuis la version 2.6.33.
Jusqu’à la version 0.7, DRBD fonctionnait en mode actif/passif. Depuis la version 0.8, il est possible de mettre en place un système multi-maîtres
à condition que le système de fichiers le prenne en charge et c’est là que GFS2 entre en jeu.

1. Apéritif

Afin de mettre en oeuvre ce qui va suivre, j’ai préparé deux machines virtuelles sous KVM,
disons arnold et willy sous Debian GNU/Linux Squeeze. Bien qu’elle ne soit pas encore publiée,
elle est gelée et j’ai donc bon espoir qu’elle ne soit pas aussi retardée que la woody.
Surtout, la prise en charge de DRBD 0.8 et de GFS2 est à un stade bien plus avancé que la lenny.
Les deux machines virtuelles possèdent une patte dans le réseau LAN en 192.168.69.0/24 et une patte dans le réseau de stockage en 192.168.254.0/24.

2. DRBD

1.1 Installation

Depuis la Squeeze, le module noyau drbd est intégré en standard, il n’est donc plus nécessaire de passer par
module-assistant pour son installation. On installe juste le nécessaire sur les deux serveurs via un simple :

# aptitude install drbd8-utils

2.2 Deux noeuds primaires

Par défaut, DRBD n’active pas le mode multi-maîtres. Il faut donc lui spécifier le nécessaire dans
les options globales du fichier /etc/drbd.d/global_common.conf via les deux directives
become-primary-on both et allow-two-primaries.

global {
        usage-count yes;
}

common {
        protocol C;

        handlers {
		[...]
        }

        startup {
                degr-wfc-timeout 120;
                become-primary-on both;
        }

        disk {
        }

        net {
                allow-two-primaries;
                after-sb-0pri discard-zero-changes;
                after-sb-1pri discard-secondary;
                after-sb-2pri disconnect;
        }

        syncer {
                verify-alg md5;
                rate 1000M;
        }
}

Il faut donc indiquer qu’on autorise les deux noeuds à devenir des noeuds maîtres à la section net et ce, dès le démarrage du service (section startup).
Dans le bloc syncer, on définit le débit maximal du réseau de stockage et la fonction de hash qui s’assurera que les données sont correctement répliquées.
On peut utiliser à ce niveau tout algorithme de hash supporté par le noyau.

2.3 Paramétrage du stockage répliqué

Sur chacun des serveurs, on créé un fichier /etc/drbd.d/cluster.res
qui contiendra la configuration du stockage partagé. La configuration de DRBD doit être identique sur les deux serveurs,
par conséquent le plus simple reste de faire le paramétrage sur un serveur et de copier la configuration en scp.

resource r0 {
  protocol "C";
  on arnold {
    device    /dev/drbd0;
    disk      /dev/vda5;
    address   192.168.254.1:7789;
    meta-disk internal;
  }
  on willy {
    device    /dev/drbd0;
    disk      /dev/vda5;
    address   192.168.254.2:7789;
    meta-disk internal;
  }
}

Le fichier parle de lui-même pour la plupart des éléments de configuration.
On définit une ressource DRBD nommée r0, accessible via le périphérique /dev/drbd0.
Sur chaque serveur, on définit le périphérique bloc (de taille identique) qui sera répliqué au travers du réseau.
meta-disk indique que les méta-données seront stockées en fin de fichier. Un point plus important est la notion de protocole :

– protocol A considère les données écrites lorsque les données de réplication sont dans le buffer TCP;
– protocol B considère les données écrites lorsque les données de réplication sont dans le cache disque distant;
– protocol C considère les données écrites lorsque les données sont écrites sur les deux noeuds du cluster, c’est donc logiquement le plus fiable.

2.4 Alors, ça marche?

Tout d’abord, il faut créer la ressource drbd à partir de ce qui est spécifié dans les fichiers de configuration précédent.
Ceci est fait par le script d’init de drbd, mais il me semble plus intéressant de voir en détail les commandes lancées par ce script
lors de son premier lancement :

# modprobe drbd
# drbdadm create-md r0
Writing meta data...
initializing activity log
NOT initialized bitmap
New drbd meta data block successfully created.
success
# drbdadm attach r0
# drbdadm syncer r0
# drbdadm connect r0

Si tout s’est bien déroulé, on peut lancer la synchronisation initiale.
A partir de ce moment, les deux noeuds restent en secondaire tant que la synchronisation n’est pas lancée.
Celle-ci peut être lancée indifféremment du noeud et l’état d’avancement et de synchronisation est visible dans le fichier
/proc/drbd. Quand la synchronisation est terminée, on demande à chaque noeud de passer maître sur la ressource
chose qui n’est pas souhaitable tant que la synchronisation ne s’est pas terminée.

root@arnold~# drbdadm -- --overwrite-data-of-peer primary r0
root@willy~# cat /proc/drbd 
version: 8.3.7 (api:88/proto:86-91)
srcversion: EE47D8BF18AC166BE219757 
 0: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r----
    ns:95892 nr:0 dw:0 dr:104264 al:0 bm:5 lo:1 pe:249 ua:256 ap:0 ep:1 wo:b oos:4056636
	[>....................] sync'ed:  2.2% (4056636/4144572)K
	finish: 0:02:18 speed: 29,312 (29,312) K/sec


root@arnold:/etc# cat /proc/drbd 
version: 8.3.7 (api:88/proto:86-91)
srcversion: EE47D8BF18AC166BE219757 
 0: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r----
    ns:0 nr:4144628 dw:4144572 dr:144 al:0 bm:253 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0
root@arnold:/etc# drbdadm primary r0
root@arnold:/etc# cat /proc/drbd 
version: 8.3.7 (api:88/proto:86-91)
srcversion: EE47D8BF18AC166BE219757 
 0: cs:Connected ro:Primary/Primary ds:UpToDate/UpToDate C r----
    ns:0 nr:4144628 dw:4144572 dr:344 al:0 bm:253 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0

3. Au tour du système de fichiers

3.1 Un FS clusterisé

Pour utiliser un périphérique de type bloc en lecture/écriture sur plusieurs noeuds, il faut naturellement un système de fichiers
prenant en charge le multi-maîtres, ce que ne sont pas XFS et EXTn. De base, le noyau Linux prend en charge GFS de RedHat et OCFS2 d’Oracle.
Ils sont relativement proches en terme de fonctionnalités, le choix de GFS2 étant purement arbitraire.
GFS2 gère les verrous entre les noeuds via DLM, CLVM et CMAN. Commençons par installer les prérequis et corriger les bugs de packaging.

# aptitude install clvm cman gfs2-tools

Une fois les dépendances installées, il faut créer le répertoire
/var/run/lvm qui n’est pas créé à l’installation de clvm
puis modifier le fichier d’init /etc/init.d/clvm et modifier la ligne indiquant le chemin du binaire clvmd
en pointant vers DAEMON=/usr/sbin/clvmd.

3.2 Création du cluster

La création du cluster se fait via la commande ccs_tool.
La mise en place du cluster consiste à indiquer d’une part les noeuds qui le composent et d’autre part les « fence device ».
Un fence device est un agent permettant contrôllant un noeud. Cela peut être un powerswitch, une carte DRAC, iLO, ipmi, vmware, un opérateur humain etc…
ccs_tool se charge également de déployer les mises à jour du fichier de configuration du cluster
/etc/cluster/cluster.conf sur l’ensemble des noeuds en cas de modification ultérieure. Passons à la création du cluster.

# ccs_tool create ClusterDRBD
# ccs_tool addfence human manual

Le cluster est créé avec un opérateur humain pour redémarrer les machines. Il faut maintenant ajouter les noeuds au cluster
en indiquant leur numéro dans le cluster (option -n) et le fence device associé (-f).

# ccs_tool addnode arnold -n 1 -f human
# ccs_tool addnode willy -n 2 -f human

Une fois ceci fait, il faut déployer ce même fichier sur le second noeud
et paraméter le fichier d’initialisation du service cluster manager via le fichier /etc/default/cman
en prenant soin d’adapter le nom du serveur. Les paramètres de ce fichier sont clairement documentés dans le fichier d’init de cman.

CLUSTERNAME="ClusterDRBD"
NODENAME="arnold"
USE_CCS="yes"
FENCE_JOIN="no"
CMAN_QUORUM_TIMEOUT=0

Le cluster devrait démarrer sans hurler, ce que vous pouvez vérifier via la commande cman_tool nodes -a.

# /etc/init.d/cman start
Starting cluster: 
   Checking Network Manager... [  OK  ]
   Global setup... [  OK  ]
   Loading kernel modules... [  OK  ]
   Mounting configfs... [  OK  ]
   Starting cman... [  OK  ]
   Waiting for quorum... [  OK  ]
   Starting fenced... [  OK  ]
   Starting dlm_controld... [  OK  ]
   Starting gfs_controld... [  OK  ]
   Unfencing self... [  OK  ]
   Joining fence domain... [  OK  ]

3.3 Le périphérique LVM

Avant de créer un système de fichiers, GFS s’appuie sur un périphérique LVM.
La seule particularité étant que l’on s’appuie cette fois sur un LVM en cluster et donc il faut définir un verrou de ce type dans le fichier
/etc/lvm/lvm.conf comme ci-dessous. Une fois ceci fait, il faut redémarrer le service clvm.

locking_type = 3

Le reste est tout ce qu’il y a de plus classique avec du LVM, on créé la pile PV/VG/LV

# pvcreate /dev/drbd0
  Physical volume "/dev/drbd0" successfully created
# vgcreate Data /dev/drbd0
  Clustered volume group "Data" successfully created
# vgchange -ay
  0 logical volume(s) in volume group "Data" now active
# lvcreate -L 2G -n LVGFS2 Data
  Logical volume "LVGFS2" created

Pensez à exécuter également vgchange -ay sur le deuxième serveur à l’issue de ces commandes
afin qu’il relise également les superblocks des volumes LVM.

3.4 MKFS… Enfin!

Après cette longue suite d’étapes et cet empilement imposant de couches logicielles on arrive enfin à la partie utilisable du système.
Celle qui va nous permettre de stocker des données utilisateur.

# mkfs -t gfs2 -p lock_dlm -j 2 -t ClusterDRBD:FS01 /dev/Data/LVGFS2 
This will destroy any data on /dev/Data/LVGFS2.
It appears to contain: symbolic link to `../dm-0'

Are you sure you want to proceed? [y/n] y

Device:                    /dev/Data/LVGFS2
Blocksize:                 4096
Device Size                2,00 GB (524288 blocks)
Filesystem Size:           2,00 GB (524288 blocks)
Journals:                  2
Resource Groups:           8
Locking Protocol:          "lock_dlm"
Lock Table:                "ClusterDRBD:FS01"
UUID:                      71877675-BC3D-28C0-1F66-E9F68A5E8F5E

Le système de fichier peut désormais être monté soit manuellement soit via la fstab.
Les deux noeuds ont désormais un accès en lecture/écriture. Un bon moyen de tester cela est d’ouvrir un fichier depuis l’un des noeuds
et de s’assurer que ce même fichier est en lecture seule sur le deuxième noeud. Notez par contre que le démontage des systèmes de fichiers est un peu hasardeux
et j’ai donc tendance à modifier légèrement les scripts d’init de la partie GFS afin que les systèmes de fichiers GFS soient démontés avant l’arrêt des démons

4. Conclusion

DRBD 0.7 était simple à metter en place et administrer, cependant le fait qu’il soit limité à un seul noeud actif
impliquait que le deuxième serveur ne pouvait être utilisé pour répartir la charge.
La mise en place de GFS2 sur DRBD implique néanmoins une pile logicielle conséquente voire même effrayante mais qui couplée avec un répartiteur de charge de type IPVS,
offre de nouvelles possibilités.

Julien Morot

Sysadmin passionné par les logiciels libres depuis 1998.

 

One comment

Leave a Reply

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