Dateisystem zfs (ZoL = ZFS on Linux)
zfs ist ein von Solaris kommendes Dateisystem, das einige Vorzüge in sich vereint, u.a.:
- Copy-on-Write / Journalling
- Prüfsummen über Datenblöcke (kann dadurch selbst entscheiden, ob bzw. welche Daten korrekt sind)
- RAID-Funktionen: mirror (RAID1), raid-z1 (RAID5), raid-z2 (RAID6)
- Kompression
- Verschlüsselung (nur in relativ neuen Releases von ZoL, z.B. auf Debian 11)
- Snapshots
- Deduplikation (Vorsicht: braucht viel RAM!)
- LVM-artige Funktionen
Vorteile im RAID-Betrieb
- wenn Daten auf einem Datenträger z.B. eines Mirrors korrupt sind, weiss ZFS, welche korrupt und welche ok sind durch die Prüfsummen und muss sich nicht auf Fehlermeldungen der HDDs/SSDs verlassen. Bei einem "Scrub" koennen korrupte Blöcke gefunden und korrigiert neu geschrieben werden (gut gegen "bit rot").
- wenn ein Datentraeger getauscht werden muss, weiss zfs, welche Blöcke wirklich benutzt sind und muss nur diese neu synchronisieren (nicht den leeren Platz)
- kein HW-RAID-Controller + zugehörige hersteller-spezifische SW-Tools notwendig
Linux-Distributionen, die ZoL unterstützen
- Ubuntu (experimentell, seit 16.04. seit 20.04 im Desktop-Installer)
Debian (seit "BullsEye" 11, siehe zfs-dkms "contrib" Package)
- Proxmox VE (und im Gegensatz zu md-RAID wird ZFS-mirror auch von den Entwicklern supported)
Tipps
Partitionierung
- macht Euch 2GB große /boot-Partition(en) - 500MB reichen definitiv nicht!
- es sieht so aus, als ob Ubuntu 20.04 für /boot einen separaten "bpool" haben will ("/" u.a. == rpool).
- /boot separat, weil: grub kann nicht alle zfs-Features. encrypted root-fs geht ohne auch nicht.
- die ca. 8MB GPT-Partition 9 "Solaris reserved" ganz hinten auf der Disk hat wohl historische Gründe und wird von Linux nicht benutzt
Fehlererkennung
- scrub sollte regelmäßig (z.B. sonntags) laufen, so dass kleinere Fehler automatisch korrigiert und größere Probleme früh erkannt werden
Boot-Problem: rpool kann nicht importiert werden
Tritt gerne nach Upgrade auf 20.04 auf.
Man landet dann auf dem initramfs-Prompt. Probiert man dort zpool import, kommt ein Hinweis, dass das Filesystem woanders importiert ist.
Wenn man sich sicher ist, dass das nicht der Fall ist, kann man via zpool import -f rpool es forcieren.
Boot-Problem: /var/cache kann nicht gemounted werden
Tritt oft direkt nach o.g. Problem auf. Ursache ist, dass das Verzeichnis /var/cache nicht leer ist und sich zfs daher weigert darauf zu mounten.
Lösungen:
- erstmal schauen, was da drin liegt. Da es ein Cache ist, ist es normalerweise nicht wichtig und kann gelöscht werden.
- falls es immer wieder kommt, kann man per zfs-Option "overlay=on" auch einstellen, dass auch auf nicht-leere Verzeichnisse gemountet wird
Speicherverwaltungs-Konflikte?
Ich habe es schon erlebt, dass zfs irgendwie instabil war.
Man hatte den Eindruck, dass sich zfs und Linux sich um's RAM schlagen und es dabei manchmal nur Verlierer gibt.
Abhilfe: Speicherverbrauch von ZFS limitieren, z.B. auf 8GB:
# /etc/modprobe.d/zfs.conf options zfs zfs_arc_max=8589934592
Danach (wenn man zfs als root-Filesystem hat):
update-initramfs -u
Wichtige Kommandos
Mirror / RAID / Pool - Status checken
zpool status
Snapshot erstellen
Kann man z.B. vor größeren Änderungen (wie Upgrades) machen:
zfs snapshot -r rpool@before-upgrade-to-xxxx
Mirror: Datenträger ersetzen
# falls zu entfernender DT noch im Pool ist: zpool detach rpool /dev/disk/by-id/<bad-disk>-partN # dann neuen/leeren DT identisch partitionieren wie vorhandenen DT mit Daten # Spiegel neu zusammenbauen: zpool attach rpool /dev/disk/by-id/<existing-disk-with-data>-partN /dev/disk/by-id/<new-disk-empty>-partN # danach sollte es alle benutzten Datenblöcke auf die leere Disk-Partition kopieren "resilvering"... zpool status
Mirror erzeugen aus einzelnem Datenträger
# leere GPT-Partitiontable auf neuem/leeren DT anlegen, z.B. mit fdisk # Spiegel erzeugen (wenn man die ganzen Disks angibt, macht es auf der neuen eine entspr. Partitionierung): zpool attach rpool /dev/disk/by-id/<existing-disk-with-data> /dev/disk/by-id/<new-disk-empty> # danach sollte es alle benutzten Datenblöcke auf den leeren DT kopieren "resilvering"... zpool status
Verschlüsselung
Kombination von Verschlüsselung mit ZFS-Kompression und/oder ZFS-Deduplikation ist potentiell problematisch.
Platzbedarf: ein ansonsten minimales Debian 11 rootfs mit zfs-dkms (und dessen Abhängigkeiten) hat ca. 1.5GB belegten Platz.
zpool create rpool mirror /dev/disk/by-id/<disk1>-partN /dev/disk/by-id/<disk2>-partN zpool set feature@encryption=enabled rpool zfs create -o encryption=aes-256-ccm -o keyformat=passphrase rpool/ccm zfs create -o encryption=aes-256-gcm -o keyformat=passphrase rpool/gcm # aes-256-gcm is default in OpenZFS >= 0.8.4 zfs create -o encryption=off rpool/none
gcm war in meinen Versuchen beim Lesen ca. doppelt so schnell wie ccm. Beim Schreiben war die Geschwindigkeit ähnlich.
Test-Umgebung: Virtualbox VM auf Xeon E5-2667v2 Workstation (HW mit AES-NI).
zfs get encryption # verschluesselung checken, aktiv? modus? zfs mount -a -l # alle FSe mounten, inkl. verschlüsselte zfs umount -a # alle FSe umounten - Vorsicht: danach ist key immer noch im RAM geladen! zfs unload-key -a # alle Keys aus dem RAM entladen.
Swap auf ZVOL
Es ist unklar, ob swappen auf ZVOL zu Lockups führen kann. Wenn man es leicht vermeiden kann, sollte man ggf. lieber auf eine separate Partition oder ein MD-Device swappen.
Falls man es riskieren will, dann ungefähr so:
zfs create -V 2G -b $(getconf PAGESIZE) -o logbias=throughput -o sync=always -o primarycache=metadata -o secondarycache=none -o com.sun:auto-snapshot=false -o compression=zle rpool/encrypted/swap mkswap -f /dev/zvol/rpool/encrypted/swap echo "/dev/zvol/rpool/encrypted/swap none swap discard 0 0" >> /etc/fstab.
SLOG
Wenn man zusätzlich zu den (langsamen) Devices (z.B. HDDs oder SATA SSDs) noch deutlich schnellere hat (z.B. PCIe SSDs oder Optane [letzteres besser wegen niedriger Latency und hoher Write Endurance]) und synchrone Schreibzugriffe beschleunigen will, kann man ein SLOG auf den schnellen Devices machen.
Größe: maximum_ingress_rate * txg_intervall, z.B. : 1 Gbit/s Ethernet-Verbindung: 110 MB/s * 30 s == 3.3 GB plus 20% Sicherheitsabstand: 4GB SLOG.
Mirrored SLOG, um Crash Recovery nicht zu gefährden, falls ein Device stirbt.
Da dort potentiell viel geschrieben wird, ist eine entsprechend hohe Write Endurance ratsam: Optane > Enterprise SSDs.
zpool add hddpool log mirror /dev/disk/by-id/<disk1>-partN /dev/disk/by-id/<disk2>-partN
L2ARC
Zusätzlich zum ARC (im RAM) kann man noch ein L2ARC auf einem schnellen Device hinzufügen.
Striped L2ARC, der Pool wird nicht beschädigt, wenn L2ARC verloren geht.
zpool add hddpool cache /dev/disk/by-id/<disk1>-partN /dev/disk/by-id/<disk2>-partN
Per default ist der L2ARC nicht persistent (geht also beim reboot verloren) - seit OpenZFS 2.0 wird aber auch persistent l2arc angeboten:
# /etc/modprobe.d/zfs.conf: options zfs l2arc_rebuild_enabled=1