neues Datenstorage mit ZFS und NFS – Plattenstorage mit mirror (und bald auch RaidZ?)


  ZFS? Wieso?

  Warum und ob man ZFS nutzen möchte, das muss jeder für sich selber wissen. Für mich stand es nun langsam außer Frage, dass mein Storage mal wieder ein Upgrade erfährt und hier auch gleich ein wenig am Dateisystem geschraubt wird.
Um etwas mehr mit ZFS zu „spielen“ eh ich es auf meinem Storage einsetze habe ich mal ein paar Szenarien durchgespielt. Was natürlich eine klasse Geschichte ist: Man kann aus einer einzelnen Festplatte, die ein ZFS Pool hat, recht schmerzfrei einen Mirror erstellen. Wieso (nur) ein Mirror? Wieso nicht gleich RaidZ? Wieso Software-RAID? Warum kein Hardware RAID?

Die Vorteile, die ZFS bietet, sind die recht unkomplizierten Portabilitäten. Man kann einen Pool ohne viel Aufwand an einem anderen Rechner importieren. Kein eigener Controller ist notwendig. Also hat man, sollte sein System mal sterben, wenig Aufwand um an seine Daten zu kommen. Einfach Platten wieder anstecken, importieren und der Pool ist wieder da. RAID Controller hingegen sind, wie sagt man nett, schmerzhaft, sollte seine Hardware mal sterben. Meist ist man dann ein wenig am ArXXXX.


Als Idee hatte ich mir also einmal einen ZFS Pool vorgestellt, der ersteinmal aus einer Platte besteht. Auf dieser wird zusätzlich ein Dataset erstellt, welches per NFS eine Freigabe für andere Clients bietet. Auf der Platte werden dann ein paar Daten erstellt, die einfach nur da sind. Um also nicht produktive Daten ins Nirvana zu schicken ein paar Gigabyte Dateien erstellt.
Schön. Nun hat man einen Pool mit einer Platte. Zwar fein, aber nicht fein genug. Die einzelne Platte kann sterben. Hat man kein Backup, sind die Daten futsch. Jaja, Backups sind nur was für Weicheier, da bin ich aber gerne eines 😉
Nachdem nun der Pool existiert habe ich eine weitere Platte in den Pool getan, um aus der einzelnen einen Mirror zu erstellen. Gespiegelt sind die Daten auf den Platten schon mal sicherer. Hier habe ich zwar schon einen grundsätzlichen (Struktur-)Fehler begangen: Die Festplatten sind vom gleichen Hersteller, vom gleichen Typ. Und wohl auch aus einer gleichen Charge. Das sollte man natürlich nicht machen, sondern zwei unterschiedliche Hersteller, unterschiedliche Typen usw. nutzen. Wie dem auch sei, ich kann damit erstmal leben. Man muss seine Datensicherheit ja nicht unbedingt auf die Spitze treiben. Sollte also irgendwann mal eine Platte sterben, muss halt schnell eine Ersatzplatte aktiviert werden (oder bis dahin ist der einfache Mirror auf ein RaidZ umgebaut, dann ist der Ausfall einer Platte nicht so dramatisch).

Nun hat man zwar schon einmal einen Mirror (Spiegel) aus zwei Festplatten und ist schon sicherer als mit nur einer einzelnen HDD, aber reicht das? Auch ist ZFS ein wenig robuster was Bitfehler angeht als die üblichen Dateisysteme ext2, ext3 und ext4, trotzdem ist es auch noch nicht das Ziel, wenn einem die Daten unglaublich viel bedeuten und man auf diese angewiesen ist. Und hier hört dann erstmal mein Festplattenverbrauch auf. Leider sind die Preise noch immer pervers, so dass man sich schon überlegen muss, ob man nun vier HDDs einsetzen möchte oder auch mit einem Spiegel und etwas Backups auskommt. Und mir reicht dieser Aufwand ersteinmal und ich gehe davon aus, schon gut gerüstet zu sein.
Sollten die Preise mal wieder auf erträgliche (!) Preise fallen, so wird der Mirror umgebaut. Ich habe hierzu schon eine gute Anleitung gefunden, wie man aus diesem normalen Spiegel ein RaidZ bauen kann, ohne alles zu backup’pen, den Pool zu zerstören und mit allen neuen Platten neu anzulegen. Wird sich dann klären, ob das auch so klappt 😉

Eines gleich vorweg: Ein wenig Mitdenken ist zwingend erforderlich. Gibt man den falschen Devicenamen an, sind ganz schnell ein paar Daten weg. Alle Angaben hier beziehen sich auf meine Begebenheiten und sind selbstverständlich passend zu ändern. Keine Gewähr für Fehler, Datenverlust und sonstige Probleme!


  Im Einzelnen: Anlegen eines ZFS Dateisystem über die gesamte Platte – die erste Festplatte für den Spiegel vorbereiten

  Wir nennen unseren Pool datengrab. Die Festplatten sind allesamt S-ATA Festplatten, die unter Ubuntu mit Devicenamen /dev/sdX geführt werden. Plant man ersteinmal keinen Umbau oder Erweiterung der Festplatten, kann man es bei den Devicenamen /dev/sdX belassen. Will man allerdings auf der sicheren Seiten sein, so nimmt man die GUID der Festplatten. Das hat den Vorteil, dass man die Festplatten umbauen kann, weitere ein- oder ausbauen kann und der Pool danach ohne Probleme läuft. Würde man auf die Devicenamen setzen, sich dieser ändern so würde der Pool nicht mehr gestartet werden können und der Pool wird als FAULTED markiert.
Damit wir aber auch durch Schmerzen gehen (ja, man möchte auch das einmal testen) machen wir es anders: Wir legen auf einer Festplatte einen Pool mit festem Devicenamen an, fügen dann eine weitere Festplatte dem System hinzu und sehen, was passiert (in Kurzform: Es fliegt einem ein wenig um die Ohren 😉 ). Danach ändern wir das wieder ab und stellen auf GUID-Namen um.

Erstellung eines Pools über die gesamte Platte /dev/sdb:

  Shell #> sudo zpool create datengrab /dev/sdb
(Angabe kann /dev/sdb oder auch nur sdb sein.)

Es wird von ZFS der Pool datengrab angelegt und automatisch nach /datengrab gemountet. Hierdrin kann man nun Daten ablegen. Spaßeshalber kann man nun die Platte einmal ausbauen und an einem anderen Rechner anschließen. Dort kann dann mit sudo zpool import datengrab dieser Pool import werden, die Daten sind auch dort zugänglich. Damit hätte man also schon mal eine gewisse Sicherheit, sollte einem der Rechner (aber natürlich nicht die Platte!) mit der Platte mal verrecken.


Nun wollen wir mal sehen, was passiert, wenn sich der Devicename ändert. Also System herunter gefahren, weitere Festplatte eingebaut und neu gebootet. Siehe da, der ZFS Pool ist nicht automatisch nach dem Bootvorgang vorhanden, da sich der Devicename (wunschgemäßg für diesen Test) von /dev/sdb auf /dev/sdc geändert hat.

  Shell #> sudo zpool status -v datengrab
pool: datengrab
state: FAULTED
status: One or more devices could not be used because the label is missing
        or invalid. There are insufficient replicas for the pool to continue
        functioning.
action: Destroy and re-create the pool from
        a backup source.
see: http://www.sun.com/msg/ZFS-8000-5E
scrub: none requested
config:

        NAME           STATE     READ WRITE   CKSUM
        datengrab     FAULTED     0     0     0     corrupted data
            sdb           UNAVAIL     0     0     0     corrupted data

Der Status zeigt, dass der Pool FAULTED ist. In den Infos wird einem nun empfohlen, den Pool zu zerstören und neu anzulegen, Backup einzuspielen und fertig.

Ja, kann man natürlich machen. Wollen wir aber nicht. Da die Platte ja existiert und sich nur der Devicename geändert hat gibt es auch einen anderen Weg.
Einfach den Pool exportieren und wieder importieren. Der Rechner sucht nun auf allen Devices nach ZFS Infos und import diese dann korrekt:

  Shell #> sudo zpool export datengrab
  Shell #> sudo zpool import -a

Damit ist nun der Pool wieder vorhanden und kann genutzt werden. Als Deviceangabe erscheint nun in der zpool-Status Ausgabe der Device-Name als GUID, der Status ist wieder ONLINE und alles ist gut.


  Festlegen des Mountpointes

  Da ohne weitere Änderung des Wertes mountpoint der Pool automatisch nach ‚/‘ gemountet wird, sollte man das auch noch mal ändern. Eine Variante ist, dass man diesen auch mit nach /media mountet.

Um nun den Mountpount beim Import automatisch nach /media/ zu legen ändert man diesen ab:

  Shell #> sudo zfs set mountpoint=/media/mountpointname poolname

Damit wird automatisch von zfs der Mountpoint angelegt, sollte dieser noch nicht existieren und der Pool hierhin gemountet.


  Zweite Platte für einen Spiegel

  Der einzelnen Platte wird nun eine zweite hinzugefügt und damit (dank ZFS) automatisch aus der einzelnen Platte ein gespiegelter Pool erzeugt. Die Daten im Pool bleiben dabei erhalten und werden automatisch auf die zweite Festplatte gespiegelt („resilvered“). Voraussetzung hierfür ist allerdings, dass die hinzuzufügende Festplatte mindestens genau so groß ist wie die schon vorhandene. Sie darf größer oder mind. gleich groß, aber nicht kleiner sein.

Shell:~$ sudo zpool attach datengrab /dev/disk/by-id/…….. /dev/neuePlatte
(Aufruf: zpool attach Poolname VorhandeneHDD NeueHDD)


  Devicename eines Spiegelteils ändert sich

  Was ja u.U. mal vorkommen kann: Man hat einen Spiegel angelegt, der aus einem festen Devicenamen (und einem by-id GUID Namen) besteht. Nun ändert sich dieser eine feste Devicename. Der Spiegel wird nun beim Hochfahren nur mit einer Platte gestartet. Die zweite Platte wird als nicht vorhanden angezeigt. Gleiches kann natürlich passieren, wenn’s eine Platte gehimmelt hat:

Shell:~$ sudo zpool status -v spiegel
  pool: spiegel
 state: ONLINE
status: One or more devices could not be used because the label is missing or
        invalid.  Sufficient replicas exist for the pool to continue
        functioning in a degraded state.
action: Replace the device using ‚zpool replace‘.
   see: http://www.sun.com/msg/ZFS-8000-4J
 scrub: none requested
config:

        NAME                                                     STATE     READ WRITE CKSUM
        spiegel                                                  ONLINE       0     0     0
          mirror-0                                               ONLINE       0     0     0
            sdb                                                  UNAVAIL      0     0     0  corrupted data
            disk/by-id/usb-08ec_0020_0D41CA6050B06969-0:0-part1  ONLINE       0     0     0


Die Platte sdb ist somit (derzeit) nicht mehr vorhanden. Wenn man weiß, dass es die Platte nicht gehimmelt hat sonder sich nur der Name verändert hat, ist es halbwegs gut. Wenn nicht, wird man sich schon mal eine Ersatzplatte aus dem Schrank nehmen müssen 😉

Wie kriegt man den Spiegel nun wieder heil?

Situation 1: Es hat sich nur der Devicename geändert:

die Statusinfos zum Pool zeigen, dass der Spiegel zwar „so da“, aber nicht heil ist.

Shell:~$ sudo zpool status -v spiegel
pool: spiegel
state: DEGRADED
status: One or more devices could not be used because the label is missing or
      invalid. Sufficient replicas exist for the pool to continue
      functioning in a degraded state.
action: Replace the device using ‚zpool replace‘.
      see: http://www.sun.com/msg/ZFS-8000-4J
scrub: none requested
config:

      NAME STATE READ WRITE CKSUM
      spiegel DEGRADED 0 0 0
       mirror-0 DEGRADED 0 0 0
          13759121921700937472 UNAVAIL 0 0 0 was /dev/disk/by-id/usb-Generic_STORAGE_DEVICE_000000009602-0:0
          disk/by-id/usb-08ec_0020_0D41CA6050B06969-0:0-part1 ONLINE 0 0 0

Einfach den Pool einmal exportieren und erneut importieren. Danach ist der Pool wieder da.


Situation 2: Die Platte ist verstorben.
Das ist schon ein wenig aufregender. Aber auch kein großes Problem, solange nun nicht noch gleichzeitig die zweite Platte stirbt und man kein Backup hat. Nach Murphy’s law sollte man solche (zwar recht unwahrscheinlichen) Fälle trotzdem in Betracht ziehen 😉

Damit eine Platte aus einem Pool entfernt werden kann, muss diese erstmal offline genommen werden, andernfalls wird einem ZFS das auch mitteilen:

Shell:~$ sudo zpool offline spiegel /dev/disk/by-id/usb-Generic_STORAGE_DEVICE_000000009602-0:0

Danach kann diese „detached“ werden:

Shell:~$ sudo zpool detach spiegel /dev/disk/by-id/usb-Generic_STORAGE_DEVICE_000000009602-0:0

Nun ist der bisherige mirror kein mirror mehr sondern nur noch eine einzelne Platte:

Shell:~$ sudo zpool status spiegel

pool: spiegel
state: ONLINE
scrub: none requested
config:

NAME STATE READ WRITE CKSUM
spiegel ONLINE 0 0 0
disk/by-id/usb-08ec_0020_0D41CA6050B06969-0:0-part1 ONLINE 0 0 0


Nun wird dieser einzelnen Platte wieder eine zweite Platte hinzu gefügt:

Shell:~$ sudo zpool attach spiegel /dev/disk/by-id/usb-08ec_0020_0D41CA6050B06969-0:0-part1 /dev/disk/by-id/usb-Generic_STORAGE_DEVICE_000000009602-0:0
(Aufruf: zpool attach Poolname Name_existierende_HDD Name_neue_HDD)


  Anlegen eines Spiegels mit zwei Platten

  Natürlich kann man sich die obigen Schritte (einzelne Platte anlegen, zweite Platte hinzu usw.) sparen und gleich einen Spiegel aus beiden Platten bauen.
Ich wollte aber „aus Gründen“ testen, ob es klappt und habe mich daher ausdrücklich dazu entschlossen, es anders zu machen. Auch, weil u.U. andere Festplatten ebenfalls mal zu einem Spiegel umgebaut werden sollen. Da ist es also hilfreich, die Funktion getestet zu haben….

Will man also seinen Spiegel gleich aus zwei Platten bauen:

Shell:~$ sudo zpool create poolname mirror /dev/sdx /dev/sdy
(Legt den Pool poolname als Typ mirror bestehend aus den zwei angegebenen Platten an.)


Da ja nun schon bekannt ist, dass feste Devicenamen so ihre Nachteile haben sollte man statt dessen lieber die GUID Namen nehmen. Diese bekommt man unter anderem heraus, wenn man mal
ein

Shell:~$ ls -all /dev/disk/by-id/* | grep sdy
(sdy ist natürlich durch den richtigen Devicenamen zu ersetzen…)


Shell:~$ sudo zpool create spiegel mirror /dev/disk/by-id/GUID_Name_hdd1 /dev/disk/by-id/GUID_Name_hdd2 /

Wie schon in den oben erwähten Statusansichten über den Spiegel wird man nun sehen, dass der Pool poolname aus den Devices besteht. Als Typ wird einem nun mirror-laufendeZahl genannt.


Ersetzen einer Platte bzw. Vergrößerung des Pools

  Hat man geplant, seinen Spiegel zu vergrößern ist der Weg, eine Platte aus dem Pool zu entfernen, eine neue (und größere) einzubauen, die neue in
den Pool zu integrieren, ein „resilvering“ Prozess durchlaufen und dann die andere zu ersetzen ein einfacher weg. Man spart sich aus Auslagern auf eine weitere Platte, die genau so groß sein muss wie der Datenbestand.

Shell:~$ sudo zpool detach spiegel /dev/disk/by-id/usb-Generic_STORAGE_DEVICE_000000009602-0:0

Shell:~$ sudo zpool status spiegel

> Zeigt einem nun, dass der Pool nur noch aus einer Platte besteht.


Nun wird die neue Platte (zwingend erforderlich ist, dass diese mind. gleich groß oder größer ist!) dem Pool zugeordnet:

Shell:~$ sudo zpool attach spiegel /dev/disk/by-id/usb-08ec_0020_0D41CA6050B06969-0:0-part1 /dev/disk/by-id/usb-Generic_STORAGE_DEVICE_000000009602-0:0

Wir sehen, dass der resilver Prozess automatisch begonnen hat:

Shell:~$ sudo zpool status -v spiegel
pool: spiegel
state: ONLINE
scrub: resilver completed after 0h0m with 0 errors on Mon Oct 8 18:27:31 2012
config:

NAME STATE READ WRITE CKSUM
spiegel ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
disk/by-id/usb-08ec_0020_0D41CA6050B06969-0:0-part1 ONLINE 0 0 0
disk/by-id/usb-Generic_STORAGE_DEVICE_000000009602-0:0 ONLINE 0 0 0 105K resilvered


Damit die Daten nun auch wirklich korrekt auf beiden Platten drauf sind noch ein scrub durchlaufen lassen (das dauert…. und dauert):

Shell:~$ sudo zpool scrub spiegel

Der scrub-Prozess ist zwar zu diesem Zeitpunkt nicht wirklich möglich, da der resilver-Prozess den Datenbestand ja gerade erst auf die zweite Datei kopiert hat, trotzdem schadet es nichts. Ebenfalls schadet es natürlich nicht, diesen ein Mal die Woche durchlaufen zu lassen. Es ist zwar ein langwieriger Prozess und lässt die Platten ordentlich arbeiten, stellt aber die Datenintegrität sicher.


Der Spiegel ist nun mit einer noch-kleinen Platte und einer neuen-großen Platte vorhanden. Macht man nun den ganzen Durchlauf noch einmal und wirft hierbei die kleine Platte raus, attached die neue (und dann auch große) Platte dem Spiegel so hat man danach einen Spiegel, der gewachsen ist, ohne dass man eine weitere Platte zur Auslagerung benötigt hat.


  Split als Backup

  ZFS bietet eine interessante Möglichkeit, seine Daten zu sichern: Man baut aus einem Spiegel eine Platte aus und nimmt diese, um diesen Spiegel wieder woanders zu erstellen. Also auch ideal, wenn man mal ein paar GB transportieren möchte um ein offsite Backup zu haben.

Spiegel1 -> Split einer Platte aus dem Spiegel.
Diese Platte wird dann in anderem Rechner als Basis genommen, eine weitere Platte attached, resilvered, fertig.

Shell:/test2$ sudo zpool status -v

pool: test2
state: ONLINE
scrub: scrub completed after 0h0m with 0 errors on Mon Oct 8 18:53:49 2012
config:

NAME STATE READ WRITE CKSUM
test2 ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
disk/by-id/usb-Generic_STORAGE_DEVICE_000000009602-0:0 ONLINE 0 0 0
disk/by-id/usb-08ec_0020_0D41CA6050B06969-0:0 ONLINE 0 0 0

errors: No known data errors


Aus dem Zpool-Spiegel spiegel wird die angegebene Platte entfernt:

Shell$ sudo zpool split spiegel spiegel2 /dev/disk/by-id/usb-Generic_STORAGE_DEVICE_000000009602-0:0

Damit wird die angegebene Platte aus dem Pool spiegel getrennt und als Poolname spiegel2 vergeben. Wird kein Devicename angegeben, so wird die zuletzt hinzu gefügte aus dem Spiegel entfernt.
Diese Platte kann man nun an anderer Stelle wieder als spiegel2 importieren, wieder eine zweite Platte attachen und fertig ist der zweite Spiegel an anderer Stelle. Der original-Spiegel bekommt dann auch wieder eine Platte und man hat nun zwei Spiegel an unterschiedlichen Standorten.


  ZFS Pool im LAN freigeben als NFS Share

Einfach und unkompliziert lässt sich ein spezieller Pool (oder einfach alle ZFS Pools) im LAN als NFS Share freigeben. Diese Freigabe gibt den Zugriff (ohne weitere Optionen bzw. Einschränkungen) im LAN komplett frei. Man sollte sich also schon ein wenig Gedanken über Zugriffsrechte und so weiter machen und diese Optionen u.U. noch anpassen…
(Anmerkung: Voraussetzung hierfür ist, dass man NFS schon installiert hat. Unter Ubuntu ist u.a. das Paket nfs-kernel-server nötig…)
Anders als bei dem üblichen Weg über die /etc/exports muss man nicht noch einmal explizit den nfsd „durchtreten“ oder mit sudo exportfs -a diese Datei neu einlesen. Eine Freigabe über ZFS-share-on ist sofort verfügbar.


Einen speziellen Pool per Share-NFS aktivieren:

Shell:~$ sudo zfs set sharenfs=on datengrab


oder einfach alle ZFS Pools freigeben:

Shell:~$ sudo zfs share -a
(-a gibt alle Pools frei, man kann auch Poolnamen angeben)


Share-NFS für einen speziellen Pool wieder deaktivieren:

Shell:~$ sudo zfs set sharenfs=off datengrab


oder einfach für alle wieder deaktivieren:

Shell:~$ sudo zfs unshare -a


  Mounten des ZFS-NFS Pools auf dem Client

  Auf der Client Seite kann man sich nun die Freigaben auf dem ZFS-NFS Server auflisten lassen:

Shell:~$ showmount -e IP_ZFS_Server
Export list for IP_ZFS_Server:
  /datengrab       *


Der Client kann die Freigabe nun mounten:

Shell:~$ mount -t nfs IP_ZFS_Server:/datengrab /ziel/wohin

Oder einfach in die /etc/fstab eintragen und über diese mounten. Fertig.


  Probleme mit dem Schreibzugriff des NFS Shares auf dem Client?

  Es hat mich einiges an Nerven gekostet, immer wieder habe ich auf den NFS Clients den Hinweis bekommen, dass das Dateisystem „read-only“ gemountet wurde und nicht beschreibbar sei. In den sharenfs Einstellungen sowie auf dem Client stand das NFS Share jedoch mit ‚rw‘ drin. Häh?
Nach einigem Suchen habe ich dann etwas gefunden. Vll. hilft es ja jemand: Die Zugriffsrecht sollte man auf dem Mountpoint, wohin auf dem ZFS-NFS Server der Pool gemountet wird, ruhig großzügig setzen…
Zur Not einfach mal 777 nutzen, den Eigentümer und Gruppe von root auf einen Benutzer, der zugreifen darf, ändern. Fertig…


  Aus einem Mirror ein RaidZ?

  Ich habe mich nun erstmal mit der Situation „mirror“ unter ZFS beschäftigt. Nach derzeitiger Recherche soll es auch (über einen kleinen Umweg) möglich sein, aus einem mirror einen raidZ Verbund zu machen.
Das werde ich doch dann demnächst auch noch mal testen 😉


  Anmerkung….

  Der Blogeintrag ist noch nicht zu 100% vollständig und ist somit „work in progress“. Sollten wir selber noch Dinge fehlen, kommen die nach und nach hinzu. Ich denke aber, der ist schon lang genug und kann auf die Menschheit losgelassen werden 😉


Links:
http://docs.oracle.com/cd/E19253-01/819-5461/index.html
Ersetzen einer Festplatte http://docs.oracle.com/cd/E19253-01/820-2313/gbcet/index.html
http://www.fscker.ca/rc/2010/05/20/migrate-zfs-mirror-to-raidz-on-freenas/

Dieser Beitrag wurde unter Allgemein, Backup, Dokus und Tipps, Linux/ UNIX, Technikspielkram abgelegt und mit , , , , , , , , , , , , , , , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

1 Antwort zu neues Datenstorage mit ZFS und NFS – Plattenstorage mit mirror (und bald auch RaidZ?)

  1. ich sagt:

    Top Howto, leider fehlt das replace 😉

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert