Réplication de systèmes de fichiers avec DRBD

De wikiGite

Les configurations ont été faites sur 2 distributions, avec les metadatas en interne ou en externe, en primaire/esclave ou en en double primaire. Panacher ces configuration pour obtenir celle qu'on veut au final.

CentOS 5.5 BlueOnyx + primary/slave + meta-disk external

On réplique /home (/dev/mapper/VolGroup00-home). La difficulté réside dans le fait que /home est utilisé par plusieurs services (admserv, http, mysql...) ce qui posera des problèmes au boot.

Note : on va utiliser Postgresql. Mysql est déjà placé dans /home, il faut que Postgres le soit aussi, pour être répliqué.

Voir ici -> Déplacement des répertoires PostGreSQL dans /home

Installation

yum install drbd82 kmod-drbd82

DRBD demande soit un volume vierge, dans ce cas il crée ses meta data dedans et monte le volume pour la réplication (meta-disk internal), soit un volume à part, environ 32M pour 1T de partition répliquée (une partition, un volume LVM, un disque externe, un ramdisk même, ce qu'on veut) et dans ce cas on lui donne le chemin (meta-disk /chemin/vers/le/disque/metadata)

Avec LVM : reduire /home d'environ 100M, ajouter une nouveau LV pour les meta data : Gestion LVM.

"meta-disk internal" signifie qu'il utilisera une partie de la partition pour ses meta-data. Il ne doit donc pas y avoir de système de fichier sur la partition (il sera créé après).

Pour répliquer un volume existant, créer une partition à côté pour y mettre les meta-data. Référencer par exemple par "meta-disk /dev/VolGroup00/drbd[0]" pour un volume logique LVM (le [0] indique un index de metadata pour une première partition. On peut réutiliser le même volume en mettant un index [1] pour une seconde partition répliquée, et ainsi de suite).

Paramétrage

/etc/drbd.conf

global { usage-count no; }
resource home {
  protocol C;
  startup {
     wfc-timeout 0; # drbd init script will wait infinitely on resources.
     degr-wfc-timeout 120; # 2 minutes.
     become-primary-on server1.domain.net; # pour PRIMARY (server1)/SECONDARY (server2)
  }
  disk { on-io-error detach; } # or panic, ...
  net {
     cram-hmac-alg "sha1";
     shared-secret "Cent0Sru!3z"; # don't forget to choose a secret for auth !
     max-buffers 2048; #datablock buffers used before writing to disk.
     ko-count 4; # Peer is dead if this count is exceeded.
     #on-disconnect reconnect; # Peer disconnected, try to reconnect.
  }
  syncer {
    rate 10M;
    verify-alg "crc32c"; # Algorythm to tun "drbdadm verify"
  }
  on server1.domain.net {
    device /dev/drbd0;
    disk /dev/VolGroup00/home;
    address 192.168.1.6:7788;
    meta-disk /dev/VolGroup00/drbd[0];
  }
  on server2.domain.net {
    device /dev/drbd0;
    disk /dev/VolGroup00/home;
    address 192.168.1.7:7788;
    meta-disk /dev/VolGroup00/drbd[0];
  }
}

NOTE : Les noms de machines après les "on..." doivent correspondre à ce que retourne "uname -n".

Attention à bien utiliser les noms de devices indiqués par lvdisplay (pas ceux du fstab qui peuvent être des labels, ni ceux du "mount" qui peuvent être différents si LVM est utilisé).

Créer les metadata :

drbdadm create-md home (sur les 2 noeuds)

Démonter la partition si nécessaire. Si le serveur secondaire est prêt, lancer drbd

service drbd start

Il attend son alter ego, lancer drbd sur le second serveur.

Vérifier sur le "primaire" l'état de la partition :

# cat /proc/drbd
version: 8.2.6 (api:88/proto:86-88)
GIT-hash: 3e69822d3bb4920a8c1bfdf7d647169eba7d2eb4 build by buildsvn@c5-i386-build, 2008-10-03 11:42:32
 0: cs:Connected st:Primary/Secondary ds:Inconsistent/Inconsistent C r---
    ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 oos:87031808

Il est noté "Inconsistent". On force donc le primaire à se répliquer sur le secondaire ("all" peut être remplacé explicitement par le nom de la ressource à synchroniser)

# drbdadm -- --overwrite-data-of-peer primary all
# cat /proc/drbd
version: 8.2.6 (api:88/proto:86-88)
GIT-hash: 3e69822d3bb4920a8c1bfdf7d647169eba7d2eb4 build by buildsvn@c5-i386-build, 2008-10-03 11:42:32
 0: cs:SyncSource st:Primary/Secondary ds:UpToDate/Inconsistent C r---
    ns:31876 nr:0 dw:0 dr:32000 al:0 bm:1 lo:0 pe:7 ua:4 ap:0 oos:87000128
     [>....................] sync'ed:  0.1% (84961/84992)M
     finish: 2:15:56 speed: 10,560 (10,560) K/sec

Paramétrage du système

Dans /etc/fstab, remplacer les références à l'ancien volume (ex: /dev/VolGroup00/home) par /dev/drbd0.

IMPORTANT : mettre "0 0" à la fin de la ligne, sinon au reboot le système essaie de vérifier /dev/drbd0 (fsck) mais comme drbd n'est pas encore lancé à ce moment, le boot s'arrête en erreur :

/dev/drbd0 :
    The superblock could not be read...

Comme DRBD n'est pas prêt à la lecture de /etc/fstab, le volume drbd ne monte pas au boot. Il y aura des erreurs aux démarrage des services http, mysql... pendant le boot : tant pis (ou alors, il faut désactiver ces services au démarrage, par chkconfig, ce qui est plus propre).

Donc : mettre "noauto" sur la ligne du fstab concernant cette partition

/dev/drbd0              /home                   ext3    defaults,noauto,usrquota,grpquota        0 0

désactiver le démarrage auto des services (par chkconfig) et ajouter le montage de la partition et le démarrage des services à rc.local. Exemple :

chkconfig admserv off
chkconfig httpd off
chkconfig mysqld off
chkconfig postgresql off

et sur le secondaire on peut ajouter

chkconfig monit off # si monit rest installé
chkconfig sendmail off
chkconfig saslauthd off

et dans le rc.local du primaire ajouter :

mount /home
quotaon -a
service admserv start
service httpd start
service mysqld start
service postgresql start

Attribution des rôles

Une fois la synchronisation terminée, il faut décider si il fonctionne en primaire/primaire ou primaire/secondaire.

Dans le premier cas, sur les deux noeuds :

drbdadm primary all

ou dans le second cas, respectivement

drbdadm primary all

sur le premier noeud et

drbdadm secondary all

sur le second.

On peut voir l'état de la connexion par

drbdadm cstate all

ou

cat /proc/drbd

Maintenant, on peut monter la partition sur le primaire et travailler dessus.

NOTE : attention aux quotas si ils sont activés sur la partition, si elle a été réduite (pour les metadatas). Il faut monter d'abord la partition en RO (mount -o ro /home) et recalculer les quotas :

quotacheck -avug

Puis on remonte en RW, et relancer les quotas

quotaon -a

REBOOT

Attention au choix de la partition répliquée. Le volume /dev/drbd0 n'est pas montable au boot (le module drbd n'est pas chargé, et le script d'init n'arrive que tard dans la séquence de boot). Si ce volume est nécessaire au boot, le serveur ne peut donc pas redémarrer !

Voir aussi les considérations sur le paramétrage de /etc/fstab plus haut.

Si la partition de metadatas de drbd est à part, le message "drbd0: Barriers not supported on meta data device - disabling" peut apparaitre au boot : c'est un message informatif qui peut être ignoré.

SWITCH

Pour switcher le serveur secondaire en primaire, si le primaire est arrêté ou HS, appliquer la précédure ci-dessous.

Par contre si le primaire est encore en ligne, qu'on ne peut pas (ou veut pas) l'éteindre pour une raison ou une autre, il faut s'assurer que DRBD sur des deux serveurs est "déconnecté" si on veut passer le secondaire en primaire. Sur les deux serveurs, lancer :

drbdadm down all # "down" means "detach+disconnect"

Pour switcher, rur le secondaire prévoir un script à lancer pour le faire passer en primaire :

drbdadm disconnect all # pour être sûr
drbdadm primary all
mount /home # ou mount /dev/drbd0
# Pour BlueOnyx spécifiquement :
quotaon -a
service admserv start
service httpd start
service mysqld start
service postgresql start # si nécessaire

SWITCH BACK ou : le retour

Quand un slave est passé primaire, on ne peut pas simplement relancé l'autre serveur (après dépannage éventuel) et leur redonner leurs rôles. Si on essaie de repasser le slave en secondaire, on a en général :

"Split-Brain detected, dropping connection !"

qui signifie qu'il se considère primaire et refuse la connexion de l'autre serveur. Pour le re-déclarer secondaire, après lancement de drbd (et expiration du délai d'attente) il faut :

drbdadm secondary all
drbdadm -- --discard-my-data up all # "up" means "connect+attach"

A ce moment, la connexion est rétablie. Le primaire refait parfois une synchronisation complète (quoique beaucoup plus rapide que la synchro d'origine, il ne fait à priori qu'une vérification) vers le secondaire s'il détecte des différences de blocks.

On peut forcer la vérification par

drbdadm verify all

le "cat /proc/drbd" doit indiquer "cs:VerifyS" au lieu de "cs:Connected" en temps normal.

Si des blocks diffèrent, ils ne sont pas automatiquement synchronisés après un verify. Pour ça, il faut forcer la synchro par :

drbdadm disconnect all
drbdadm connect all

TODO

A faire : tester le mode primaire/primaire pour moins de temps de bascule (les services peuvent-ils être lancés sur le secondaire ?)

Debian 5 / Proxmox VE + primary/primary + meta-disk internal

apt-get install drbd8-utils

La configuration se fait en ajoutant des fichiers de configuration dans /etc/drbd.d. Elle contient déjà un fichier global_common.conf qui reprend les options globales. A modifier :

global {
   usage-count no;
   # minor-count dialog-refresh disable-ip-verification
}
common {
   protocol C;
       handlers {
          pri-on-incon-degr "/usr/lib/drbd/notify-pri-on-incon-degr.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b > /proc/sysrq-trigger ; reboot -f";
          pri-lost-after-sb "/usr/lib/drbd/notify-pri-lost-after-sb.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b > /proc/sysrq-trigger ; reboot -f";
          local-io-error "/usr/lib/drbd/notify-io-error.sh; /usr/lib/drbd/notify-emergency-shutdown.sh; echo o > /proc/sysrq-trigger ; halt -f";
          # fence-peer "/usr/lib/drbd/crm-fence-peer.sh";
          # split-brain "/usr/lib/drbd/notify-split-brain.sh root";
          # out-of-sync "/usr/lib/drbd/notify-out-of-sync.sh root";
          # before-resync-target "/usr/lib/drbd/snapshot-resync-target-lvm.sh -p 15 -- -c 16k";
          # after-resync-target /usr/lib/drbd/unsnapshot-resync-target-lvm.sh;
       }
       startup {
          wfc-timeout 0;
          degr-wfc-timeout 120;
          become-primary-on both; # POUR PRIMARY/PRIMARY
          # wfc-timeout degr-wfc-timeout outdated-wfc-timeout wait-after-sb;
       }
       disk {
          on-io-error detach;
          # on-io-error fencing use-bmbv no-disk-barrier no-disk-flushes
          # no-disk-drain no-md-flushes max-bio-bvecs   
       }
       net {
          cram-hmac-alg "sha1";
          shared-secret "ProxmoxVE!"; # don't forget to choose a secret for auth !
          max-buffers 2048; #datablock buffers used before writing to disk.
          ko-count 4; # Peer is dead if this count is exceeded.
          allow-two-primaries; # Uniquement pour PRIMARY/PRIMARY
          # snd‐buf-size rcvbuf-size timeout connect-int ping-int ping-timeout max-buffers
          # max-epoch-size ko-count allow-two-primaries cram-hmac-alg shared-secret
          # after-sb-0pri after-sb-1pri after-sb-2pri data-integrity-alg no-tcp-cork
       }
       syncer {
          rate 10M;
          verify-alg "crc32c";
          # rate after al-extents use-rle cpu-mask verify-alg csums-alg
       }
}

On ajoute /etc/drbd.d/data2.res

resource vz2 {
  on ysabell {
    device /dev/drbd0;
    disk /dev/pve/data2;
    address 192.168.1.110:7788;
    meta-disk internal;
  }
  on azrael {
    device /dev/drbd0;
    disk /dev/pve/data2;
    address 192.168.1.111:7788;
    meta-disk internal;
  }
}

Créer les metadatas :

drbdadm create-md data2

La partition ou le LV doit être vierge ! Sinon drbd refuse de créer ses metadata en "interne". Si un système de fichiers a été créé précédemment, annuler le formatage en écrasant les premiers secteurs :

dd if=/dev/zero of=/dev/pve/data2 bs=1024 count=10

Le premier démarrage doit renvoyer des erreurs de non synchronisation. L'état après démarrage est "Inconsistent" :

# /etc/init.d/drbd start
  0: State change failed: (-2) Refusing to be Primary without at least one UpToDate disk
  Command '/sbin/drbdsetup 0 primary' terminated with exit code 17

# cat /proc/drbd
 version: 8.3.7 (api:88/proto:86-91)
 srcversion: EE47D8BF18AC166BE219757 
  0: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r----
     ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:165669916

Sur UN SEUL DES NOEUDS, lancer :

drbdadm -- --overwrite-data-of-peer primary data2

Cette ligne de commande initialise ce noeud en primary avec un disque "UpToDate" (nécessaire une première fois pour dire qui est le primaire) même si le second noeud n'est pas encore en ligne (en préparation d'une future réplication, par exemple).

Il faut ensuite attendre la fin de la synchronisation. Vérifier l'état en continu avec :

# watch cat /proc/drbd
 version: 8.3.7 (api:88/proto:86-91)
 srcversion: EE47D8BF18AC166BE219757 
  0: cs:SyncSource ro:Primary/Primary ds:UpToDate/Inconsistent C r----
     ns:286416 nr:0 dw:0 dr:287072 al:0 bm:17 lo:0 pe:34 ua:0 ap:0 ep:1 wo:b oos:165384356
        [>....................] sync'ed:  0.2% (161508/161784)M
        finish: 4:25:02 speed: 10,384 (10,196) K/sec

A la fin de la synchronisation, arrêter drbd sur les 2 noeuds, puis le relancer.

On peut maintenant créer un système de fichier :

mkfs.ext4 /dev/drbd0

Puis le monter (avec mount /dev/drbd0), et l'enregistrer dans /etc/fstab pour montage automatique au démarrage (idem, en référençant le device "/dev/drbd0").