ZFS auf Linux ("ZFS on Linux")

ZFS ist ein von Sun Microsystems entwickeltes transaktionales Dateisystem, das zahlreiche Erweiterungen für die Verwendung im Server- und Rechenzentrumsbereich enthält. Hierzu zählen die vergleichsweise große maximale Dateisystemgröße, eine einfache Verwaltung selbst komplexer Konfigurationen, die integrierten RAID-Funktionalitäten, das Volume-Management sowie der prüfsummenbasierte Schutz vor Datenübertragungsfehlern. Der Name ZFS stand ursprünglich für Zettabyte File System.

Eine direkte Unterstützung innerhalb des Linux-Kernels ist aus Lizenzgründen problematisch (Inkompatibilität von GPLv2 und CDDL), daher gibt es momentan keine direkt in die Kernelsourcen integrierte Linux-Implementierung. Allerdings gibt es:

  • das Projekt ZFS on FUSE, das ZFS auch unter Linux nutzbar macht. Die Implementierung im Userspace hat verschiedene Nachteile, unter anderem einen verminderten Datendurchsatz.
  • Ein alternativer Lösungsansatz namens ZFS on Linux, bei dem die nötigen Kernel-Module außerhalb des Kernel-Quellbaums gepflegt werden, ist nach Aussagen der Entwickler seit der im April 2013 veröffentlichen Version 0.6.1 reif für den produktiven Einsatz.

Quelle: Wikipedia.

Enthaltene Versionen von ZFS on Linux in den Distributionen

Ubuntu

ab 15.10:

apt install zfsutils-linux

Ältere Versionen siehe hier.

CentOS7

Install zfs-release package:

yum localinstall --nogpgcheck http://archive.zfsonlinux.org/epel/zfs-release.el7.noarch.rpm
yum-config-manager --enable "zfs"
yum install zfs
modprobe zfs

ZFS Virtual Devices (ZFS VDEVs) sind meta-Devices die aus den u.g. Geräten bestehen kann. VDEVs werden dynamisch erzeugt, devices/Geräte können hinzugefügt, aber nicht entfernt werden.

Bezeichnung Bedeutung
File Dateien auf anderen Dateisystemen die als Quelle dienen
Physical Drive physikalisches Gerät (HDD, SDD, PCIe NVME, usw.)
Mirror a standard RAID1 mirror
ZFS software raidz1, raidz2, raidz3 'distributed' parity based RAID
Hot Spare hot spare for ZFS software raid.
Cache a device for level 2 adaptive read cache (ZFS L2ARC)
Log ZFS Intent Log (ZFS ZIL)

ZFS Pools: bestehen aus einem oder mehreren VDEVS, auf einem Pool können ZFS-Dateisysteme erzeugt werden.

ZFS Dataset Types - es gibt drei Typen:

  • filesystem: Dateisystem und Clones
  • snapshot: Snapshots 1)
  • volume: ein blockdevice was unter /dev/zvol/$Poolname/$Volumename auftaucht. Das Volume hat ein fixe Größe, je nach Implementierung kann es auch direkt von zfs oder indirekt als iSCSI target exportiert werden. Weitere Informationen finden sich in der Doku zu ZFS Volumes

Der folgende Befehl listet die vorhandenen Typen auf:

zfs list -o name,type,mountpoint
NAME       TYPE        MOUNTPOINT
pool1      filesystem  /pool1
pool1/fs1  volume      -
pool1/fs2  filesystem  /pool1/fs2
  1. import Fehler nach reboots (insbesondere bei mehreren pools): Es sollten immer /dev/disk/by-id/* Aliases benutzt werden
  2. zfs als root-Dateisystem erfordert einige Anpassungen: https://github.com/zfsonlinux/zfs/wiki/Ubuntu-18.04-Root-on-ZFS
  3. race conditions mit anderen daemons beim mounten aufgrund fehlender systemd.mount integration: https://github.com/zfsonlinux/zfs/issues/4898 https://github.com/zfsonlinux/zfs/pull/7329
  4. Geräte (top-level VDEV) können erst mit Solaris 11.4 entfernt werden https://docs.oracle.com/cd/E37838_01/html/E61017/remove-devices.html

Pools

siehe auch: man zpool

RAID optionen

  • Striped VDEVS („Raid 0“)
    sudo zpool create samsung-stripe /dev/disk/by-id/DISK1 /dev/DISK2
  • Mirrored VDEVs („Raid 1“)
    sudo zpool create samsung-mirror mirror /dev/DISK1 /dev/DISK2
  • Striped Mirrored VDEVs („RAID10“, einen stripe über zwei mirrored pools):
    sudo zpool create meinStripedMirroredPool mirror /dev/DISK1 /dev/disk/DISK2 mirror /dev/DISK3 /dev/DISK4

    oder

    sudo zpool create meinStripedMirroredPool mirror /dev/DISK1 /dev/DISK2
    sudo zpool add meinStripedMirroredPool mirror /dev/DISK3 /dev/DISK4
  • RAIDZ („Raid 5“, verkraftet den Ausfall eines VDEVs):
    sudo zpool create meinRAIDZ raidz /dev/DISK1 /dev/DISK2 /dev/DISK3
  • RAIDZ2 („RAID6“, verkraftet den Ausfall zweier VDEVs):
    sudo zpool create meinRAIDZ2 raidz2 /dev/DISK1 /dev/DISK2 /dev/DISK3 /dev/DISK4
  • RAIDZ3 (verkraftet den Ausfall dreier VDEVs):
    sudo zpool create meinRAIDZ3 raidz3 /dev/DISK1 /dev/DISK2 /dev/DISK3 /dev/DISK4 /dev/DISK5
  • verschachteltes „Nested“ RAIDZ („RAID50“, „RAID60“)
    sudo zpool create meinNestedRAIDZ raidz /dev/DISK1 /dev/DISK2 /dev/DISK3 /dev/DISK4
    sudo zpool add example raidz /dev/DISK5 /dev/DISK6 /dev/DISK7 /dev/DISK8

pool anlegen

pool aus VDEVs anlegen:

sudo zpool create single-DISK /dev/disk/by-id/DISK1

pools auflisten

zpool list

pool zerstören

sudo zpool destroy $Poolname

Pools erweitern

Vorbereitung:

  • Alte Partitionen und Dateisystemsignaturen löschen:
    wipefs /dev/DISK2
  • neue GPT-Signatur erzeugen:
    parted /dev/DISK2 mklabel gpt
sudo zpool add $Poolname /dev/DISK2 -f

ZFS Pool Scrubbing

Scrubbing starten (Fortschritt beobachten mit -v):

zpool scrub $Poolname

Diskaustausch

Wenn der scrub Fehler gezeigt hat (zpool status)

zpool detach mypool /dev/BADDISK
zpool attach mypool /dev/GOODDISK /dev/BADDISK  -f

ZFS Intent Logs

ZFS Intent Logs

sudo zpool add meinPool log /dev/DISK1 -f

ZFS Cache Drives

ZFS Cache Drives bieten eine extra caching-Schicht zwischen Arbeitsspeicher und Speichergerät, vor allem für zufällige Lesezugriffe vorrangig statischer Daten.

sudo zpool add meinPool cache /dev/DISK1 -f

ZFS Dateisysteme

Jeder Pool kann 2^64 ZFS-Dateisysteme enthalten.

erzeugen

sudo zfs create meinPool/FS1
sudo zfs create meinPool/FS2

Die Größe wird über Quota festgelegt. Der Parameter -V $Große erzeugt ein Volume mit der angegebenen Größe, ist also kein Dateisystem mehr.

mounten

  • Bei der Erstellung werden ZFS-Dateisysteme automatisch eingehangen.
  • Die Eigenschaften übergeordneter Dateisystem werden vererbt.
  • Standardmäßig wird nur in leere Verzeichnisse gemounted, der Parameter -O ändert das

Automatische Einhängepunkte:

  • zfs list die aktuellen mountpoint auf
  • abfragen geht auch:
    zfs get mountpoint meinPool/FS1
  • Property mounted:
    zfs get mounted meinPool/FS1

Auf Anforderung:

  • wenn die Eigenschaft canmount auf off steht, ist die Eigeschaft mountpoint leer (und zfs mount bzw. zfs mount -a funktionieren nicht).
  • bei canmount auf noauto können diese nur explizit eingehangen werden

Legacy-Einhängepunkte

zfs set mountpoint=legacy meinPool/FS1
  • ZFS-Dateisysteme können nur mit Legacy-Dienstprogrammen verwaltet werden (indem Sie die Eigenschaft „mountpoint“ auf „legacy“ setzen)
  • dann sind die Befehle mount und umount sowie die Datei /etc/vfstab relevant.
  • ZFS hängt Legacy-Dateisysteme beim Systemstart nicht automatisch ein
  • die ZFS-Befehle zfs mount und zfs umount funktionieren nicht
ZFS-Property mount Option
atime atime/noatime
devices devices/nodevices
exec exec/noexec
nbmand nbmand/nonbmand
readonly ro/rw
setuid setuid/nosetuid
xattr xattr/noaxttr

Die mount Option nosuid ist ein Alias für nodevices,nosetuid.

löschen

sudo zfs destroy meinPool/FS1

Eigenschaften festlegen

Beispiel Quota:

sudo zfs set quota=10G meinPool/FS1

Kompression2):

compression=on
compression=lz4

ZFS Snapshots

  • Snapshot erstellen ( meinPool/FS1 Name des snapshots „snapshot1“):
    zfs snapshot -r meinPool/FS1@snapshot1
  • Snapshots auflisten:
    • …alle:
      zfs list -t snapshot
    • Standardmäßig mit auflisten:
      zpool set listsnapshots=on rpool
    • …geordnet nach Name und Erstellungszeit:
      zfs list -t snapshot -o name,creation -s creation
    • …nur für FS1 (ebenfalls geordnet nach Name und Erstellungszeit):
      zfs list -t snapshot -o name,creation -s creation | grep FS1
  • rollback des Dateisystems „meinPool/FS1“ auf den Snapshot „snapshot1“ (-r ist nötig wenn neuere snapshots/bookmarks existieren):
    zfs rollback -r meinPool/FS1@snapshot1
  • Snapshot löschen:
    zfs destroy meinPool/FS1@snapshot1
  • Snapshots mounten (read-only):
    • im normalen mountverzeichnis gibt es den unsichtbaren Ordner .zfs. Auch wenn dieser Ordner auch mit ls -la nicht sichtbar ist, so kann dennoch hinein gewechselt werden. Dieses Verhalten ist praktisch damit tools wie rsync nicht versehentlich snapshots mitkopieren. Falls es notwendig sein sollte den .zfs-Ordner immer mit anzuzeigen, kann dies über die folgende property aktiviert werden:
      zfs set snapdir=visible meinPool/FS1
    • legacy mount:
      mount -t zfs meinPool/FS1@snapshot1 /media/snapshot
  • Snapshot diff: Unterschiede zwischen den Snapshots anzeigen: zfs diff meinPool/FS1@snapshot1 meinPool/FS1@snapshot2
  • inkrementelle Snapshots (nur Änderungen zwischen Snapshots werden übertragen), Beispiel (Quellhost mit meinPool und Snapshots snap1,2,… sollen übertragen werden zum entfernten Rechner mit SSH-Login root$Zielhost mit Pool meinBACKUPPool):
    • initial übertragen:
      zfs send meinPool/FS1@snap1 | ssh root@$Zielhost zfs recv meinBACKUPPool/FS1
    • Datei mit 1G erstellen:
      dd if=/dev/zero bs=1024000 count=1024 >> /meinPool/FS1/test2
    • Snapshot anlegen:
      zfs snapshot -r meinPool/FS1@snap2
    • Snapshot inkrementell senden (lt. ifconfig werden 1G übertragen):
      zfs send -i meinPool/FS1@snap1 meinPool/FS1@snap2 | ssh root$Zielhost zfs recv meinBACKUPPool/FS1
Snapshot Belegungsberechnung
NAME                  AVAIL USED   USEDSNAP  USEDDS  USEDREFRESERV  USEDCHILD                                                                                                                                                                                                     
meinPool              550G  27,2G        0B     24K             0B      27,2G                                                                                                                                                                                                     
meinPool/FS1          253G  27,1G     3,46G   23,7G             0B         0B                                                                                                                                                                                                     
meinPool/FS1@snap1       -   153K         -       -              -          -                                                                                                                                                                                                     
meinPool/FS1@snap2       -   150K         -       -              -          -
Spalte Bedeutung
NAME Name des Elements
AVAIL freier Speicherplatz
USED Speicherplatz belegt
USEDSNAP Speicherplatz belegt vom Snapshot
USEDDS Speicherplatz belegt vom dataset selbst
USEDREFRESERV belegt von einer ref-reservation
USEDCHILD belegt von einem „children“ des data sets

Links:

ZFS Clones

Ein ZFS clone ist eine schreibbare Kopie eines Snapshots. Der Snapshot kann so lange nicht gelöscht werden wie der Clone besteht.

zfs snapshot -r meinPool/FS1@snapshot1
zfs clone meinPool/FS1@snapshot1 meinPool/FS2

ZFS Send and Receive

  • Senden:
    zfs send meinPool/FS1 > /backup-snap.zfs
  • Empfangen:
    zfs receive -F meinPool/FS1-Kopie < /backup-snap.zfs

Um über Netzwerk zu senden muss die Ausgabe per pipe an ein entferntes System senden:

  • Senden:
    sudo zfs send meinPool/FS1@snap1 | ssh $remoteServer zfs recv remotePool/remoteFS1

ZFS Ditto Blocks

zfs set copies=3 meinPool/FS1

1)
Momentaufnahmen von Dateisystem
2)
die effektive Kompressionsrate gibt der folgende Befehl aus:
zfs get compressratio [$Pool/$FS]
je höher der Wert über 1.00x liegt desto besser die Kompression