ZFS: jail, NFS, etc.

Rakor

Administrator
Teammitglied
Hallo zusammen,

nachdem ich nun doch beschlossen hatte auf ZFS zu wechseln habe ich mir die Manpages zu zpool(8) und zfs(8) durchgelesen. Dabei sind mir jedoch einige Fragen aufgetreten.

1. jail: Ich kann angeblich ein ZFS dataset an eine Jail binden. Aber war bringt mir das nun genau? Ich habe es so verstanden, dass dies einfach nur dazu führt, dass ich per zfs(8) aus der Jail herraus Einfluss auf das dataset nehmen kann? (aber nicht auf den zpool vermute ich).

2. NFS: So wie ich das verstehe kann ZFS selbst NFS-Funktionalität über mountd bereitstellen. Sprich ich kann einem ZFS dataset sagen, dass (und wie) ich es per NFS zur Verfügung zu stellen. Das finde ich schon sehr interessant, parallel dazu lese ich aber immer, dass NFS auf ZFS sehr langsam wird wenn man keine seperate ZIL anbietet. Ist das nur so wenn ich das "interne" NFS verwende oder auch wenn ich per exports arbeite? Wie ist das mit dem exportieren aller Mutterdatasets?

3. ZIL: Wo wir dabei sind... Eine extra ZIL sollte angeblich angeboten werden wenn man NFS nutzt oder viel mit Datenbanken arbeitet (alles was syncron schreiben will). Dass das ganze als Mirror ausgelegt sein soll ist (als Schreibpuffer) nachvollziehbar, aber wie wirkt sich das "Fehlen" aus? Gerade im Unterschied zu normalem UFS?

4. root aus zpool: Ich gehe hier davon aus, dass ich ein ZFS-only-System verwende. Ich will nun den zpool als / verwenden und darin die entsprechenden Unterverzeichnisse die ich will als dataset anlegen. Andere Tutorials gehen davon aus, dass / als eigenes dataset unter ihrem zpool angelegt werden. Dann biegen die alle mountpoints der anderen datasets entsprechend um. Gibts da einen guten Grund für? Meines erachtens ist es doch völlig legitim das zpool selbst als / zu verwenden.

5. booten: Da ich ohne UFS arbeiten will muss der Spass natürlich booten. Also zum Einen mounten sich die ganzen ZFS-datasets ja selbst (wenn die Optionen richtig gesetzt sind) und brauchen daher keine fstab aber zum Anderen muss ja / gemounted werden. Ich habe das so verstanden, dass die Zeile "vfs.root.mountfrom="zfs:$NAME_MEINES_ROOT-ZFS" in der loader.conf dazu führt. Vorrausgesetzt, dass ich zfs in der loader.conf lade sollte dann alles funktionieren oder brauchts zum Booten nochwas?
Ok, ich muss noch "zpool set bootfs=$MEINPOOL $MEINPOOL" setzen. Wobei ich mich frage warum ich das UND den Eintrag im loader.conf setzen muss? Welche unterschiedliche Bedeutung haben die beiden?


6. swap: Das Swappen auf ZFS wird allgemeinhin nicht empfohlen da das Schreiben in ZFS-Swap selbst wieder Speicher braucht und sich somit die Katze in den Schwanz beisst. gmirror zusätzlich nur für den SWAP zu verwenden finde ich nicht reizvoll daher werde ich einzelne Swaps anlegen. Wie seht ihr das? Wenn er swappt es es ja eh schon "zu spät" für Performance. Wird sich das SWAP-auf-ZFS-Problem irgendwann lösen? Ich vermute nein, da es ja ein intrinsisches Problem von ZFS ist.

7. cache: Beim anlegen des ZFS über eine LiveCD wird ein Cache angelegt den ich später nach /boot/zfs/$MEINPOOL.cache kopiere. Was genau steht denn da drin und warum kann das ZFS nicht ohne den? Kann ich mir das kopieren sparen wenn ich den pool exportiere? (Vermutlich kann ich dann nicht davon booten?).

8. import & export: Was genau macht denn das? OK, wenn ich Platten umbaue soll ich exportieren und im Zielsystem importieren. Aber was genau wird da gemacht? Geht es im den Cache?

9. src.conf: Ich lese dann noch hin und wieder: "'LOADER_ZFS_SUPPORT=YES' > /etc/src.conf". Was macht denn das?!

10. /var/empty: Hat nix direkt damit zu tun aber der wird gerne als eigenes Dataset angelegt und ich frage mich: Was ist denn das für ein Ordner der immer leer sein soll?!

Soweit meine kleine Fragerunde.... ;) Danke für eure Anteilnahme
:)
 
So, dann fangen wir mal an:

1. Genau. Ein ZFS an ein Jail zu binden ermöglicht dir, das Dataset (und alle darunter) aus dem Jail mit zfs(8) zu manipulieren. Damit das funktioniert, benötigt das Jail noch einige andere Attribute. Dazu gehört unter anderem "allow_statfs".

2. ZFS hat keinen eingebauten NFS-Server. Freigaben per zfs(8) werden in /etc/zfs/exports eingetragen und der mountd danach geHUPt. Genauso gut kannst du den Eintrag auch manuell in /etc/exports machen, es ändert nichts. Das ZFS ohne Logdevice relativ langsam über das Netz ist ist, ist ein prinzipielles Problem aller Netzwerkdateisysteme inklusive Samba. Im Fall von NFS4 ist zusätzlich zu beachten, dass alle Datasets vom NFS4-Root bis zur eigentlichen Freigabe ebenfalls freigegeben werden müssen.

3. Wenn du kein Logdevice hast, wird die ZIL innerhalb des Pools gespeichert. Die Funktionalität ist also gleich. Wenn du die ZIL komplett abschaltest (nicht empfohlen), ist das Verhalten im Absturzfall das Gleiche wie unter UFS. Die letzten paar Sekunden bis Minuten können fehlen. Grundsätzlich benötigt ZFS im Regelbetrieb niemand ein fsck, anders als UFS. Je nach Qualität der Hardware kann aber u.U. ab und an ein "zfs scrub" notwendig werden.

4. Genauso mache ich das. Das Rootverzeichnis meines Pool ist /. Das harmoniert zwar nicht besonders gut mit "Boot Environments" - also der Möglichkeit verschiedene FreeBSD in einem Pool zu haben und beim Boot auszuwählen - aber das möchte ich nicht. Es sieht dann so aus:
Code:
system                  26,4G  15,4G   878M  legacy
system/tmp               222M  15,4G   221M  /tmp
system/usr              23,0G  15,4G  3,97G  /usr
system/usr/home         2,31G  15,4G    33K  /usr/home
system/usr/home/yamagi  2,31G  15,4G  2,07G  /usr/home/yamagi
system/usr/jails        5,75G  15,4G  1,69G  /usr/jails
system/usr/local        8,47G  15,4G  5,71G  /usr/local
system/usr/ports         581M  15,4G   485M  /usr/ports
system/usr/src           946M  15,4G   473M  /usr/src
system/var              2,19G  15,4G  1,28G  /var
 
Und nun die zweite Hälfte:

5. Der Bootprozess von ZFS ist in 9-STABLE deutlich vereinfacht worden, da man dort weder den zpool.cache durch die Gegen kopieren, noch irgendwelche sysctl setzen muss. Die Lösung in 9.1 und älter ist das Ergebnis des Versuchs, die Solaris-Logik mit FreeBSD zu verheiraten:
- zpool.cache benötigt man, da ZFS sonst nicht erkennt, ob der Pool zum System gehört.
- vfs.root.mountfrom braucht man, damit der Kernel weiß, was das Root-FS ist.
- das bootfs Property braucht man, damit ZFS weiß, was das Root-FS ist.
In Zukunft wird es reichen, bootfs zu setzen. Solange es eindeutig ist. Der zpool.cache wird für den Rootpool ignoriert, aber für die anderen Pools zwecks Kompatibilität mit Solaris noch beachtet.

6. Das Problem ist lange nicht mehr zu groß wie am Anfang, das System mit Swap auf ZFS zu killen ist kaum mehr möglich. Optimal ist es aber nicht. Von daher sind zwei Partitionen schon eine gute Wahl, spiegeln würde ich nichts. Wenn die Platte verreckt, hast du andere Sorgen als deine Swap. Zumindest auf Desktopsystemen.

7. Der Cache ist wie oben schon angedeutet ein weiterer Solarismus (das Wort lasse ich mir schütze). Solaris ist der sehr langsam darin, alle Speichermedien einzulesen, Das kann bei größeren Mengen schon mal Minuten dauern. Der zpool.cache speichert also simpel gesagt, welches Device zu welchem Pool gehört, damit nicht jedes Mal neu eingelesen wird. Unter FreeBSD ist das nicht nötig, da dank GEOM auch große Mengen Platten in Sekundenbruchteilen eingelesen werden können. Außerdem hat FreeBSD keine statischen Device-Namen, weshalb der Sinn des Caches eh unterlaufen wird. Es gab daher eine längere Diskussion, ihn komplett abzuschaffen. Man hat es am Ende nur für den Root-Pool gemacht und sich bei den anderen dagegen entschieden, um nicht zu weit von anderen ZFS-Implementierungen abzuweichen.

8. Ja, es geht auch um den Cache. Aber der eigentliche Sinn des Imports ist, dass der Pool einem System zugeordnet wird. Dabei wird die Ausgabe von "sysctl kern.hostuuid" in den Pool gespeichert, damit er ist dem System zugeordnet. Da die UUID über Reboots hinweg in /etc/hostid gespeichert wird, ist es beim Klonen einer Installation eine gute Idee die Datei zu löschen und noch einmal zu rebooten. Der Sinn dieser Bindung eines Pools an einen Host ist vor allem in großen SAN zu sehen, wo die Festplatten nicht lokal gespeichert sind, stattdessen über das Netz eingebundene Images. Es wird verhindert, dass der falsche Host den Pool nutzt.

9. Gar nichts. Zu Beginn der ZFS-Ära war die Bootuntrstützung optional, man musste sie erst einschalten. Inzwischen muss man das nicht mehr.

10. Eine (meiner Meinung nach kaputte) Programme und Scripte brauchen aus seltsamen Gründen ein leeres Verzeichnis. In /var/empty finden sie es. Muss eigentlich kein Dataset sein, ist ja eh leer. :)
 
Und nun die zweite Hälfte:
10. Eine (meiner Meinung nach kaputte) Programme und Scripte brauchen aus seltsamen Gründen ein leeres Verzeichnis. In /var/empty finden sie es. Muss eigentlich kein Dataset sein, ist ja eh leer. :)
Das sind keine kaputten Programme sondern vorsichtige. Sie sperren sich nach der Initialisierung per chroot(2) oder jail(2) nach /var/empty und geben ihre Rechte ab. Somit können sie selbst im Falle einer Memory Corruption mit Remote Code Execution nicht mehr missbraucht werden um ins Dateisystem zu schreiben. Ist /var/empty ein eigenes Dateisystem kann es read-only gemounted werden. Dadurch wird die Angriffsfläche noch weiter reduziert.
 
Kamikaze: Die Absicht ist hier Defence in Depth. Selbst sollte etwas schief gehen wird der Schaden beschränkt.
 
ich hab gestern meinen Desktop mal neu eingerichtet mit einer SSD und 3 Festplatten. Natürlich alles zfs only mit 2 Pools.

Das schlimme an zfs ist eigentlich dass du irgendwann feststellst dass das was du an Dateisystemen/LVM/Sonstigen Managern bei anderen Betriebssystemen (ausser Solaris) bekommst einfach nur Schrott ist. Du kapierst dann einfach nicht mehr warum du dich unter Linux mit LVM rumschlagen musst wenn du ein RAID willst, oder warum das unter Windows ohne Hardware RAID sowieso nicht funktioniert. Du verstehst es einfach nicht ;)
 
ZFS macht echt Spaß und ist einfach zu bedienen, sogar so einfach das ich immer wieder erwarte das mir das zeug um die Ohren fliegt :D
Soweit ich bisher gelesen habe ist ZFS an einer Stelle nicht zu gebrauchen, nämlich dann wenn du ein verteiltes Dateisystem brauchst. Wenn ich den Anwendungsfall jemals haben sollte, findet sich da aber bestimmt auch eine Lösung. :)
 
Da möchte ich mich zunächst mal bedanken für die sehr guten Antworten :) Es ist hier einfach immer wieder sehr aufschlussreich :)

ad 1. OK dann brauch ich das nicht. Ich verwalte meine Jails eh alle vom Host aus :)

ad 2. Aha, das erklärt so einiges. Ich hatte mich schon gewundert, dass man NFS in ZFS mit einbaut, aber man weiss ja nie. Dass ich mit NFS4 alle überlagerten Verzeichnisebenen mit freigeben muss finde ich irgendwie komisch... Ich muss die aber nur in den exports haben, nicht wirklich alle für den entsprechenden client freigeben oder? Das wäre sonst doch eine derbe Einschränkung. Vom Sicherheitsaspekt her will ich an sich nicht unbedingt mehr freigeben als ich wirklich will.

ad 3. Aha. Also wird das ganze nur durch ein extra ZIL-Mirror nur schneller weil er parallel in die ZIL schreiben kann, unabhängig vom restlichen Pool? Aber dann leuchtet mir noch immer nicht ganz ein warum UFS das in Zusammenhang mit NFS besser macht? Der muss die Daten doch auch auf die Platte rausschreiben.

ad 4. Ahh, wunderbar. Ich hatte mich schon gewundert, denn es ist ja an sich eine recht angenehme Sache, dass der zpool direkt als Dateisystem nutzbar ist und dass die Mountpoints alle automatisch passen. Dann legen die anderen das nur in ein extra dataset um die Boot Environments zu nutzen. Leuchtet ein ;) Wieso ist / bei dir legacy?

ad 5. Ein wenig ungeschickt finde ich halt auch die Tatsache, dass nirgends in der Doku steht, dass der Cache nach /boot/zfs/ muss. Noch, dass der kopiert werden müsste wenn man per Livesystem arbeiet oder so. Es steht nur, dass ich den per cachefile den cache wo anders hin schreiben kann sollte ich ihne von extern anlegen. Das klingt nach einem deutlichen Schritt in eine übersichtlichere Richtung.

ad 7. Aber was macht das System denn wenn es das Cachefile nicht findet? Zerlegt es den zpool? Kann er den pool einfach nicht aufbauen? Oder baut er sich ggf sogar sein cache selbst neu? Kann ich ihn einfach duch ein import reparieren?

Soweit dann nochmal vielen Dank von meiner Seite.
 
Zu 2: Nehmen wir mal ein Beispiel, das macht es deutlicher. Angenommen du möchtest /usr/home/rakor freigeben, wobei jeweils jeweils /, usr/, home/ und rakor/ eigene Datasets sind. Bei NFSv3 kannst du einfach /usr/home/rakor freigeben und alles ist gut. NFSv4 muss allerdings Dateisysteme vom Rootverzeichnis des Exports aus traversieren können. Du hast nun also zwei Möglichkeiten:
- Du setzt / als NFSv4-Root und gibst /, usr/, home/ und rakor/ frei. Client können dann natürlich all diese Verzeichnisse zumindest lesen.
- Du setzt /usr/home/rakor als NFSv4-Root und gibst nur /usr/home/rakor frei. Clients mounten dann "mount -t nfs -o nfsv4 server:/ /mnt" und haben /usr/home/rakor eingehängt. Du kannst dann aber kein anderes Verzeichnis mehr freigeben, was nicht unter /usr/home/rakor liegt. Also zum Beispiel /usr/home/yamagi ginge nicht.
Das ist eine Einschränkung des NFSv4-Protokolls, ZFS kann da nichts für. Bei UFS ist es nur nicht notwendig, da das System intern jeden UFS-Mount getrennt betrachtet.

Zu 3: Das sind die Softupdates. Alle relevanten Netzwerkdateisysteme schreiben synchron, also "operation -> sync -> operation -> sync -> operation -> etc.". Sehr simpel gesagt muss das Dateisystem bei jedem Sync sicherstellen, dass die vorherigen Operationen jedes folgendes Desaster überleben. Bei ZFS bedeutet es, dass er die laufende Arbeit unterbrechen muss, alle im Flug befindenden Operationen sortieren und in die ZIL schreiben. Liegt die ZIL im Pool auf langsamen Festplatten, muss erstmal der Schreibkopf schwenken, dann folgt eine Reihe synchroner Schreiboperationen und schließlich geht es weiter. Weil eine Platte nur ~150 Operationen pro Sekunde schafft, das Netzwerkdateisystem aber meist viel mehr "sync" generiert, wird die Platte zum Flaschenhals. Bei UFS löst das "sync" nur ein Ausschreiben der Softupdates-Puffer auf die Platte aus, was eine deutlich schnellere Operation ist.

zu 4: / usr bei mir "legacy", damit der Kernel das Rootdateisystem per vfs.kern.mountroot mounten kann, ohne dass mir die später laufende ZFS-Automagie dazwischenfunkt.

zu 7: Kommt drauf an. Der Pool ist dann als importiert markiert, kann aber mangels Cache nicht importiert werden. Für einen normalen Pool hilft ein "zpool import -f", also ein Erzwingen des Imports. Er baut dann einen neuen Cache. Beim Root-Pool mit / ist es eklig, weil das System ohne Cache sein / nicht mounten kann. Da muss man dann mit einer Live-CD bei, den Pool importieren und den Cache durch die Gegend kopieren.

EDIT: Die Erklärung zur ZIL ist wirklich extrem vereinfacht. Aber es halbwegs akkurat hinzubekommen, würde einiges an Text bedeuten. Es gibt von Sun einige schöne PDF, die die Interna von ZFS komplett aufdröseln. Wenn man daran Interesse hat.
 
Zuletzt bearbeitet:
Kann man nicht von beliebiger Stelle des Systems nullfs Mounts machen und als eigenes root freigeben?
 
Super Yamagi danke.

Dabei bleibt nur noch eine Frage zu dem / als legacy. Ich habe das bisher sonst nirgends gelesen. Bzw. anders ausgedrückt überall wo ich bisher legacy gelesen habe wurde per fstab gemounted. Ist das ein spezielles Problem bei dir oder ist es allgemein hin sinnvoll/notwendig / als legacy zu markieren?
 
Moin Yamagi,

danke für die interessanten Ausführungen. Ich wünschte, ich hätte auch dieses Wissen :)
Eine Frage zu den Cache-File(s) habe ich aber dennoch. Wenn ich die im FreeBSD.org-Wiki beschriebe Anleitung ( https://wiki.freebsd.org/RootOnZFS/GPTZFSBoot/9.0-RELEASE ) durchgehe, dann lese ich da aber nix vom Kopieren von Cache-Files.
Hängt es davon ab, wie man die Installation durchführt: mit BSDInstaller oder vollständig manuelle Methode? Das Kopieren der Datei wird immer nur in solchen Anleitungen beschrieben, die eine BSDInstaller-freie Installation durchführen.
Falls das bei der oben genannten Anleitung vergessen wurde zu beschreiben, wie sähe das Kommando aus?

Ich möchte mein Notebook umstellen auf FreeBSD mit ZFS-only und bin gerade in der Lern- und Vorbereitungsphase :)

Viele Grüße und danke für die Antworten.

JueDan
 
@Kamikaze:
Erst mit 9-STABLE, da nullfs vorher nicht wirklich nfs-komaptibel ist. Er nutzt dort nach jedem Mount unterschiedliche Identifier, was NFSv4 nachhaltig verwirrt.

@Rakor:
Das war lange ein allgemeines Problem. Der Kernel muss sein / manuell mounten, da die ZFS Mount-Magie erst später (durch /etc/rc.d/zfs) läuft. Das war nur möglich, wenn das / auf "legacy" war. Inzwischen ist es nicht mehr so. Wenn du allerdings keine Boot Environments willst, "legacy" nach wie vor keine schlechte Wahl, da du damit halt volle Kontrolle hast und sicher sein kannst, dass sich jede Automagie heraushält.
 
@Juedan:
Auch wenn der Wiki-Artikel sagt, dass er sich auf 9.0 bezieht, ist dort vorgestellte Methode eindeutig für 9-STABLE gedacht. Die Cache-File wird seit einer Änderung im Februar im Artikel nicht mehr erwähnt:
Code:
Fix so that the default instructions does not install data directly to the zroot pool. Simplify instructions regarding cache files, they are no longer needed. Fixes and cleanups.
Ich gebe zu, dass ich in der letzten Zeit etwas den Überblick verloren habe, welche ZFS-Änderungen wann in welche Branch eingegangen sind. Ich bin mir allerdings sicher, dass die neue Root-Mount-Magie ohne Cache-File nicht in 9.1 ist.
 
Danke für die Antwort.

Wenn ich am Ende folgendes mache
Code:
# cd /
# zpool export zroot
# zpool import -o altroot=/tmp/zroot -o cachefile=/tmp/zpool.cache zroot
# cd /tmp/zroot/boot/zfs
# cp /tmp/zpool.cache .
# cd /

ist alles fit und FreeBSD rennt dann nach einem Boot wie gewohnt.

JueDan
 
Zurück
Oben