relecture

This commit is contained in:
gcolpart 2017-01-26 02:31:08 +01:00
parent e295e7d098
commit 47a3d86dab

View file

@ -46,7 +46,7 @@ Sur une installation DRBD on définit :
- 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`
La configuration des ressources DRBD est dans le répertoire `/etc/drbd.d/` par exemple `/etc/drbd.d/foo.res` définit le volume `/dev/drbd42`:
La configuration des ressources DRBD est dans le répertoire `/etc/drbd.d/` ; voici un exemple simple d'une ressource _foo_ avec un volume `/dev/drbd42` définie dans un fichier `/etc/drbd.d/foo.res` entre deux serveurs nommés _tic_ et _tac_ (cette exemple sera repris par la suite) :
~~~
resource "foo" {
@ -95,13 +95,13 @@ Pour lister la configuration et vérifier la syntaxe :
# drbdadm primary/secondary [ressource]
~~~
On peut également piloter un volume d'une ressource en indiquant la syntaxe _[ressource]/[n° de volume]_, par exemple:
On peut également piloter un volume d'une ressource en indiquant la syntaxe _[ressource]/[n° de volume]_, par exemple :
~~~
# drbdadm secondary foo/0
~~~
**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 :
**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 :
~~~
# drbdadm -d adjust all
@ -133,19 +133,19 @@ resource "foo" {
}
~~~
> *Note* : les hostnames et adresses IP doivent être correctes, DRBD vérifie qu'ils sont effectivement configurés en local !
> *Note* : les hostnames et adresses IP doivent être corrects car DRBD vérifie qu'ils sont effectivement configurés en local !
On vérifie la syntaxe :
On vérifie la syntaxe via :
~~~
# drbdadm dump foo
# resource foo on diez: not ignored, not stacked
# defined at /etc/drbd.d/foo.res:1
[…]
# resource foo on tic: not ignored, not stacked
# defined at /etc/drbd.d/foo.res:1
[…]
~~~
On initialise les _metadatas_ sur les volumes de la ressource (attention, cela écrit des données à la fin des _disk_) sur chaque serveur :
On initialise les _metadatas_ sur les disques (attention, cela écrit des données à la fin des _disk_) sur chaque serveur :
~~~
tic# drbdadm create-md foo
@ -190,7 +190,7 @@ Il reste à forcer la synchronisation d'un côté :
tic# drbdadm -- --overwrite-data-of-peer primary foo
~~~
Et observer la resynchronisation et l'état **UpToDate** de chaque côté :
Et observer cette première ynchronisation puis l'état **UpToDate** de chaque côté :
~~~
# drbd-overview
@ -207,13 +207,13 @@ Si l'on veut être en _Primary/Primary_ il faut avoir configuré `allow-two-prim
tac# drbdadm primary foo
# drbd-overview
42:foo/0 Connected Primary/Primary UpToDate/UpToDate
42:foo/0 Connected Primary/Primary UpToDate/UpToDate
~~~
### ressources avec plusieurs volumes
### ressource avec plusieurs volumes
On peut avoir plusieurs volumes pour une même ressource.
Cela simplifie la configuration (un seul fichier) et la gestion (drbdadm s'applique pour tous les volumes d'une même ressource).
Cela simplifie la configuration (un seul fichier, un seul port TCP) et la gestion (_drbdadm_ s'applique alors pour tous les volumes d'une même ressource).
Voici un exemple de fichier `/etc/drbd.d/foo.res` associé à un volume pour `/dev/drbd43` et un volume pour `/dev/drbd44` :
@ -241,9 +241,9 @@ resource "foo" {
}
~~~
> *Note* : attention, les _device minor_ doivent être différents (uniques sur tout un serveur)
> *Note* : attention, les _device minor_ doivent être différents pour chaque volume DRBD sur l'ensemble du serveur car ils vont correspondre à un périphérique unique `/dev/drbd<device minor>`
Les étapes sont similaires à une ressource avec un seul volume (voir ci-dessous pour détails). En résumé :
Les étapes sont ensuite similaires à une ressource avec un seul volume ([voir détails ci-dessus](#ressource-avec-un-seul-volume)). En résumé :
~~~
tic# drbdadm create-md foo
@ -253,17 +253,17 @@ tic# drbdadm adjust foo
tac# drbdadm adjust foo
tic# drbdadm -- --overwrite-data-of-peer primary foo
~~~
Si l'on veut être en _Primary/Primary_ :
~~~
tac# drbdadm primary foo
# drbd-overview
43:foo/0 Connected Primary/Primary UpToDate/UpToDate
44:foo/0 Connected Primary/Primary UpToDate/UpToDate
~~~
### ajouter un volume à une ressource existante
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.
Pour ajouter un nouveau volume à une ressource 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` :
@ -319,12 +319,6 @@ Et enfin, on force la synchronisation de ce nouveau volume `/dev/drbd45` :
tic# drbdsetup primary 45 --overwrite-data-of-peer
~~~
Si l'on veut être en _Primary/Primary_ :
~~~
tac# drbdsetup primary 45
~~~
## Configuration
@ -338,9 +332,9 @@ La configuration générale (directives _global_ et _common_) est dans le fichie
└── /etc/drbd.d/*.res
~~~
### Authentification
### authentification
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_):
Afin de sécuriser un peu les échanges DRBD entre deux serveurs, on peut configurer une authentification dans la section _net{}_ (que l'on peut mettre dans _common_ ou dans chaque directive _resource_):
~~~
net {
@ -349,7 +343,7 @@ net {
}
~~~
### Protocoles A/B/C et _allow-two-primaries_
### protocoles A/B/C et _allow-two-primaries_
DRBD dispose de 3 protocoles de réplication/synchronisation : A, B et C.
@ -374,16 +368,16 @@ net {
}
~~~
### Vitesse de re-synchronisation
### vitesse de re-synchronisation
<https://www.drbd.org/en/doc/users-guide-84/s-configure-sync-rate>
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;`.
La re-synchronisation est l'étape d'échange des données quand un volume n'est pas/plus en _UpToDate/UpToDate_ (par exemple à la création d'un nouveau volume). 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 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. Par exemple pour forcer à 200 Mo/s :
~~~
# drbdadm disk-options --c-plan-ahead=0 --resync-rate=500M <ressource>
# drbdadm disk-options --c-plan-ahead=0 --resync-rate=200M <ressource>
~~~
Pour reprendre les valeurs des fichiers de configuration :
@ -392,19 +386,18 @@ Pour reprendre les valeurs des fichiers de configuration :
# drbdadm adjust <ressource>
~~~
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_) :
Si l'on veut modifier ces paramètres de façon définitive, on utilisera la section _disk{}_ (que l'on peut mettre dans _common_ ou dans chaque directive _resource_) :
~~~
disk {
c-max-rate 300M;
resync-rate 40M;
resync-rate 200M;
}
~~~
## Administration
### Supprimer une ressource
### supprimer une ressource
On peut supprimer une ressource via `drbdadm down` (qui fait un _disconnect_ puis _detach_) :
@ -412,26 +405,26 @@ On peut supprimer une ressource via `drbdadm down` (qui fait un _disconnect_ pui
# drbdadm down <ressource>
~~~
On peut ensuite supprimer le fichier de conf associé et s'assurer que c'est pris en compte :
On peut ensuite supprimer le fichier de conf associé et s'assurer que c'est bien pris en compte :
~~~
# rm /etc/drbd.d/<ressource>.res
# drbdadm dump <ressource>
~~~
### Supprimer un volume d'une ressource
### supprimer un volume d'une ressource
Dans le fichier `/etc/drbd.d/foo.res` on supprime le volume `/dev/drbd45` :
Dans le fichier `/etc/drbd.d/foo.res` on supprime la section suivante correspondant au volume `/dev/drbd45` :
~~~
volume 2 {
device minor 45;
disk /dev/sdz3;
meta-disk internal;
}
volume 2 {
device minor 45;
disk /dev/sdz3;
meta-disk internal;
}
~~~
On utilise ensuite `drbdsetup` sur le `device minor` correspondant à notre volume :
On utilise ensuite `drbdsetup` sur chaque serveur avec le _device minor_ correspondant au volume volume à supprimer :
~~~
tic# drbdsetup secondary 45
@ -453,49 +446,58 @@ tic# drbdadm adjust foo
tac# drbdadm adjust foo
~~~
### Passer une ressource en primary/secondary
### passer une ressource en primary/secondary
Pour passer une ressource (ou toutes les ressources) en primary ou secondary :
Pour passer une ressource en primary ou secondary :
~~~
# drbdadm primary <ressource/all>
# drbdadm secondary <ressource/all>
# drbdadm primary <ressource>
# drbdadm secondary <ressource>
~~~
> *Note* : pour passer en _primary_ il faut s'assurer d'utiliser le protocole C et d'avoir configuré `allow-two-primaries;`
### Invalider une ressource
Pour passer toutes les ressources en primary ou secondary :
Sur le serveur à invalider, on provoque la réception immédiate des volumes via :
~~~
# drbdadm primary all
# drbdadm secondary all
~~~
### invalider une ressource
Si l'on considère qu'une ressource locale est _out-of-sync_ on va l'invalider, ce qui provoque une resynchronisation immédiate depuis le serveur distant :
~~~
# drbdadm invalidate <ressource>
~~~
> *Note* : on peut aussi utiliser `drbdadm invalidate-remote` depuis le serveur « maître »
> *Note* : on peut aussi utiliser `drbdadm invalidate-remote` pour invalider une ressource sur le serveur distant
### Déconnecter/connecter une ressource
### déconnecter/connecter une ressource
Pour des raisons de maintenance, on peut déconnecter une ressource (ou toutes les ressources) :
Pour des raisons de maintenance, on peut déconnecter une ressource. Attention, il faudra alors éviter un [split-brain](#récupérer-dun-split-brain) (notamment ne pas écrire sur les deux serveurs) :
~~~
# drbdadm disconnect <ressource/all>
# drbdadm connect <ressource/all>
# drbdadm disconnect <ressource>
# drbdadm connect <ressource>
~~~
> *Note* : pour toutes les ressources on pourra utiliser _drbdadm disconnect all_
### DRBD et systemd
Bien qu'il n'y ait pas de démon pour DRBD, il y a une unité [systemd](HowtoSystemd), mais **son utilisation est déconseillée** :
* `systemctl reload drbd` fait un `drbdadm adjust all` : autant utiliser la commande soi-même (en la testant en dry-run avant)
* `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`
* `systemctl reload drbd` fait un _drbdadm adjust all_ : autant utiliser la commande soi-même (en la testant en dry-run avant)
* `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 down all_
### DRBD et les filesystem
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 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_
@ -503,18 +505,18 @@ DRBD réalise une réplication au niveau bloc, il ne tient donc absolument pas c
<https://www.drbd.org/en/doc/users-guide-84/p-learn>
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.
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épliquer sur un périphérique distant via un lien réseau.
<img src="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.
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é (option `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
* Un _quick-sync bitmap_ qui est une sorte de hash du volume DRBD pour optimiser la re-synchronisation
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 :
@ -547,36 +549,43 @@ Il est important de bien comprendre les 3 protocoles de réplication/synchronisa
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.
B : Réplication synchronisée 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.
C : Réplication synchronisée 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.
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
### Bien comprendre /proc/drbd
* `cs` : Connection State (Connected/WFConnection/Unconnected/StandAlone/PausedSync)
* `ro` : Resources roles (Primary/Secondary/Unknow)
* `ds` : Disk States (UpToDate/Inconsistent/DUnknown)
* `A/B/C` : Protocol
<http://www.drbd.org/en/doc/users-guide-84/ch-admin#s-proc-drbd>
* `cs` : [Connection State](http://www.drbd.org/en/doc/users-guide-84/ch-admin#s-connection-states) (Connected/WFConnection/Unconnected/StandAlone/PausedSync/etc.)
* `ro` : [Resources roles](http://www.drbd.org/en/doc/users-guide-84/ch-admin#s-roles) (Primary/Secondary/Unknow)
* `ds` : [Disk States](http://www.drbd.org/en/doc/users-guide-84/ch-admin#s-disk-states) (UpToDate/Inconsistent/DUnknown/etc.)
* `A/B/C` : Replication Protocol
* `r-----` : [I/O Flags](http://www.drbd.org/en/doc/users-guide-84/ch-admin#s-io-flags) [r/s][-/a][-/p][-/u][-/d/b/n/a][-/s]
* `ns nr dw dr al bm log pe ua ap ep wo oos` : [Performance indicators](http://www.drbd.org/en/doc/users-guide-84/ch-admin#s-performance-indicators) notamment ns/nr (network send/receive), dw/dr (disk write/read), oos (out of sync)
Exemples :
~~~
42: cs:WFConnection ro:Primary/Unknown ds:UpToDate/DUnknown C r-----
~~~
Le nœud attend une reconnexion avec le second nœud pour lui renvoyer les données (resynchronisation).
Le nœud attend une reconnexion avec le second serveur pour lui renvoyer les données (re-synchronisation).
~~~
42: cs:StandAlone ro:Primary/Unknown ds:UpToDate/DUnknown r-----
~~~
Il s'agit d'un split-brain, le nœud est en standalone, et n'est plus synchronisé avec le second nœud.
Il s'agit d'un split-brain, le nœud est en standalone, et n'est plus synchronisé avec le second serveur.
~~~
42: cs:Connected ro:Primary/Primary ds:UpToDate/UpToDate C r-----
~~~
Les nœuds sont bien synchronisés.
Les serveurs sont bien synchronisés.
~~~
42: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r-----
@ -584,9 +593,7 @@ Les nœuds sont bien synchronisés.
[>…] sync'ed: 7.3% (7596/8188)Mfinish: 0:04:29 speed: 28,800 (28,964) K/sec
~~~
Une synchronisation est en cours vers le serveur secondaire.
TODO : expliquer ns/nr/dw/al/bm/log/pe/ua/ap/ep/wo/oos
Une re-synchronisation est en cours vers le second serveur.
## Optimisation
@ -656,7 +663,7 @@ user root
### Nagios
On peut surveiller l'état des synchronisations DRBD via Nagios via <https://exchange.nagios.org/directory/Plugins/Operating-Systems/Linux/check_drbd/details>
On peut surveiller l'état des volumes DRBD via Nagios via <https://exchange.nagios.org/directory/Plugins/Operating-Systems/Linux/check_drbd/details>
~~~
/usr/local/lib/nagios/plugins/check_drbd -d All -c StandAlone
@ -718,7 +725,7 @@ Une ressource DRBD doit être définie entre deux serveurs, mais rien n'enpêche
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
### É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 ?