Mise en place DRBD

De Sn4kY
Aller à : navigation, rechercher

DRBD est une sorte de RAID1 via Ethernet, une réplication de périphérique de stockage en mode block. Il travaille très bien avec LVM, et assure la synchronisation des block-devices entre deux serveurs du réseau (les nodes).

On considère ici que LVM est acquis, et que DRBD est installé sur les deux nodes (sur Debian Squeeze, un aptitude install drbd-utils vous installera la version 8.3, ainsi que le module kernel qui va bien.

Configuration initiale

Pour commencer, il nous faut créer un LV qui sera identique sur chaque node (le LV a répliquer)

[root@node1 ~]# lvcreate -L 1G -n testdrbd myvg-node1
[root@node2 ~]# lvcreate -L 1G -n testdrbd myvg-node2

Le fichier de configuration global de DRBD /etc/drbd.conf contient les généralités de DRBD.

Debian spirit, il contient en réalité deux includes : drbd.d/global_common.conf et drbd.d/*.res. Le premier contient la config globale, et l'autre include va servir a inclure les fichiers de resource (des volumes à synchroniser).

La configuration globale de DRBD étant satisfaisante sur Debian, nous n'allons pas la 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 degr-wfc-timeout outdated-wfc-timeout wait-after-sb;
       }
       disk {
               # on-io-error fencing use-bmbv no-disk-barrier no-disk-flushes
               # no-disk-drain no-md-flushes max-bio-bvecs
       }
       net {
               # 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 after al-extents use-rle cpu-mask verify-alg csums-alg
       }
}

Les options de la configuration sont très bien expliquées dans la documentation.

Nous allons surtout nous intéresser au fichier de resource, par exemple /etc/drbd.d/testdrbd.res

resource testdrbd {
       startup {
               degr-wfc-timeout 10;    # 10s
       }
       disk {
               on-io-error   detach;
       }
       net {
               timeout         60;
               connect-int     10;
               ping-int        10;
               ping-timeout    5;
               after-sb-0pri disconnect;
               after-sb-1pri disconnect;
               after-sb-2pri disconnect;
               rr-conflict disconnect;
       }
       syncer {
               rate 640M;
               verify-alg sha1;
       }
       on node1 {
               device          /dev/drbd0;
               disk            /dev/myvg-node1/testdrbd;
               address         192.168.0.1:7788;
               meta-disk       internal;
       }
       on node2 {
               device          /dev/drbd0;
               disk            /dev/myvg-node2/testdrbd;
               address         192.168.0.2:7788;
               meta-disk       internal;
       }
}

La configuration doit être identique sur les deux nodes.

Quelques explications tout de même :

common {
protocol C;
}

"protocol" indique la méthode qui sera utilisée pour effectuer la synchronisation des data. La méthode C est la plus sure, elle indique à DRBD que le status du block copié est OK lorsque la donnée est physiquement écrite sur les deux nodes.

resource testdrbd {
on nodeX {
  device /dev/drbd0;
  disk /dev/myvg-nodeX/testdrbd;
  meta-disk internal;
  address 192.168.0.2:7788;
}

"resource" défini le début de la description d'un volume spécifique (par opposition à la configuration globale). "disk" est le block device qui contient les données actuelles. "device" représentera le nom qu'utilisera DRBD. "meta-disk" spécifie où DRBD stoquera ses méta données. "internal" est un très bon choix pour les options automatiques. Il est possible de séparer les méta données, mais ceci est un peu "performance killer".

Le bloc "on" défini les paramètres spécifiques à chaque node. Attention, le paramètre doit absolument être le véritable nom du host du node. "address" spécifie l'adresse ainsi que le port à utiliser pour cette ressource. Pour partager plusieurs ressources entre les deux même nodes, il faut changer le port (ou l'IP...).

Mise en place

Initialisation des volumes

Il faut a présent initialiser les métadata des volumes

[root@node1 ~]# drbdadm create-md testdrbd
md_offset 54521856
al_offset 54489088
bm_offset 54484992
Found some data
 ==> This might destroy existing data! <==
Do you want to proceed?
[need to type 'yes' to confirm] yes
Writing meta data...
initializing activity log
NOT initialized bitmap
New drbd meta data block successfully created.
[root@node2 ~]# drbdadm create-md testdrbd
md_offset 54521856
al_offset 54489088
bm_offset 54484992
Found some data
 ==> This might destroy existing data! <==
Do you want to proceed?
[need to type 'yes' to confirm] yes
Writing meta data...
initializing activity log
NOT initialized bitmap
New drbd meta data block successfully created.

Une fois les métadata crées, on peut lancer le démon drbd, sur les deux nodes simultanément (dans le laps de temps du timeout)

[root@node1 ~]# /etc/init.d/drbd start
[root@node2 ~]# /etc/init.d/drbd start
Starting DRBD resources:    [ d0 s0 n0 ].

Le démon est démarré, on vérifie que les états de drbd :

# cat /proc/drbd
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:53208

Les volumes sont bien dans un état Connecté, UP, sont considérés comme secondaires, et inconsistants. C'est ce que nous attendons dans la mesure où il n'y a pas eu de données sur le volume.

Il faut a présent synchroniser la grappe. Cette opération ne doit être effectuée que sur un node (le master)

[root@node1 ~]# drbdsetup /dev/drbd0 primary --overwrite-data-of-peer

Si on regarde à ce moment l'état de /proc/drbd, on observe la synchronisation entre les deux nodes :

0: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r----
   ns:21680 nr:0 dw:0 dr:21992 al:0 bm:1 lo:0 pe:94 ua:40 ap:0 ep:1 wo:b oos:31900
       [========>...........] sync'ed: 46.2% (31900/53208)K
       finish: 0:00:02 speed: 10,652 (10,652) K/sec

Une fois la réplication terminée, on se retrouve avec un device prêt à être utilisé sur le node master :

[root@node1 ~]# cat /proc/drbd
0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----
   ns:77052 nr:204 dw:77256 dr:154710 al:62 bm:53 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0

et un device prêt a répliquer sur le node secondaire :

[root@node2 ~]# cat /proc/drbd
0: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r----
   ns:204 nr:77052 dw:77256 dr:272 al:9 bm:8 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0

Y'a plus qu'à !


n.b. : l'ordre affiché du status ro et ds corresponds à node local/node distant.
n.b.2 : le 0: corresponds au périphérique /dev/drbd0


sources

[1] [2] [3]