21x9.org | System Administration | Home Automation | Smart Home
11.07.2023

ZFS

ZFS1 ist ein sehr mächtiges Dateisystem. Es wurde ursprünglich für BSD2-Systeme entwickelt, kann aber auch unter Linux problemlos genutzt werden. ZFS unterstützt nativ Verschlüsselung, Snapshots3 und verschiedene RAID4-Funktionen. Snapshots frieren quasi den Zustand eines ZFS-Volumes ein und man kann diesen Zustand zu einem späteren Zeitpunkt wiederherstellen. Dies ist z.B. vor größeren Updates einer Software praktisch. Auch Backups können mittels Snapshots sicherer erstellt werden, da sich die Daten in einem Snapshot nicht mehr verändern. Die RAID-Funktionen von ZFS erhöhen, je nach gewähltem Typ, die Datensicherheit und/oder die Geschwindigkeit der genutzten Datenträger.

Die Installation erfolgt mittels:

apt install zfs-dkms zfsutils-linux

Sollte zfs-dkms nicht gefunden werden, muss das Debian contrib Repo hinzugefügt werden.

Nach der Installation kann ein sog. Pool5 erzeugt werden:

zpool create tank mirror ata-Samsung_SSD_860_EVO_250GB_S4CJNF0M921306M ata-Samsung_SSD_860_EVO_250GB_S4CJNF0M921370X

Hier wird ein Mirror (also RAID1) mit zwei Festplatten angelegt. Die IDs der Platten können mittels ls -lah /dev/disk/by-id/ ermittelt werden.

Als nächstes erzeugen wir ein Kennwort für die Festplattenverschlüsselung und legen dieses in einer Datei ab:

pwgen -1 500 > /root/zfs_cryptkey
chmod 600 /root/zfs_cryptkey

Die Datei /root/zfs_cryptkey sollte gut gesichert werden, bestenfalls in einem Passworttresor oder ähnlichem. Verlieren wir diese Datei, können wir nicht mehr auf die auf unseren ZFS-Volumes gespeicherten Daten zugreifen. Es gibt keine Recoverymöglichkeit (außer ein entsprechendes Daten-Backup natürlich).

Nun können wir innerhalb des Pools unsere Laufwerke anlegen:

zfs create -o encryption=on -o keyformat=passphrase -o keylocation=file:///root/zfs_cryptkey tank/data
zfs create -o mountpoint=/docker/gitea tank/data/gitea

Zunächst erzeugen wir einen verschlüsselten Container, ohne Mountpoint. Innerhalb davon legen wir dann unsere eigentlichen Laufwerke an. Die Verschlüsselungseinstellungen des übergeordneten Containers werden hierbei übernommen. Genau aus diesem Grund ist ein übergeordnetes Element auch praktisch, notwendig ist es aber nicht zwingend. Durch die Angabe der Mountpoints werden die Laufwerke automatisch ins System eingebunden und stehen sofort zur Nutzung bereit. gitea ist hier natürlich nur als Beispiel zu verstehen. Ich lege gern ein Volume pro Docker-Container an, dies erleichtert später die Nutzung von Snapshots.

Legen wir noch ein paar Laufwerke an, diese ohne übergeordnetes Element:

zfs create -o encryption=on -o encryption=aes-256-gcm -o keyformat=passphrase -o keylocation=file:///root/zfs_cryptkey -mountpoint=/var/www tank/www
zfs create -o encryption=on -o encryption=aes-256-gcm -o keyformat=passphrase -o keylocation=file:///root/zfs_cryptkey -mountpoint=/opt tank/opt
zfs create -o encryption=on -o encryption=aes-256-gcm -o keyformat=passphrase -o keylocation=file:///root/zfs_cryptkey -mountpoint=/var/lib/docker tank/docker

Achtung: /var/lib/docker wird ggf. von Docker genutzt. In diesem Fall sollte Docker zunächst gestoppt und die Daten in /var/lib/docker in ein temporäres Verzeichnis verschoben werden. Nachdem das ZFS Volume erzeugt und gemoutet wurde, kann man dann die Daten wieder dorthin verschieben und Docker wieder starten.

Der Status des Pools lässt sich mittels zpool status abfragen:

  pool: tank
 state: ONLINE
  scan: scrub repaired 0B in 00:05:22 with 0 errors on Sun Dec 11 00:29:23 2022
config:

        NAME                                               STATE     READ WRITE CKSUM
        tank                                               ONLINE       0     0     0
          mirror-0                                         ONLINE       0     0     0
            ata-Samsung_SSD_860_EVO_250GB_S4CJNF0M921306M  ONLINE       0     0     0
            ata-Samsung_SSD_860_EVO_250GB_S4CJNF0M921370X  ONLINE       0     0     0

errors: No known data errors

Um uns automatisch über den Zustand unseres ZFS informieren zu lassen, können wir zed6 nutzen:

apt install zfs-zed

In die zed Konfiguration nehmen wir nun unsere Mailadresse auf:

##  
# zed.rc  
#  
# This file should be owned by root and permissioned 0600.  
##  

##  
# Absolute path to the debug output file.  
#  
#ZED_DEBUG_LOG="/tmp/zed.debug.log"  

##  
# Email address of the zpool administrator for receipt of notifications;  
# multiple addresses can be specified if they are delimited by whitespace.  
# Email will only be sent if ZED_EMAIL_ADDR is defined.  
# Disabled by default; uncomment to enable.  
#  
ZED_EMAIL_ADDR="root@example.org"  

##  
# Name or path of executable responsible for sending notifications via email;  
# the mail program must be capable of reading a message body from stdin.  
# Email will only be sent if ZED_EMAIL_ADDR is defined.  
#  
ZED_EMAIL_PROG="mail"  

##  
# Command-line options for ZED_EMAIL_PROG.  
# The string @ADDRESS@ will be replaced with the recipient email address(es).  
# The string @SUBJECT@ will be replaced with the notification subject;  
# this should be protected with quotes to prevent word-splitting.  
# Email will only be sent if ZED_EMAIL_ADDR is defined.  
#  
ZED_EMAIL_OPTS="-s '@SUBJECT@' @ADDRESS@"  

##  
# Default directory for zed lock files.  
#  
#ZED_LOCKDIR="/var/lock"  

##  
# Minimum number of seconds between notifications for a similar event.  
#  
ZED_NOTIFY_INTERVAL_SECS=3600  

##  
# Notification verbosity.  
# If set to 0, suppress notification if the pool is healthy.  
# If set to 1, send notification regardless of pool health.  
#  
ZED_NOTIFY_VERBOSE=1  

##  
# Send notifications for 'ereport.fs.zfs.data' events.  
# Disabled by default, any non-empty value will enable the feature.  
#  
#ZED_NOTIFY_DATA=  

##  
# Pushbullet access token.  
# This grants full access to your account -- protect it accordingly!  
# <https://www.pushbullet.com/get-started>  
# <https://www.pushbullet.com/account>  
# Disabled by default; uncomment to enable.  
#  
#ZED_PUSHBULLET_ACCESS_TOKEN=""  

##  
# Pushbullet channel tag for push notification feeds that can be subscribed to.  
# <https://www.pushbullet.com/my-channel>  
# If not defined, push notifications will instead be sent to all devices  
# associated with the account specified by the access token.  
# Disabled by default; uncomment to enable.  
#  
#ZED_PUSHBULLET_CHANNEL_TAG=""  

##  
# Slack Webhook URL.  
# This allows posting to the given channel and includes an access token.  
# <https://api.slack.com/incoming-webhooks>  
# Disabled by default; uncomment to enable.  
#  
#ZED_SLACK_WEBHOOK_URL=""  

##  
# Default directory for zed state files.  
#  
#ZED_RUNDIR="/var/run"  

##  
# Turn on/off enclosure LEDs when drives get DEGRADED/FAULTED. This works for  
# device mapper and multipath devices as well. Your enclosure must be  
# supported by the Linux SES driver for this to work.  
#  
ZED_USE_ENCLOSURE_LEDS=0  

##  
# Run a scrub after every resilver  
# Disabled by default, 1 to enable and 0 to disable.  
#ZED_SCRUB_AFTER_RESILVER=0  

##  
# The syslog priority (e.g., specified as a "facility.level" pair).  
#  
ZED_SYSLOG_PRIORITY="daemon.notice"  

##  
# The syslog tag for marking zed events.  
#  
ZED_SYSLOG_TAG="zed"  

##  
# Which set of event subclasses to log  
# By default, events from all subclasses are logged.  
# If ZED_SYSLOG_SUBCLASS_INCLUDE is set, only subclasses  
# matching the pattern are logged. Use the pipe symbol (|)  
# or shell wildcards (*, ?) to match multiple subclasses.  
# Otherwise, if ZED_SYSLOG_SUBCLASS_EXCLUDE is set, the  
# matching subclasses are excluded from logging.  
#ZED_SYSLOG_SUBCLASS_INCLUDE="checksum|scrub_*|vdev.*"  
ZED_SYSLOG_SUBCLASS_EXCLUDE="history_event"  

##  
# Use GUIDs instead of names when logging pool and vdevs  
# Disabled by default, 1 to enable and 0 to disable.  
#ZED_SYSLOG_DISPLAY_GUIDS=1

Anschließend starten wir zed neu:

/etc/init.d/zfs-zed restart

Außerdem fügen wir ein paar Housekeeping-Job in unsere Crontab7 hinzu:

0 2 1 * * /sbin/zpool scrub tank 2>&1 | mail -s "Scrub status" root@example.org  
0 13 1 * * /sbin/zpool status 2>&1 | mail -s "zpool status" root@example.org  

Desweiteren bietet es sich an, regelmäßige Snapshots zu erstellen. Hierfür können wir zfsnap8 nutzen:

apt install zfsnap

Hierfür erzeugen wir noch ein kleines Shellscript:

#!/bin/bash  

volumes=$(/usr/sbin/zfs list | /usr/bin/grep 'tank/' | /usr/bin/grep -v docker | /usr/bin/awk '{print $1}')  

for x in ${volumes}; do  
    echo "${x}"  
    /usr/sbin/zfSnap -v -d -z -S -a 14d ${x}  
    echo ""  
done

echo "tank/docker"  
/usr/sbin/zfSnap -v -d -z -S -a 14d tank/docker

Das Script listet alle Volumes im Pool tank auf. Volumes mit docker im Namen werden ausgenommen, da Docker, sofern es Daten auf ZFS Dateisystemen ablegt, automatisch Volumes und Snapshot für Images erzeugt. Da wir selbst ein Volume mit dem Namen tank/docker erzeugt haben, sorgen wir im Anschluss separat noch dafür, dass auch dieser einen Snapshot erhält.

Das Script binden wir als Cronjob ein:

0 23 * * * /root/zfsnap.sh 2>&1 | mail -s "Snapshot status" root@example.org

  1. https://openzfs.github.io/openzfs-docs/index.html ↩

  2. https://de.wikipedia.org/wiki/Berkeley_Software_Distribution ↩

  3. https://de.wikipedia.org/wiki/Schnappschuss_(Informationstechnik)#In_Dateisystemen ↩

  4. https://de.wikipedia.org/wiki/RAID ↩

  5. https://openzfs.github.io/openzfs-docs/man/7/zpoolconcepts.7.html ↩

  6. https://openzfs.github.io/openzfs-docs/man/8/zed.8.html ↩

  7. https://de.wikipedia.org/wiki/Cron ↩

  8. https://github.com/zfsnap/zfsnap ↩

Tags: linux zfs

Mehr

  • Flexible, bootfähige USB-Sticks mit Ventoy
  • Backups mit Borg und ZFS/LVM Snapshots
  • Docker
  • VPN mit Wireguard (und ChatGPT)
  • SSH-Keys mit TPM

Tags

linux zfs

Archiv

  • Mar 2025 (2)
  • May 2024 (2)
  • Oct 2023 (1)
  • Aug 2023 (5)
  • Jul 2023 (31)

  • Ältere Einträge (95)

Feeds

Atom 1.0 RSS JSON
  • Datenschutz
  • Impressum
  • Archiv