[DRBD](http://www.drbd.org) (Distributed Replicated Block Device) est un outil libre pour répliquer des blocs (disques, partitions, volumes LVM…) entre deux serveurs Linux via une connexion réseau. On peut voir cela comme un « RAID1 over TCP/IP ». Nous l'utilisons principalement comme stockage pour de la virtualisation avec [KVM](HowtoKVM), cela permet notamment de réaliser des migrations à chaud de machines virtuelles entre deux hyperviseurs sans dépendre d'un équipement externe de type _SAN_.
- des **ressources** : chaque ressource DRBD a plusieurs paramètres, notamment le second serveur vers qui envoyer/recevoir la réplication
- des **volumes** : chaque ressource DRBD peut avoir un ou plusieurs volumes, chaque volume est accessible via un périphérique unique nommé `/dev/drbdXX`
**drbdadm** pilote principalement les commandes bas niveau `drbdsetup` et `drbdmeta` : son mode _dry-run_ est très utile car il va lister les commandes bas niveau effectuées (sans les appliquer). Par exemple pour voir tous les changements de configuration non appliqués :
Pour ajouter un volume à une ressource existante avec des volumes déjà en production, on utilisera directement les commandes bas niveau `drbdsetup` et `drbdmeta` pour ne pas perturber les autres volumes.
Voici l'exemple du fichier `/etc/drbd.d/foo.res` ci-dessus avec l'ajout d'un 3ème volume `/dev/drbd45` :
La configuration générale (directives _global_ et _common_) est dans le fichier `/etc/drbd.d/global_common.conf` (inclus par `/etc/drbd.conf`), les ressources sont dans des fichiers `/etc/drbd.d/*.res` (directives _resource_).
Afin de sécuriser un peu les échanges DRBD entre deux serveur, on peut configurer une authentification dans la section _net{}_ (que l'on peut mettre dans _common_ ou dans chaque directive _resource_):
Par défaut, la vitesse de re-synchronisation est dynamique et limitée à 100Mo/s (soit 800Mb/s). Ceci est valable depuis DRBD 8.4 [même si la documentation principale n'est pas tout à fait à jour](https://www.drbd.org/en/doc/users-guide-84/re-drbdconf). [Les paramètres par défaut sont](https://www.drbd.org/en/doc/users-guide-84/s-recent-changes-defaults#s-recent-changes-defaults-variable-rate-sync) `c-plan-ahead 20; c-fill-target 50k; c-min-rate 250k; c-max-rate 100M;`.
Si besoin, on peut fixer temporairement cette vitesse (pour la limiter ou pour l'augmenter) en définissant en Mo/s sur le serveur qui reçoit les données :
Si l'on veut modifier des paramètres de façon définitive, on utilisera la section _disk{}_ (que l'on peut mettre dans _common_ ou dans chaque directive _resource_) :
*`systemctl start drbd` fait tout d'abord un `drbdadm adjust-with-progress all` : si vous n'avez aucune ressource DRBD, cela échoue avec _no resources defined!_ ; il fait ensuite `drbdadm wait-connect all` qui sera bloqué infiniment si vos serveurs secondaires ne sont pas encore opérationnels ; enfin, il tente de passer les ressources en _Primary_ ce qu'il est plus prudent de faire manuellement
*`systemctl stop drbd` est dangereux, il stoppe toutes les ressources en faisant `drbdadm stop all`
DRBD réalise une réplication au niveau bloc, il ne tient donc absolument pas compte du filesystem :
* si l'on utilise un filesystem classique (ext4, brtfs etc.) il faut faire attention à ne jamais monter le filesystem à deux endroits à la fois
* si l'on veut lire/écrire les données d'une ressource DRBD depuis les deux serveurs, il faut utiliser un filesystem réseau comme [OCFS2](HowtoOCFS2) ou _GFS2_
DRBD est un _block device_ qui se met en _proxy_ devant un périphérique de stockage pour intercepter les requêtes en écriture et les réplique sur un périphérique distant via un lien réseau.
<imgsrc="https://www.drbd.org/ug/users-guide-8.4/drbd-in-kernel.png"alt="Architecture de DRBD"/>
DRBD a besoin de [metadatas](https://www.drbd.org/en/doc/users-guide-84/ch-internals#s-metadata) : il les écrit en général **à la fin** du disque concerné (`meta-disk internal`)… la taille du _block device_ final est donc un peu plus petite que le disque concerné. Il peut aussi gérer ses _metadatas_ à un autre emplacement, ce qui peut notamment servir à utiliser DRBD avec un disque sans le modifier.
Les metadatas DRBD contiennent :
* la taille du volume DRBD
* des _Generation Identifiers (GI)_
* un _Activity Log (AL)_ qui liste les blocs récemment écrits au cas où
* Un _quick-sync bitmap_ qui est une sorte de hash du volume DRBD pour optimiser la resynchronisation
Les [Generation Identifiers (GI)](https://www.drbd.org/en/doc/users-guide-84/s-gi) identifient le statut d'un volume DRBD. Concrètement il s'agit de plusieurs UUID auxquels on peut accéder via :
A : Réplication asynchrone. Les écritures sur le disque local du nœud primaire sont considérées complètes dès que le disque local a fini. Les paquets de réplication sont placés dans le buffer TCP.
B : Réplication synchronisé en mémoire. Les écritures sur le disque local du nœud primaire sont considérées complètes dès que le disque local a fini **et** que les paquets de réplication sont reçus sur le second nœud.
C : Réplication synchronisé sur les disques. Les écritures sur le disque local du nœud primaire sont considérées complètes dès que le disque local a fini **et** sur le disque distant aussi.
Le protocole C est donc le plus sécurisé mais ayant le plus d'impact sur les performances, le protocole A a les meilleures performances (comparables aux performances des disques locaux… si les buffers de réplication ne sont pas saturés) et le protocole B est un compromis entre les deux : il n'est ni sécurisé ni performant.
DRBD s'assure que les données sont écrites, et notamment que les données sont effectivement écrites sur le disque. Si l'on veut davantage de performance, on peut désactiver ces actions. On conseille notamment de le faire si l'on utilise une carte RAID hardware équipée d'une batterie :
On peut aussi envisager de modifier le _scheduler_ des disques concernés par DRBD de _cfq_ à **_deadline_** et modifier certaines valeurs _iosched/\*_.
Le protocole C utilisé par défaut est le plus sécurisé, mais il implique qu'une donnée est considérée comme écrite si elle l'a été également sur le second serveur. Pour éviter cela on peut utiliser le protocole A ou B tout en gardant en tête que c'est risqué. Le plus performant (et le plus risqué) est `protocol A;`
On peut surveiller l'état des synchronisations DRBD via Nagios via <https://exchange.nagios.org/directory/Plugins/Operating-Systems/Linux/check_drbd/details>
Un _split-brain_ signifie que des écritures ont été réalisées sur deux volumes primaires et desynchronisés, le seul moyen est de choisir manuellement un volume à réinitialiser !
Sur le serveur en _Standalone_ qu'on veut réinitialiser :
Si l'on veut répliquer une ressource avec un troisième serveur, [une solution est d'empiler deux réplications DRBD](https://www.drbd.org/en/doc/users-guide-84/s-three-way-repl)
### états différents pour les volumes d'une ressource
Les volumes d'une même ressource sont-ils forcément dans le même état primary/secondary ?
Contrairement à ce que l'on pourrait penser, on peut très bien ajuster des volumes d'une même ressource dans des états différents :
On peut migrer les données d'un disque existant en créant un volume DRBD avec des _metadatas_ stockées en externe. Par exemple, [Gitlab a migré 9To de données en quelques jours](https://about.gitlab.com/2015/03/09/moving-all-your-data/).
Voici la configuration d'un volume avec les _metadatas_ en externe :
~~~
volume 0 {
device minor 42;
disk /dev/sdz1;
meta-disk /dev/sdx1;
}
~~~
> *Note* : _meta-disk_ doit indiquer un périphérique [d'une taille suffisante](https://www.drbd.org/en/doc/users-guide-84/ch-internals#s-meta-data-size), on peut utiliser /dev/loop*
Comme pour la [création d'une ressource avec un seul volume](#ressource-avec-un-seul-volume) on ajoute la configuration sur chaque serveur, puis :
~~~
tic# drbdadm create-md foo
tac# drbdadm create-md foo
tic# drbdadm adjust foo
tac# drbdadm adjust foo
~~~
Sur le serveur avec le disque existant, il faut remonter le périphérique via `/dev/drbd42` (cela prend quelques secondes) :
Plus fort que l'[IPoAC](https://fr.wikipedia.org/wiki/IP_over_Avian_Carriers), DRBD décrit la [réplication truck-based](https://www.drbd.org/en/doc/users-guide-84/s-truck-based-replication)