Berny's Knowledgebase als Newsfeed

Wenn man Linux-Systeme betreibt, insbesondere auf einem kleinen Server (siehe z. B. Vortrag: Ein Server für zu Hause), kann es Sinn machen, die Datensicherheit dadurch weiter zu erhöhen, dass man die Daten redundant auf mehrere Festplatten schreibt. Fällt eine Festplatte aus, sind die Daten nicht verloren, da sie sich noch auf (mindestens) einer andere Festplatte befinden. Dazu kann man z. B. RAID einsetzen.

Warning
Achtung:
RAID ersetzt kein Backup!!
siehe Backup unter Linux

Hardware-RAID oder Software-RAID?

Spezielle RAID-Controller sind in Hardware verfügbar. Entweder direkt am Motherboard oder auch als Erweiterungskarten. Vorteil: Die RAID-Logik wird von dieser Hardware übernommen. Die CPU des Rechners muss sich nicht darum kümmern und steht für andere Aufgaben zur Verfügung.

Gerade im Bereich Heimserver / kleine Server halte ich persönlich allerdings Hardware-RAID für eine große Gefahr für die eigenen Daten, denn die RAID-Controller legen die Daten in einer jeweils sehr eigenen Strukturierung auf den Festplatten ab. Damit sind diese nur mit diesem RAID-Controller wieder lesbar. Der RAID-Controller wird somit also schnell zum Single Point of Failure. Im ungünstigsten Fall läuft ein Heimserver über mehrere Jahre gut und hat dann einen Hardware-Defekt am Mainboard oder RAID-Controller. Dieses Teil ist dann aber im Handel längst nicht mehr verfügbar. Man kommt an seine Daten also gar nicht mehr heran. Aber gerade um die Daten bestmöglich zu schützen, hatte man auf RAID gesetzt… :-(

Für ein Software-RAID verwendet man unter Linux mdadm und setzt z. B. auf SATA-Platten die an einem ganz normalen SATA-Controller hängen. In dem Fall hat zwar die CPU etwas mehr zu tun, aber das schaffen eigentlich alle CPUs der letzten Jahre problemlos nebenbei. Bei Hardware-Ausfall kann so eine Festplatte dann an einem beliebigen Rechner mit SATA-Controller wieder in Betrieb genommen und gelesen werden. Ein Linux mit mdadm (auch von Live-CD) ist alles was man dazu braucht.

Einrichten von mdadm

Am einfachsten setzt man gleich bei der Installation des Betriebssystems (beim Partitionieren der Festplatten) seine RAIDs mit auf, wie z. B. unter http://wiki.ubuntuusers.de/Software_RAID_mit_LVM beschrieben. Bei anderen Linux-Distributionen funktioniert das sehr ähnlich.

Um in einem laufenden System RAIDs aufzusetzen, sei auf http://wiki.ubuntuusers.de/Software-RAID verwiesen. (Hier werden auch ein paar andere nützliche Dinge über mdadm erklärt, kann man also auf jeden Fall mal lesen.)

Beispiel Heimserver mit RAID1

Im Beispiel setzen wir einen Server für zu Hause auf. Er hat zwei (idealerweise gleiche) SATA-Festplatten. Beim Partitionieren der Festplatten (s. o.) wollen wir 2 RAIDs, beide vom Type RAID1 (gespiegelte Platten) aufsetzen. Auf das zweite (kleine) RAID-Device (/dev/md1) kommt unser Swap-Bereich. Auf das erste (/dev/md0) wollen wir alles andere packen. Wir partitionieren also (während der Installation) unser Festplatten z. B. wie folgt:

root@dunno ~ # fdisk -l /dev/sda

Disk /dev/sda: 2000.4 GB, 2000398934016 bytes
255 heads, 63 sectors/track, 243201 cylinders, total 3907029168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk identifier: 0xa6167474

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048  3867187199  1933592576   fd  Linux raid autodetect
/dev/sda2      3867187200  3907028991    19920896   fd  Linux raid autodetect

root@dunno ~ # fdisk -l /dev/sdb

Disk /dev/sdb: 2000.4 GB, 2000398934016 bytes
255 heads, 63 sectors/track, 243201 cylinders, total 3907029168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk identifier: 0x932a932a

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1   *        2048  3867187199  1933592576   fd  Linux raid autodetect
/dev/sdb2      3867187200  3907028991    19920896   fd  Linux raid autodetect

Wir bilden ein RAID1 /dev/md0 aus /dev/sda1 und /dev/sdb1
und ein weiteres RAID1 /dev/md1 aus /dev/sda2 und /dev/sdb2

Bei /dev/md1 geben wir an, es als Swap nutzen zu wollen. In /dev/md0 legen wir LVM. (D. h. es dient als Physical Device für eine LVM Volume Group. Darin wiederum legen wir Logical Volumes für die benötigten Filesysteme, z. B. /, /tmp, /home, … an, aber das ist Thema eines andere Artikels.)

root@dunno ~ # cat /proc/mdstat
Personalities : [raid1]
md1 : active raid1 sda2[0] sdb2[1]
      19904384 blocks super 1.2 [2/2] [UU]

md0 : active raid1 sda1[0] sdb1[1]
      1933461312 blocks super 1.2 [2/2] [UU]

unused devices: <none>

root@dunno ~ # mdadm --detail /dev/md0
/dev/md0:
        Version : 1.2
  Creation Time : Sat Oct 26 22:09:24 2013
     Raid Level : raid1
     Array Size : 1933461312 (1843.89 GiB 1979.86 GB)
  Used Dev Size : 1933461312 (1843.89 GiB 1979.86 GB)
   Raid Devices : 2
  Total Devices : 2
    Persistence : Superblock is persistent

    Update Time : Sun Nov  3 10:57:48 2013
          State : clean
 Active Devices : 2
Working Devices : 2
 Failed Devices : 0
  Spare Devices : 0

           Name : dunno:0  (local to host dunno)
           UUID : d60acf22:98dad163:64314a68:89062122
         Events : 46

    Number   Major   Minor   RaidDevice State
       0       8        1        0      active sync   /dev/sda1
       1       8       17        1      active sync   /dev/sdb1

root@dunno ~ # mdadm --detail /dev/md1
/dev/md1:
        Version : 1.2
  Creation Time : Sat Oct 26 22:09:31 2013
     Raid Level : raid1
     Array Size : 19904384 (18.98 GiB 20.38 GB)
  Used Dev Size : 19904384 (18.98 GiB 20.38 GB)
   Raid Devices : 2
  Total Devices : 2
    Persistence : Superblock is persistent

    Update Time : Sun Nov  3 09:49:54 2013
          State : clean
 Active Devices : 2
Working Devices : 2
 Failed Devices : 0
  Spare Devices : 0

           Name : dunno:1  (local to host dunno)
           UUID : 88fa42db:d9cfa303:b015809d:72dd962c
         Events : 23

    Number   Major   Minor   RaidDevice State
       0       8        2        0      active sync   /dev/sda2
       1       8       18        1      active sync   /dev/sdb2

Bootsektor

Leider schreiben zumindest Ubuntu und Debian auch dann den Bootsektor nur auf die erste Festplatte (/dev/sda), wenn man das Setup gleich bei der Installation so hochzieht. Um im Zweifelsfall die Chance zu haben, auch von der anderen Platte zu booten, muss man den Bootsektor auf dieser Platte dann manuell schreiben mit:

grub-install /dev/sdb

Monitoring

Damit können wir unseren Server jetzt schon mal recht gut betreiben. Wichtig ist es, den RAID-Status auch zu überwachen, denn für den Anwender spürbar ist der Ausfall einer Festplatte jetzt ggf. gar nicht mehr. Es ist aber wichtig, schon zu reagieren, wenn die erste Festplatte ausgefallen ist, und nicht erst, wenn die zweite schlapp macht (denn dann wäre das RAID sinnlos).

Überwachen sollte man, zusätzlich zum SMART-Status der einzelnen Festplatten (den man auch ohne RAID überwachen sollte) jetzt also auch das [UU] in /proc/mdstat (s. o.). Es wird bei Problemen zu [U_] oder [_U].

Für Nagios gibt es fertige Check-Plugins, die man sich einfach installieren kann, z. B. check_md_raid. Wer zum Monitoring auf Nagios plus Check_MK setzt, hat es noch einfacher: Der Agent erkennt Linux-SoftRAIDs automatisch mit seiner Inventurfunktion und bietet an, diese ebenso automatisiert in die Überwachung aufzunehmen.

Sync erzwingen

Wenn in /proc/mdstat ein RAID dauerhaft den Status resync=PENDING hat und das System keine Anstalten macht, diesen Zustand selbst wieder zu beheben, kann man einen Sync auch manuell erzwingen mit mdadm --readwrite /dev/md1

Wiederherstellung bei Ausfall einer Festplatte

Was tun, wenn jetzt wirklich eine Festplatte einen Hardware-Defekt hat? Booten können wir ja noch, das hatten wir ja sichergestellt (siehe oben). Man kann die Wiederherstellung also mit dem Orginal-Betriebssystem selber durchführen. Man kann aber genauso gut von einer Live-CD, wie etwa GRML, booten.

Wir gehen davon aus, dass die zweite Festplatte (/dev/sdb) ausgefallen ist. Aus den RAID-Signaturen der noch funktionierenden Festplatte sollte Linux (auch im Live-System) die RAID-Arrays noch sicher identifizieren können. Wir prüfen das kurz:

root@grml ~ # grep ARRAY /etc/mdadm/mdadm.conf
ARRAY /dev/md/0 metadata=1.2 UUID=d60acf22:98dad163:64314a68:89062122 name=dunno:0
ARRAY /dev/md/1 metadata=1.2 UUID=88fa42db:d9cfa303:b015809d:72dd962c name=dunno:1

Ok, sieht gut aus.

Falls von Live-CD gebootet, bauen wir uns unser Device md0 erst mal wieder "zusammen" mit nur einer Platte:

mdadm --assemble /dev/md0 /dev/sda1 --force

Den "Teilerfolg" können wir überprüfen mit:

mdadm --detail /dev/md0

Gleiches tun wir auch mit md1:

mdadm --assemble /dev/md1 /dev/sda2 --force
mdadm --detail /dev/md1

Wie es jetzt weitergeht, hängt davon ab, ob schon eine Ersatz-Festplatte vorhanden ist, die in den RAID-Verbund eingebunden werden soll, oder ob man erst mal nur an seine Daten will.

Falls schon eine Ersatz-Festplatte vorhanden ist

Die neue Platte muss die gleiche Partitonsstruktur haben, wie die alte, wir übernehmen sie der Einfachkeit halber einfach von /dev/sda:

sfdisk -d /dev/sda | sfdisk /dev/sdb --force
# neue Partitionstabelle dem laufenden Kernel bekannt geben:
sfdisk -R /dev/sdb
# überprüfen:
fdisk -l

Jetzt können wir jedem RAID wieder eine zweite Platte hinzufügen:

mdadm /dev/md0 --add /dev/sdb1
mdadm /dev/md1 --add /dev/sdb2

Indem wir immer mal wieder

cat /proc/mdstat

eingeben, können wir prüfen, wie weit die Spiegelung bereits wieder aufgebaut ist.

Auf die Daten zugreifen

Unabhängig davon, ob die RAIDs schon wieder mit zwei Festplatten laufen, oder vorerst nur mit einer, kann man (im speziellen von der Live-CD aus) wie folgt auf seine Daten zugreifen:

# nach LVM Volume Groups auf allen verfügbaren Block-Devices suchen
vgscan
# gefundene Volume Groups anzeigen
vgdisplay
# eine davon (im Beispiel vg0) aktivieren
vgchange -a y vg0
# die verfügbaren Logical Volumes anzeigen
lvdisplay
# eines davon (im Beispiel lv_root) mounten
mount /dev/vg0/lv_root /mnt/test

Wenn das System wieder läuft

Im Beispiel sind wir davon ausgegangen, dass /dev/sdb ausgefallen war. Spätestens wenn die RAIDs wieder hergestellt sind booten wir wieder das orginal Betriebssystem. Jetzt sollte man nicht vergessen, den Bootsektor wieder redundant nach /dev/sdb zu schreiben, siehe oben.