Allgemeines
DRBD (Distributed Replicated Block Device) ist eine Software, die es ermöglicht ein blockbasierendes Gerät eines produktiven Systems auf ein anderes in Echtzeit über TCP/IP zu spiegeln. Schreibvorgänge gelten dabei erst als abgeschlossen, wenn das zweite System dem ersten meldet, dass der Schreibzugriff erfolgreich war.
DRBD stellt auf allen Komponenten eine Verbindung zwischen der eigentlichen lokalen Partition (zum Beispiel /dev/sdb1) und dem virtuellen Device /dev/drdbN her, welches aber nicht direkt angesprochen und nur auf dem aktiven System verwendet werden kann. Den Hosts wird dazu ein entsprechender Status, entweder primär oder sekundär, zugewiesen.
Bei einem Ausfall des produktiven Systems (primary), wird dieses als inaktiv markiert, so dass dem bis dahin sekundären Server, der Status primär zugewiesen werden kann. Das kann manuell aber auch mit Hilfe von Heartbeat automatisch erfolgen.
Punkt 1: Installation von DRBD 8.3.x unter Debian 7 (Wheezy)
Primary und Secondary:
1 |
apt-get install drbd8-utils |
Nun prüfen wir ob das Module drbd geladen wurde, dies sollte automatisch geschehen und ist Out-of-the-Box Reboot fest.
1 |
lsmod | grep drbd |
Punkt 2: Konfigurationsdateien /etc/drbd.conf erstellen
Primary und Secondary:
Zuerst leeren wir die Datei /etc/drbd.conf und fügen auf beiden Nodes den selben Inhalt ein.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
global { usage-count no; } common { syncer { rate 100M; } } resource r0 { protocol A; startup { wfc-timeout 15; degr-wfc-timeout 60; } net { cram-hmac-alg sha1; shared-secret "PASSWORD"; after-sb-0pri discard-older-primary; after-sb-1pri discard-secondary; after-sb-2pri disconnect; } on node1 { device /dev/drbd0; disk /dev/sdb1; address 10.0.0.101:7788; meta-disk internal; } on node2 { device /dev/drbd0; disk /dev/sdb1; address 10.0.0.102:7788; meta-disk internal; } } |
Achtung!
Der Node Name muss uname -n entsprechen !
Informationen zu den Variablen
usage-count – Daten werden an DRBD übermittelt und mitgezählt
rate – 100M entsprechen 1GBit/s
ressource – Die Ressource die mit z.B. drbdadm angesprochen werden kann
protocol – „A“ entspricht einer Asynchronen Replikation Primary/Secondary
- after-sb-0pri regelt das Verhalten, wenn beide Nodes den Status Secondary haben. In diesem Fall findet keine automatische Synchronisation statt
- after-sb-1pri regelt das Verhalten, wenn einer von den beiden Nodes Primary ist. Dieser Punkt ist für die Kombination von Heartbeat und DRBD wichtig, da DRBD hier dafür sorgt das ein Node Primary wird
- after-sb-2pri regelt das Verhalten, wenn beide Nodes Primary sind. Auch hier wird nichts gemacht und es wird getrenntIn den meisten Setups ist der Automatismus NICHT erwünscht und sollte NICHT in der Config stehen.
Punkt 3: DRBD Device vorbereiten
Primary und Secondary:
Nun muss das DRBD Device, für die Ressource r0, auf beiden Nodes initialisiert werden.
1 |
drbdadm create-md r0 |
Jetzt muss DRBD auf beiden Nodes gestartet werden.
1 |
/etc/init.d/drbd start |
Primary:
Jetzt könnt ihr die Primary Node bestimmen.
1 |
drbdadm -- --overwrite-data-of-peer primary r0 |
Die Ausgabe, ähnlich wie bei mdadm, von cat /proc/drbd dürfte wie folgt aussehen.
1 2 3 4 5 |
root@node1:~# cat /proc/drbd version: 8.3.7 (api:88/proto:86-91) srcversion: EE47D8BF18AC166BE219757 0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate A r---- ns:0 nr:0 dw:0 dr:200 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0 |
oder
1 2 3 4 5 6 7 |
cat /proc/drbd version: 8.3.7 (api:88/proto:86-91) srcversion: EE47D8BF18AC166BE219757 0: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent A r---- ns:1832516 nr:0 dw:0 dr:1833672 al:0 bm:111 lo:105 pe:216 ua:134 ap:0 ep:1 wo:b oos:2928350292 [>....................] sync'ed: 0.1% (2859716/2861496)M finish: 7:49:17 speed: 103,744 (86,932) K/sec |
Die folgende Zeile sagt euch ob die Node Primary und UpToDate ist.
1 |
0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate A r---- |
Nun kann ein Dateisystem erstellt und eingehangen werden.
1 2 |
mkfs.ext4 /dev/drbd0 mount /dev/drbd0 /storage |
Beispiel /etc/fstab Eintrag.
1 |
/dev/drbd0 /storage ext4 defaults 0 0 |
Achtung!
Nur auf der Primary Node ausführen! Die Secondary Node kann das Dateisystem nicht mounten, da es read-only ist.
Punkt 4: Status prüfen
Der DRBD Status kann ähnlich wie bei einem Raid1 (mdadm) über das „/proc“-Filesystem geprüft und auf beiden Hosts abgefragt werden. In der folgenden Ausgabe sieht man, das sowohl der Server auf dem die Abfrage abgesetzt wurde (primär), als auch auf dem sekundären System keine Probleme existieren und die Daten „UpToDate“ sind.
1 2 3 4 5 |
# cat /proc/drbd version: 8.3.12 (api:88/proto:86-96) GIT-hash: e2a8ef4656be026bbae540305fcb998a5991090f build by dag@Build64R6, 2011-11-20 10:57:03 0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----\- ns:604 nr:102928 dw:103532 dr:4879758 al:8 bm:12 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0 |
Hier ist eine laufende Synchronisation vom aktuellen Master (Primary) zum inkonsistenten Slave (Secondary) zu sehen.
1 2 3 4 5 6 7 |
# cat /proc/drbd version: 8.3.7 (api:88/proto:86-91) srcversion: EE47D8BF18AC166BE219757 0: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent A r---- ns:255936 nr:0 dw:0 dr:263272 al:0 bm:15 lo:1 pe:35 ua:223 ap:0 ep:1 wo:b oos:3937920 [>...................] sync'ed: 6.2% (3937920/4192768)K finish: 0:02:18 speed: 28,316 (28,316) K/sec |
In der nächsten Ausgabe ist zu erkennen, dass der Slave ausgefallen ist bzw. dieser nicht vom Master erreicht werden kann. Hier muss nur das sekundäre System wieder in Betrieb genommen und anschließend der Status erneut geprüft werden.
1 2 3 4 5 |
# cat /proc/drbd version: 8.3.7 (api:88/proto:86-91) srcversion: EE47D8BF18AC166BE219757 0: cs:WFConnection ro:Primary/Unknown ds:UpToDate/DUnknown A r---- ns:4192768 nr:0 dw:0 dr:4192968 al:0 bm:256 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0 |
Falls der Master ausfällt, könnte die Ansicht auf dem Slave wie folgt aussehen. Hier kann das sekundäre System auf „primär“ gesetzt werden, sobald sichergestellt ist, dass der Master wirklich nicht erreichbar ist.
1 2 3 4 5 |
# cat /proc/drbd version: 8.3.7 (api:88/proto:86-91) srcversion: EE47D8BF18AC166BE219757 0: cs:WFConnection ro:Secondary/Unknown ds:UpToDate/DUnknown A r---- ns:0 nr:4192768 dw:4192768 dr:0 al:0 bm:256 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0 |
In der folgenden Ausgabe sind beide Komponenten inkonsistent, was nur bei der Ersteinrichtung auftreten sollte. Hier ist es nur noch möglich den primären Host zu forcieren. Ein einfaches „drbdadm primary r0“ wird fehlschlagen.
1 2 3 4 5 6 7 8 9 |
# cat /proc/drbd version: 8.3.7 (api:88/proto:86-91) srcversion: EE47D8BF18AC166BE219757 0: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent A 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:4192768 # drbdadm primary drbd0 0: State change failed: (-2) Refusing to be Primary without at least one UpToDate disk Command 'drbdsetup 0 primary' terminated with exit code 17 |
Punkt 5: Failover – Primary <-> Secondary
Sollte die Primary Node ausfallen könnt Ihr die Secondary Node zum Primary machen und das DRBD Device mounten.
1 2 |
drbdadm primary r0 mount /dev/drbd0 /storage |
Die /proc/drbd Datei sollte dann wie folgt aussehen.
1 2 3 4 5 |
root@node2:~# cat /proc/drbd version: 8.3.7 (api:88/proto:86-91) srcversion: EE47D8BF18AC166BE219757 0: cs:WFConnection ro:Primary/Unknown ds:UpToDate/DUnknown A r---- ns:0 nr:0 dw:0 dr:400 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0 |
WFConnection = Waiting For Connection
Achtung!
Der alte Primary kann ohne Probleme nach dem Ausfall wieder gestartet werden, das INIT Script startet den DRBD Dienst automatisch und wird zum Secondary Node.
1 2 3 4 5 |
root@node1:~# cat /proc/drbd version: 8.3.7 (api:88/proto:86-91) srcversion: EE47D8BF18AC166BE219757 0: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate A 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:0 |
Punkt 6: Manueller Failover
Um einen manuellen Failover durchzuführen, sind folgende Schritte notwendig.
1. Stoppen des Netzwerks der Ressource, damit diese nicht mehr vom Slave aus erreichbar ist und Entfernen des Devices /dev/drbd0, damit kein Zugriff mehr darauf erfolgen kann.
1 2 |
master # drbdadm disconnect r0 master # drbdadm detach r0 |
Auch folgender Shortcut für diese beiden Befehle wäre möglich. Er ist auch zu empfehlen, wenn ein disconnect erfolgreich ist, ein detach aber nicht funktioniert.
1 |
master # drbdadm down r0 |
2. Setzen des Status „Primary“ auf dem Slave.
1 |
slave # drbdadm primary r0 |
Failover erzwingen, da Zugriff auf Master nicht mehr möglich ist:
Manchmal muss ein Failover erzwungen werden. Zum Beispiel kam es in der Vergangenheit bei einem Setup zu dem Problem, dass der Master bzw. primäre Server Out-Of-Memory war und der Zugriff nicht mehr funktionierte. Die Webserver konnten damit keine Seiteninhalte laden und auch „detached“ funktionierte nicht. Die Kommunikation zwischen den DRBD-Hosts war aber weiterhin vorhanden, so dass der Slave nicht mittels „drbdadm primary r0“ zum primären System gesetzt werden konnte. Hier könnte es helfen mittels IPTables den Zugriff vom defekten Master auf den Slave zu blockieren.
1 2 |
slave # iptables -I INPUT -p tcp --dport 7788 -j DROP slave # iptables -I OUTPUT -p tcp --dport 7788 -j DROP |
1 |
slave # drbdadm primary r0 |
Punkt 7: Split Brain
Recovery aus Split Brain:
Auf dem vormals Primary:
1 2 |
drbdadm secondary r0 drbdadm -- --discard-my-data connect r0 |
auf dem vormals Secondary (Split Brain Survivor)
1 |
drbdadm connect r0 |