SoftRAID1

Autor/Kontakt

Autor: Sascha Singert
E-Mail:

Art der Lösung

Anleitung zum Lernen (Tutorial)

Inhaltsverzeichnis

Vorwort

Mit diesem Tutorial wird beschrieben, wie bei einem laufenden Debian Etch und Lenny aus der einzelnen System-Platte ein Software-RAID1 (gespiegelt) erzeugt wird. Es wird dringend empfohlen, die einzelnen Schritte in einer virtuellen Maschine zu testen/üben, bevor an Produktivmaschinen Änderungen vorgenommen werden. Des Weiteren wird auch gezeigt, wie der GRUB Bootloader so weit konfiguriert wird, dass das System immer sauber hochfährt, egal ob eine der beiden Platten ausfällt oder das System einen Reboot benötigt. Von folgenden Dingen wird ausgegangen:
  • /dev/sda ist die Festplatte, auf der sich das aktuelle System befindet
  • /dev/sdb ist die zweite (neue) Festplatte, mit mindestens der gleichen Speicherkapazität wie /dev/sda
  • GRUB wird als Bootloader genutzt
  • root-Rechte sind vorhanden (zumindest für die benötigten Operationen)
Diese Anleitung wird ohne jede Garantie oder Gewährleistung zur Verfügung gestellt. Schadensersatzansprüche (oder sonstige andere juristische Späße) sind nichtig. – Nutzung auf eigene Gefahr!

Schritt 1: Vorbereitung

Der Einfachheit wegen werden nur zwei Partitionen in diesem Tutorial explizit genutzt. debian4spielwiese:~# fdisk -l /dev/sda Disk /dev/sda: 2147 MB, 2147483648 bytes 255 heads, 63 sectors/track, 261 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/sda1 * 1 242 1943833+ 83 Linux /dev/sda2 243 261 152617+ 82 Linux swap / Solaris Der folgende Befehl wird zwar empfohlen, ist aber unter Umständen nicht benötigt. Der Inhalt der zweiten Platte wird mit Nullen überschrieben. debian4spielwiese:~# dd if=/dev/zero of=/dev/sdb dd: Schreiben in /dev/sdb: Auf dem Gerät ist kein Speicherplatz mehr verfügbar 4194305+0 Datensätze ein 4194304+0 Datensätze aus 2147483648 Bytes (2,1 GB) kopiert, 67,7415 Sekunden, 31,7 MB/s

Schritt 2: Software installieren

Als Nächstes wird Software installiert, die im weiteren Verlauf benötigt wird. Bei der Konfiguration von mdadm sollte all gewählt werden. debian4spielwiese:~# apt-get install initramfs-tools mdadm Danach laden wir das benötigte Kernel-Modul. Das erspart einen unnötigen Neustart. debian4spielwiese:~# modprobe raid1 Entfernen etwaiger RAID-Informationen von Platte 1 und Platte 2. debian4spielwiese:~# mdadm --zero-superblock /dev/sda1 debian4spielwiese:~# mdadm --zero-superblock /dev/sda2 debian4spielwiese:~# mdadm --zero-superblock /dev/sdb1 debian4spielwiese:~# mdadm --zero-superblock /dev/sdb2 Kommt eine Meldung wie mdadm: Couldn't open /dev/sda1 for write - not zeroing, muss vorher ein aktives RAID gestoppt und die obigen Befehle erneut ausgeführt werden. In /proc/mdstat steht, in welchem Verbund die obigen Partitionen genutzt werden. debian4spielwiese:~# cat /proc/mdstat Personalities : [raid1] md1 : active raid1 sda2[0] 152512 blocks [2/1] [U_] debian4spielwiese:~# mdadm --stop /dev/md1 debian4spielwiese:~# mdadm --zero-superblock /dev/sda2 Zur Kontrolle führen wir debian4spielwiese:~# cat /proc/mdstat Personalities : [raid1] unused devices: <none> aus. Taucht dort [raid1] auf, ist das benötigte Modul geladen.

Schritt 3: Die zweite Platte vorbereiten

Die Partitionsinformationen von Platte eins werden auf die zweite Platte kopiert. debian4spielwiese:~# sfdisk -d /dev/sda | sfdisk -f /dev/sdb Checking that no-one is using this disk right now ... OK Disk /dev/sdb: 4161 cylinders, 16 heads, 63 sectors/track sfdisk: ERROR: sector 0 does not have an msdos signature /dev/sdb: unrecognized partition table type Old situation: No partitions found New situation: Units = sectors of 512 bytes, counting from 0 Device Boot Start End #sectors Id System /dev/sdb1 * 63 3887729 3887667 83 Linux /dev/sdb2 3887730 4192964 305235 82 Linux swap / Solaris Warning: partition 1 does not end at a cylinder boundary Successfully wrote the new partition table Re-reading the partition table ... If you created or changed a DOS partition, /dev/foo7, say, then use dd(1) to zero the first 512 bytes: dd if=/dev/zero of=/dev/foo7 bs=512 count=1 (See fdisk(8).) debian4spielwiese:~# fdisk -l Disk /dev/sda: 2147 MB, 2147483648 bytes 255 heads, 63 sectors/track, 261 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/sda1 * 1 242 1943833+ 83 Linux /dev/sda2 243 261 152617+ 82 Linux swap / Solaris Disk /dev/sdb: 2147 MB, 2147483648 bytes 16 heads, 63 sectors/track, 4161 cylinders Units = cylinders of 1008 * 512 = 516096 bytes Device Boot Start End Blocks Id System /dev/sdb1 * 1 3857 1943833+ 83 Linux /dev/sdb2 3857 4160 152617+ 82 Linux swap / Solaris Nun ändern wir die Partitionen der zweiten Platte auf fd (Linux raid autodetect). debian4spielwiese:~# fdisk /dev/sdb Command (m for help): t Partition number (1-4): 1 Hex code (type L to list codes): fd Command (m for help): t Partition number (1-4): 2 Hex code (type L to list codes): fd Command (m for help): p Disk /dev/sdb: 2147 MB, 2147483648 bytes 255 heads, 63 sectors/track, 261 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/sdb1 * 1 242 1943833+ fd Linux raid autodetect /dev/sdb2 243 261 152617+ fd Linux raid autodetect Command (m for help): w The partition table has been altered! Calling ioctl() to re-read partition table. Syncing disks.

Schritt 4: RAID1 erstellen

In diesem Schritt bringen wir das SoftRAID1 zum Laufen, allerdings nur mit der zweiten Platte. debian4spielwiese:~# mdadm --create /dev/md0 --level=1 --raid-disks=2 missing /dev/sdb1 debian4spielwiese:~# mdadm --create /dev/md1 --level=1 --raid-disks=2 missing /dev/sdb2 Erstellen der Dateisysteme und das korrekte Setzen der Superblöcke (ein Grund, weshalb wir im Vorfeld nicht einfach per dd Platte 1 auf Platte 2 kopiert haben) debian4spielwiese:~# mkfs.ext3 /dev/md0 debian4spielwiese:~# mkswap /dev/md1

Schritt 5: Das System auf SoftRAID1 umstellen

Damit bereits beim Booten das RAID bekannt ist, schreiben wir dies in die entsprechende Konfigurationsdatei. debian4spielwiese:~# mdadm -Ds >> /etc/mdadm/mdadm.conf Nun sollte in /etc/mdadm/mdadm.conf etwas in dieser Art stehen: debian4spielwiese:~# cat /etc/mdadm/mdadm.conf # mdadm.conf # # Please refer to mdadm.conf(5) for information about this file. # # by default, scan all partitions (/proc/partitions) for MD superblocks. # alternatively, specify devices to scan, using wildcards if desired. DEVICE partitions # auto-create devices with Debian standard permissions CREATE owner=root group=disk mode=0660 auto=yes # automatically tag new arrays as belonging to the local system HOMEHOST <system> # instruct the monitoring daemon where to send mail alerts MAILADDR root # definitions of existing MD arrays # This file was auto-generated on Mon, 29 Dec 2008 18:34:26 +0100 # by mkconf $Id: mkconf 261 2006-11-09 13:32:35Z madduck $ ARRAY /dev/md1 level=raid1 num-devices=2 UUID=a6e7f669:cf1ef2e6:f1e4296b:f263187d ARRAY /dev/md0 level=raid1 num-devices=2 UUID=e778f94e:6207f35d:f1e4296b:f263187d Als Nächstes fügen wir der Datei /etc/fstab die Dateisysteminformationen für das RAID hinzu. Im Ergebnis dürfte die Datei danach in etwa so aussehen: debian4spielwiese:~# cat /etc/fstab # /etc/fstab: static file system information. # # <file system> <mount point> <type> <options> <dump> <pass> proc /proc proc defaults 0 0 /dev/md0 / ext3 defaults,errors=remount-ro 0 1 /dev/md1 none swap sw 0 0 /dev/hda /media/cdrom0 udf,iso9660 user,noauto 0 0 /dev/fd0 /media/floppy0 auto rw,user,noauto 0 0 Nun wird das GRUB-Menü angepasst, damit wir beim nächsten Neustart das SoftRAID1 auswählen können. Des Weiteren fügen wir ein Fallback-Verhalten hinzu. Bitte unbedingt darauf achten, ob die Pfade stimmen, sonst erhält man beim Booten Error 15: File not found. debian4spielwiese:~# cat /boot/grub/menu.lst [...] default 0 fallback 1 [...] title Debian GNU/Linux, kernel 2.6.18-6-686 (SoftRAID1, hd1) root (hd1,0) kernel /boot/vmlinuz-2.6.18-6-686 root=/dev/md0 ro initrd /boot/initrd.img-2.6.18-6-686 title Debian GNU/Linux, kernel 2.6.18-6-686 root (hd0,0) kernel /boot/vmlinuz-2.6.18-6-686 root=/dev/sda1 ro initrd /boot/initrd.img-2.6.18-6-686 ## ## End Default Options ## [...] Bei diesen Änderungen ist es wichtig, dass fallback 1 hinzugefügt und die Reihenfolge der Menüeinträge eingehalten wird. Beim Booten wird zuerst versucht, von (hd1,0) zu booten; und sollte das nicht klappen: von (hd0,0), was dem aktuellen System entspricht. Damit die Änderungen beim nächsten Booten auch vorhanden sind aktualisieren wir das ramfs. debian4spielwiese:~# update-initramfs -u Jetzt kopieren wir alle Dateien von Platte 1 auf Platte 2. Dazu mounten wir /dev/md0 und kopieren komplett / debian4spielwiese:~# mkdir /mnt/md0 debian4spielwiese:~# mount /dev/md0 /mnt/md0 debian4spielwiese:~# cp -dpRx / /mnt/md0/ debian4spielwiese:~# umount /dev/md0 Um später festzustellen, von welcher Partition tatsächlich gebootet wurde, wird eine Testdatei hinzugefügt. debian4spielwiese:~# cd ~ debian4spielwiese:~# date > __TEST__ && echo "Das ist Platte 1" >> __TEST__ debian4spielwiese:~# cat __TEST__ Mo 29. Dez 20:06:46 CET 2008 Das ist Platte 1 Als letzten Teilschritt installieren wir den GRUB-Bootloader auf beide Platten. debian4spielwiese:~# grub-install hd0 debian4spielwiese:~# grub-install hd1 Falls es dabei Probleme gab, schauen Sie, ob /boot/grub/device.map so aussieht und führen Sie grub-install nach der Anpassung erneut aus. GRUB beginnt das Zählen der Geräte bei 0, während die Reihenfolge vom BIOS ausgelesen wird. Ein Diskettenlaufwerk wäre mit (fd0) ausgewiesen. debian4spielwiese:~# cat /boot/grub/device.map (hd0) /dev/sda (hd1) /dev/sdb

Schritt 6: Der Neustart

Gab es zwischenzeitlich keine Probleme, können Sie bedenkenlos einen Neustart ausführen. debian4spielwiese:~# reboot

Schritt 7: Migration der ersten Platte

Zuerst prüfen wir, ob unsere Testdatei existiert. debian4spielwiese:~# cat __TEST__ cat: __TEST__: Datei oder Verzeichnis nicht gefunden Datei nicht gefunden? Das ist genau das gewünschte Ergebnis. Nun können wir guten Gewissens die Partitionsinformationen der ersten Platte auf RAID umstellen. debian4spielwiese:~# sfdisk -d /dev/sdb | sfdisk -f /dev/sda Checking that no-one is using this disk right now ... OK Disk /dev/sda: 4161 cylinders, 16 heads, 63 sectors/track Old situation: Warning: The partition table looks like it was made for C/H/S=*/255/63 (instead of 4161/16/63). For this listing I'll assume that geometry. Units = cylinders of 8225280 bytes, blocks of 1024 bytes, counting from 0 Device Boot Start End #cyls #blocks Id System /dev/sda1 * 0+ 241 242- 1943833+ 83 Linux /dev/sda2 242 260 19 152617+ 82 Linux swap / Solaris New situation: Units = sectors of 512 bytes, counting from 0 Device Boot Start End #sectors Id System /dev/sda1 * 63 3887729 3887667 fd Linux raid autodetect /dev/sda2 3887730 4192964 305235 fd Linux raid autodetect Warning: partition 1 does not end at a cylinder boundary Successfully wrote the new partition table Re-reading the partition table ... If you created or changed a DOS partition, /dev/foo7, say, then use dd(1) to zero the first 512 bytes: dd if=/dev/zero of=/dev/foo7 bs=512 count=1 (See fdisk(8).) Zur Kontrolle schauen wir nochmal nach, ob die Partitionen stimmen. debian4spielwiese:~# fdisk -l Disk /dev/sda: 2147 MB, 2147483648 bytes 16 heads, 63 sectors/track, 4161 cylinders Units = cylinders of 1008 * 512 = 516096 bytes Device Boot Start End Blocks Id System /dev/sda1 * 1 3857 1943833+ fd Linux raid autodetect /dev/sda2 3857 4160 152617+ fd Linux raid autodetect Disk /dev/sdb: 2147 MB, 2147483648 bytes 16 heads, 63 sectors/track, 4161 cylinders Units = cylinders of 1008 * 512 = 516096 bytes Device Boot Start End Blocks Id System /dev/sdb1 * 1 3857 1943833+ fd Linux raid autodetect /dev/sdb2 3857 4160 152617+ fd Linux raid autodetect Jetzt fügen wir die erste Platte dem RAID hinzu und schauen zu, wie sich die Partitionen synchronisieren. debian4spielwiese:~# mdadm --add /dev/md0 /dev/sda1 debian4spielwiese:~# mdadm --add /dev/md1 /dev/sda2 debian4spielwiese:~# watch cat /proc/mdstat Personalities : [raid1] md0 : active raid1 sda1[0] sdb1[1] 1943744 blocks [2/1] [_U] [====>................] recovery = 23.6% (461184/1943744) finish=0.1min speed=153728K/sec md1 : active raid1 sda2[0] sdb2[1] 152512 blocks [2/2] [UU] unused devices: <none> Jetzt kann man sich darauf verlassen, dass in /etc/mdadm/mdadm.conf das Richtige steht, oder man aktualisiert die Datei (empfohlen). Dazu werden die alten Einträge entfernt und die aktuellen hinzugefügt und geprüft. debian4spielwiese:~# pico /etc/mdadm/mdadm.conf debian4spielwiese:~# mdadm -Ds >> /etc/mdadm/mdadm.conf debian4spielwiese:~# cat /etc/mdadm/mdadm.conf # mdadm.conf # # Please refer to mdadm.conf(5) for information about this file. # # by default, scan all partitions (/proc/partitions) for MD superblocks. # alternatively, specify devices to scan, using wildcards if desired. DEVICE partitions # auto-create devices with Debian standard permissions CREATE owner=root group=disk mode=0660 auto=yes # automatically tag new arrays as belonging to the local system HOMEHOST <system> # instruct the monitoring daemon where to send mail alerts MAILADDR root # definitions of existing MD arrays # This file was auto-generated on Mon, 29 Dec 2008 23:37:32 +0100 # by mkconf $Id: mkconf 261 2006-11-09 13:32:35Z madduck $ ARRAY /dev/md1 level=raid1 num-devices=2 UUID=2dd09377:e752b28b:f1e4296b:f263187d ARRAY /dev/md0 level=raid1 num-devices=2 UUID=6b15ca30:afa5a2cd:f1e4296b:f263187d Da das Booten von der zweiten Platte funktioniert hat, fügen wir GRUB die erste Platte als den "echten" Fallback hinzu. Das sollte zum Schluss in etwa so aussehen. Durch # kopt setzen wir den Standardkernel, der geladen werden soll. Die Raute gehört zum Befehl, also nicht weglassen.
Hinwies: Der Fallback-Mechanismus funktioniert nur, wenn GRUB selbst versucht zu booten, nicht, wenn man manuell einen Eintrag im Bootmenü wählt. debian4spielwiese:~# cat /boot/grub/menu.lst [...] # kopt=root=/dev/md0 ro [...] title Debian GNU/Linux, kernel 2.6.18-6-686 (SoftRAID1, hd1) root (hd1,0) kernel /boot/vmlinuz-2.6.18-6-686 root=/dev/md0 ro initrd /boot/initrd.img-2.6.18-6-686 title Debian GNU/Linux, kernel 2.6.18-6-686 (SoftRAID1, hd0) root (hd0,0) kernel /boot/vmlinuz-2.6.18-6-686 root=/dev/md0 ro initrd /boot/initrd.img-2.6.18-6-686 ## ## End Default Options ## [...] Erneute Aktualisierung des ramfs und GRUB auf den Platten. debian4spielwiese:~# update-initramfs -u debian4spielwiese:~# grub-install hd0 debian4spielwiese:~# grub-install hd1

Schritt 8: Neustart (2)

Und Neustart :-) debian4spielwiese:~# reboot Im Prinzip ist das Tutorial hier zu Ende. Es wird aber empfohlen, die Tests zumindest einmal zur Übung auszuführen.

Schritt 9: Test

Vertrauen ist gut, Kontrolle ist besser: Um zu testen, ob auch wirklich alles funktioniert, wie erwartet, gibt es zwei Wege, dies herauszufinden. Im Folgenden wird der softwareseitige Test beschrieben: Wir entfernen die zweite Platten aus dem Verbund, indem wir diese zuerst als failed bzw. failure deklarieren, um sie daraufhin zu entfernen. debian4spielwiese:~# mdadm -f /dev/md0 /dev/sdb1 debian4spielwiese:~# mdadm -r /dev/md0 /dev/sdb1 debian4spielwiese:~# mdadm -f /dev/md1 /dev/sdb2 debian4spielwiese:~# mdadm -r /dev/md1 /dev/sdb2 debian4spielwiese:~# cat /proc/mdstat Personalities : [raid1] md0 : active raid1 sda1[0] 1943744 blocks [2/1] [U_] md1 : active raid1 sda2[0] 152512 blocks [2/1] [U_] unused devices: <none> Sie können aber auch einfach die zweite Platte ausbauen und eine andere dafür einbauen. Ab hier geht es bei beiden Wegen gleich weiter. Zuerst werden die Partitionsinformationen von Platte 1 auf die neue Platte kopiert. Die Partitionen der neuen Platte werden dem RAID hinzugefügt und wir betrachten mal wieder die Synchronisation. Zu guter Letzt installieren wir auf der neuen Platte GRUB erneut (sicher ist sicher) debian4spielwiese:~# sfdisk -d /dev/sda | sfdisk -f /dev/sdb debian4spielwiese:~# mdadm --add /dev/md0 /dev/sdb1 debian4spielwiese:~# mdadm --add /dev/md1 /dev/sdb2 debian4spielwiese:~# watch cat /proc/mdstat debian4spielwiese:~# grub-install hd0 debian4spielwiese:~# grub-install hd1

Migration einer dritten Platte

Wenn zwei Platten im SoftRAID1 nicht genügen, kann man durch die folgenden Schritte weitere Platten hinzufügen. Zuerst wird der Verbund auf drei vergrößert. debian4spielwiese:~# mdadm --grow --raid-devices=3 /dev/md0 debian4spielwiese:~# mdadm --grow --raid-devices=3 /dev/md1 debian4spielwiese:~# cat /proc/mdstat Personalities : [raid1] md0 : active raid1 sda1[0] sdb1[1] 1943744 blocks [3/2] [UU_] md1 : active raid1 sda2[0] sdb2[1] 152512 blocks [3/2] [UU_] unused devices: <none> Nun übertragen wir die bestehenden Partitionsinformationen einer der Platten im RAID auf die dritte Platte und staunen, wie toll die Synchronisation funktioniert. debian4spielwiese:~# sfdisk -d /dev/sda | sfdisk -f /dev/sdc debian4spielwiese:~# mdadm --add /dev/md0 /dev/sdc1 debian4spielwiese:~# mdadm --add /dev/md1 /dev/sdc2 debian4spielwiese:~# watch cat /proc/mdstat Die dritte Platte sollte natürlich als Fallback mit in das GRUB-Menü. debian4spielwiese:~# cat /boot/grub/menu.lst [...] default 0 fallback 1 2 [...] title Debian GNU/Linux, kernel 2.6.18-6-686 (SoftRAID1, hd1) root (hd1,0) kernel /boot/vmlinuz-2.6.18-6-686 root=/dev/md0 ro initrd /boot/initrd.img-2.6.18-6-686 title Debian GNU/Linux, kernel 2.6.18-6-686 (SoftRAID1, hd0) root (hd0,0) kernel /boot/vmlinuz-2.6.18-6-686 root=/dev/md0 ro initrd /boot/initrd.img-2.6.18-6-686 title Debian GNU/Linux, kernel 2.6.18-6-686 (SoftRAID1, hd2) root (hd2,0) kernel /boot/vmlinuz-2.6.18-6-686 root=/dev/md0 ro initrd /boot/initrd.img-2.6.18-6-686 ## ## End Default Options ## [...] Wie gehabt die Aktualisierung des ramfs. debian4spielwiese:~# update-initramfs -u Und nun das Hinzufügen der neuen Platte in /boot/grub/device.map und das Aktualisieren von GRUB auf allen Platten (wichtig!). debian4spielwiese:~# cat /boot/grub/device.map (hd0) /dev/sda (hd1) /dev/sdb (hd2) /dev/sdc debian4spielwiese:~# grub-install hd0 debian4spielwiese:~# grub-install hd1 debian4spielwiese:~# grub-install hd2 Fertig.

Hinweis zu Debian 5 Lenny

Seit Debian 5 werden die Kernel-Module für Software-RAIDs standardmäßig mitgeliefert. Bei Schritt 2 kann dies beim Entfernen der Superblock-Information zu Verwirrung führen. Kommt es zur Meldung mdadm: Couldn't open /dev/sda1 for write - not zeroing, obwohl kein aktives RAID vorhanden ist, einfach weitermachen. Frei nach der Devise: Mut zur Lücke.

Hinweis zu abweichender Kernel-Version

Gerade Gameserver nutzen speziell angepasst Kernel-Konfigurationen. Der erste Neustart in Schritt 6 läuft dann ins Leere und man ist gezwungen die Dateien /boot/grub/menu.lst und /etc/mdadm/mdadm.conf zurückzusetzen. Steht die Maschine im Rechenzentrum hilft nur noch das Rescue-System (sofern angeboten). Um dem Gerecht zu werden müssen alle obigen update-initramfs-Aufrufe ersetzt werden. Obacht auch in der /boot/grub/menu.lst, da hier der Pfad ebenfalls angepasst sein muss. -- bisher -- debian4spielwiese:~# update-initramfs -u -- jetzt -- debian4spielwiese:~# update-initramfs -u -k `uname -r` -t

Nützliche Links

Software RAID1 Tutorial / Debian Etch (englisch)
Software RAID1 Tutorial / Debian Lenny (englisch)
Erläuterungen zu "menu.lst" von GRUB