Dauerhafter Schutz mit ZFS Auto Snapshots
ZFS-Snapshots in Proxmox: Aufbewahrung und Wiederherstellung
Wie wir mit ZFS Auto Snapshot ältere Datenstände erhalten und im Notfall VMs, LXC-Container und NAS-Dateien wiederherstellen.
Was ist ein ZFS-Snapshot?
Ein ZFS-Snapshot ist eine schreibgeschützte Momentaufnahme eines Dateisystems oder ZVOLs. ZFS nutzt Copy-on-Write: Änderungen werden in neue Blöcke geschrieben. Der Snapshot hält die Verweise auf die bisherigen Blöcke fest.
Es entsteht keine vollständige Datenkopie. Zusätzlichen Speicher benötigen vor allem ältere Blöcke, die nach Änderungen oder Löschungen nur noch für Snapshots erhalten bleiben. Unveränderte Blöcke werden gemeinsam genutzt.
ZFS-Snapshots und VMware-Snapshots
| Merkmal | ZFS | VMware vSphere / ESXi |
|---|---|---|
| Ebene | Dateisystem oder ZVOL | Virtuelle Maschine |
| Verfahren | Alte Datenblöcke bleiben referenziert. | Neue Schreibzugriffe landen bei klassischen Snapshots in Delta-Dateien. |
| Arbeitsspeicher | Wird nicht erfasst. | Kann optional erfasst werden. |
| Löschen | Gibt nicht mehr benötigte Blöcke frei. | Konsolidiert die Delta-Daten; der aktuelle Stand bleibt erhalten. |
Klassische VMware-Snapshots sind für kurzfristige Rückkehrpunkte gedacht; Broadcom empfiehlt höchstens 72 Stunden Aufbewahrung. Diese Empfehlung lässt sich nicht auf ZFS-Snapshots übertragen. Die VMware-Umsetzung kann je nach Speicherplattform abweichen. VMware-Empfehlungen
Unsere Snapshot-Aufbewahrung: ungefähr drei Monate
Die Crontab bestimmt die Ausführungszeitpunkte. Pro Zeitstufe behalten wir eine feste Anzahl von Snapshots:
| Intervall | Reihe | Anzahl | Ungefähres Fenster |
|---|---|---|---|
| Alle 15 Minuten | frequent |
12 | 3 Stunden |
| Stündlich | hourly |
96 | 4 Tage |
| Täglich | daily |
21 | 3 Wochen |
| Wöchentlich | weekly |
6 | 6 Wochen |
| Monatlich | monthly |
3 | 3 Monate |
Je neuer der Datenstand, desto feiner die Auswahl. Für heutige Fehler gibt es viele Rückkehrpunkte. Für spät bemerkte Fehler bleiben ältere Tages-, Wochen- und Monatsstände.
Die Fenster sind Richtwerte, keine garantierten Mindestzeiten. Die tatsächliche Reichweite hängt vom Cron-Zeitpunkt und erfolgreichen Ausführungen ab. Eine bestimmte Dateiversion ist nur wiederherstellbar, wenn mindestens ein noch vorhandener Snapshot sie erfasst hat.
Wie arbeitet ZFS Auto Snapshot?
Cron startet das Programm. Es wählt die vorgesehenen Datenbereiche aus, erstellt einen Snapshot mit Zeitstufe und Zeitstempel und entfernt ältere passende Snapshots nach der eingestellten Anzahl.
Bei der Stundenreihe bleibt beispielsweise mit --label=hourly --keep=96 nach dem Aufräumen eine Auswahl von 96 Stundenständen. Die Reihen sind unabhängig: Ein Viertelstunden-Snapshot wird nicht später zum Tages- oder Monatssnapshot umgewandelt.
Die verwendeten ZFS-Befehle
| Befehl | Aufgabe |
|---|---|
zpool status |
Poolzustand und laufende Scrubs prüfen. |
zfs list |
Datenbereiche, Auto-Snapshot-Eigenschaften und vorhandene Snapshots auslesen. |
zfs snapshot |
Neue Momentaufnahme erstellen; mit -r auch für untergeordnete Datasets. |
zfs destroy -d |
Alte Snapshots entfernen oder deren Löschung vormerken, wenn Holds oder Clones sie noch benötigen. |
zfs get |
Optional die seit dem letzten Snapshot geschriebenen Daten prüfen. |
Die Auswahl lässt sich über Eigenschaften wie com.sun:auto-snapshot und com.sun:auto-snapshot:hourly steuern. Diese Beschreibung bezieht sich auf die Linux-Implementierung von zfsonlinux/zfs-auto-snapshot.
Mit zpool list die 80-%-Grenze prüfen
Unser Betriebsziel ist, den Pool unter 80 % Belegung zu halten. Die Reserve lässt Platz für neue Daten, Snapshot-Wachstum und Änderungen an Clones. 80 % ist eine betriebliche Richtlinie, keine feste ZFS-Funktionsgrenze.
zpool list -o name,size,alloc,free,cap,health rpool
Entscheidend ist CAP: Steht dort 78%, bleibt wenig Reserve bis zu unserem Grenzwert. Bei 80% oder mehr reduzieren wir die Belegung. ALLOC zeigt den belegten, FREE den freien Poolplatz. Der tatsächlich für Datasets nutzbare Platz kann wegen Reservierungen und anderer Faktoren abweichen.
Zur Einordnung prüfen wir zusätzlich, wo Platz belegt wird:
zfs list -r -o name,used,avail,usedbysnapshots,usedbydataset rpool
zfs list -t snapshot -r -o name,used,referenced -s creation rpool
zfs list -t volume -r -o name,used,referenced,refreservation rpool
usedbysnapshots zeigt den von Snapshots gebundenen Platz eines Datasets. Snapshot-Werte dürfen nicht einfach addiert werden, da Blöcke gemeinsam genutzt werden. Bei ZVOLs prüfen wir auch refreservation, also reservierten Platz. OpenZFS: zpool list
Aufbewahrung bei Platzmangel reduzieren
In den bestehenden Cron-Aufrufen ändern wir --keep. Die Ausführungszeiten bleiben erhalten. Eine mögliche kürzere Aufbewahrung ist:
| Reihe | Bisher | Kürzeres Beispiel | Ungefähres Fenster |
|---|---|---|---|
| frequent | 12 | 8 | 2 Stunden |
| hourly | 96 | 48 | 2 Tage |
| daily | 21 | 14 | 2 Wochen |
| weekly | 6 | 4 | 4 Wochen |
| monthly | 3 | 2 | 2 Monate |
Beispiel für eine Benutzer- oder Root-Crontab; den Programmpfad gegebenenfalls anpassen. In /etc/cron.d/ steht zusätzlich nach den fünf Zeitfeldern der Benutzer root. Bestehende Aufgaben ersetzen, keine parallelen doppelten Aufgaben anlegen.
*/15 * * * * /usr/sbin/zfs-auto-snapshot --quiet --syslog --label=frequent --keep=8 //
0 * * * * /usr/sbin/zfs-auto-snapshot --quiet --syslog --label=hourly --keep=48 //
0 0 * * * /usr/sbin/zfs-auto-snapshot --quiet --syslog --label=daily --keep=14 //
0 0 * * 0 /usr/sbin/zfs-auto-snapshot --quiet --syslog --label=weekly --keep=4 //
0 0 1 * * /usr/sbin/zfs-auto-snapshot --quiet --syslog --label=monthly --keep=2 //
Die Zeitfelder sind ein Beispiel. Bei unserer Installation übernehmen wir die vorhandenen Zeiten, Dataset-Auswahl und sonstigen Optionen und ändern nur die gewünschten Aufbewahrungszahlen. Auto Snapshot räumt jede Reihe beim nächsten erfolgreichen Aufruf auf. Die Monatsreihe wird deshalb nicht sofort durch eine Änderung der Crontab verkürzt.
Für zeitnahes Aufräumen kann ein entsprechender normaler Aufruf außerhalb von Cron erfolgen: zuerst mit --dry-run prüfen, dann nach Prüfung ohne diese Option ausführen. Dieser Aufruf erstellt auch einen neuen Snapshot. Für jede betroffene Reihe ist ein eigener Aufruf nötig; er sollte nicht gleichzeitig mit dem regulären Cron-Lauf erfolgen.
# Vorschau für die Stundenreihe:
zfs-auto-snapshot --dry-run --label=hourly --keep=48 //
# Nach Prüfung: neuer Snapshot und Aufräumen der Stundenreihe
zfs-auto-snapshot --label=hourly --keep=48 //
# Anschließend Belegung erneut kontrollieren:
zpool list -o name,size,alloc,free,cap,health rpool
CAP nicht.Warum Snapshots auch bei SSD-TRIM erhalten bleiben
TRIM meldet der SSD, welche Speicherbereiche der Pool nicht mehr benötigt. Die SSD darf deren Inhalt anschließend intern verwerfen.
Blöcke, die ein Snapshot noch benötigt, bleiben für ZFS belegt und werden nicht zum Trimmen freigegeben. Eine im aktuellen Dateisystem gelöschte Datei bleibt dadurch aus einem vorhandenen Snapshot wiederherstellbar.
Erst wenn keine Referenz mehr besteht, können die Blöcke freigegeben und später getrimmt werden. Snapshot-Löschung und TRIM sind getrennte Vorgänge; Auto Snapshot führt keinen eigenen Pool-TRIM aus.
Proxmox: Rollback, Snapshot-Verzeichnis oder Clone?
Wir verwenden ZFS Auto Snapshot. Unsere Wiederherstellung erfolgt auf ZFS-Ebene; Proxmox stoppt und startet die Gäste.
| Ziel | Geeigneter Weg |
|---|---|
| Einzelne LXC- oder NAS-Dateien retten | Aus dem Snapshot-Verzeichnis herauskopieren. |
| Alten Stand untersuchen oder reparieren | Separaten beschreibbaren Clone erstellen. |
| Produktiven Speicher vollständig zurücksetzen | Gast stoppen, Rollback durchführen, Gast starten. |
Rollback einer VM oder eines LXC-Containers
Die folgenden Befehle sind Vorlagen. IDs, Speicherbereiche und Snapshot-Namen müssen zum Gast passen. Vorher wird sichergestellt, dass beispielsweise HA den Gast nicht automatisch neu startet.
VM mit ZVOL:
qm stop 100
zfs rollback rpool/data/vm-100-disk-0@SNAPSHOTNAME
# Erst nach erfolgreichem Rollback starten:
qm start 100
LXC mit Dateisystem-Dataset:
pct stop 200
zfs rollback rpool/data/subvol-200-disk-0@SNAPSHOTNAME
# Erst nach erfolgreichem Rollback starten:
pct start 200
qm stop und pct stop stoppen unmittelbar. Anwendungen werden vorher möglichst geordnet beendet. Bei mehreren Festplatten oder Datasets müssen alle benötigten Bereiche auf zusammenpassende Stände gebracht werden; erst danach startet der Gast.Ohne Zusatzoption erlaubt ZFS nur den neuesten Snapshot. Für einen älteren Stand ermöglicht zfs rollback -r das Zurücksetzen, löscht dabei aber neuere Snapshots und Bookmarks des betroffenen Speicherbereichs. Untergeordnete Datasets werden nicht automatisch zurückgesetzt. OpenZFS: Rollback
Snapshot-Verzeichnis für LXC und NAS
Bei Dateisystem-Datasets erreichen wir die alten Dateien auf dem Host unter:
<MOUNTPOINT>/.zfs/snapshot/<SNAPSHOTNAME>/
Der Inhalt ist schreibgeschützt. Wir kopieren benötigte Dateien zunächst in ein separates Wiederherstellungsverzeichnis. Beim Zurückkopieren bleiben Eigentümer und Rechte erhalten, insbesondere bei unprivilegierten LXC-Containern. Vor dem Ersetzen aktiver Anwendungsdateien stoppen wir die betroffene Anwendung.
snapdir=visible macht .zfs in Verzeichnislisten sichtbar. Bei hidden funktioniert normalerweise der direkte Pfad. Ein ZVOL für eine VM besitzt kein solches Dateiverzeichnis.
Clones für eine separate Wiederherstellung
Ein ZFS-Clone ist ein beschreibbarer Speicherbereich aus einem Snapshot. Für LXC oder NAS mounten wir ihn separat. Einen ZVOL-Clone können wir als zusätzliche Festplatte einer Wiederherstellungs-VM zuordnen und darin auf das Gast-Dateisystem zugreifen.
Der aktuelle Datenbestand bleibt erhalten. Clones benötigen anfangs kaum zusätzlichen Platz, eigene Änderungen belegen neue Blöcke. Der Ursprungssnapshot bleibt erforderlich, solange der Clone davon abhängt.
Ein manueller ZFS-Clone ist noch kein startfertiger Proxmox-Gast. Speicherzuordnung und Konfiguration müssen eingerichtet werden. Ein daraus gestarteter Testgast erhält zunächst ein getrenntes Netzwerk, damit keine doppelten IP-Adressen oder gleichzeitig aktiven Dienste entstehen.
OpenZFS: Snapshot-Zugriff und Clones
Grenzen der Wiederherstellung
Auto-Snapshots erfassen die ausgewählten Speicherbereiche. RAM, separat gespeicherte Proxmox-Gastkonfigurationen und externe Mounts gehören nicht automatisch dazu. Ein konsistenter ZFS-Snapshot garantiert außerdem keine Anwendungskonsistenz einer laufenden Datenbank.
zfs send und zfs receive auf ein anderes System muss zusätzlich eingerichtet werden.Alle VM-Disks nach rpool/clone klonen und eine neue VM anlegen
Wir erstellen aus den Auto-Snapshots beschreibbare ZVOL-Clones und ordnen sie einer neuen Proxmox-VM zu. Die produktive VM und ihre aktuellen Disks bleiben erhalten. Die folgenden Schritte sind eine Vorlage für VM 100 → VM 900 auf dem Host mit rpool; VMID 900 und die Zielnamen müssen frei sein.
1. Alle Disks und den Wiederherstellungsstand erfassen
qm config 100
zfs list -t volume -r rpool
zfs list -t snapshot -r -o name,creation -s creation rpool/data
Aus qm config übernehmen wir jede Festplatten-Zuordnung, einschließlich vorhandener efidisk0 und tpmstate0. Speicherpfade lassen sich mit pvesm path <VOLUME-ID> auflösen. CD-ROM-ISOs werden nicht als ZVOL geklont. Eine vorhandene Cloud-Init-Disk und zusätzliche ZVOLs müssen ebenfalls berücksichtigt werden.
Für jede Disk muss der gewählte Snapshot existieren. Derselbe Snapshot-Name bedeutet bei einzeln erstellten Snapshots nicht zwingend denselben Erstellungszeitpunkt. Für Datenbanken über mehrere Disks benötigen wir einen koordinierten, anwendungskonsistenten Stand oder müssen nach dem Start mit Wiederherstellungsarbeiten rechnen.
| Anschluss | Quell-ZVOL | Ziel-ZVOL |
|---|---|---|
| scsi0 | rpool/data/vm-100-disk-0 | rpool/clone/vm-900-disk-0 |
| scsi1 | rpool/data/vm-100-disk-1 | rpool/clone/vm-900-disk-1 |
| efidisk0 | rpool/data/vm-100-disk-2 | rpool/clone/vm-900-disk-2 |
| tpmstate0 | rpool/data/vm-100-disk-3 | rpool/clone/vm-900-disk-3 |
2. ZFS-Bereich und Proxmox-Storage einrichten
Einmalig anlegen, wenn noch nicht vorhanden. rpool/clone ist der ZFS-Bereich; zfs-clone ist die Storage-ID in Proxmox. Hier ist mit „Datastore“ ein Proxmox-VE-Storage gemeint, kein Proxmox-Backup-Server-Datastore.
zfs create -o mountpoint=none -o com.sun:auto-snapshot=false rpool/clone
# PVE-NODENAME durch den tatsächlichen Proxmox-Knotennamen ersetzen:
pvesm add zfspool zfs-clone --pool rpool/clone --content images --sparse 1 --nodes PVE-NODENAME
pvesm status
Die Beschränkung auf den richtigen Knoten ist besonders im Cluster wichtig: Dieser Storage liegt lokal. com.sun:auto-snapshot=false schließt den Wiederherstellungsbereich über die geerbte Eigenschaft von der normalen Auto-Snapshot-Rotation aus.
3. Für jede Disk einen ZFS-Clone erstellen
SNAPSHOTNAME durch den tatsächlich vorhandenen Auto-Snapshot-Namen ersetzen. Die vier Befehle decken alle Disks unseres Beispiels ab. Hat die VM weitere ZVOLs, wird die Liste entsprechend erweitert.
zfs clone -o refreservation=none -o com.sun:auto-snapshot=false rpool/data/vm-100-disk-0@SNAPSHOTNAME rpool/clone/vm-900-disk-0
zfs clone -o refreservation=none -o com.sun:auto-snapshot=false rpool/data/vm-100-disk-1@SNAPSHOTNAME rpool/clone/vm-900-disk-1
zfs clone -o refreservation=none -o com.sun:auto-snapshot=false rpool/data/vm-100-disk-2@SNAPSHOTNAME rpool/clone/vm-900-disk-2
zfs clone -o refreservation=none -o com.sun:auto-snapshot=false rpool/data/vm-100-disk-3@SNAPSHOTNAME rpool/clone/vm-900-disk-3
zfs list -t volume -r -o name,origin,used,referenced,refreservation rpool/clone
pvesm list zfs-clone --vmid 900
refreservation=none vermeidet eine vollständige Platzreservierung pro Clone. Eigene Schreibzugriffe brauchen trotzdem echten freien Poolplatz. Die Namen vm-900-disk-N ordnen die Volumes der neuen VMID zu. ZFS-Clones müssen innerhalb desselben Pools bleiben.
4. Neue VM anlegen und geklonte Disks anschließen
Dieses Beispiel setzt eine UEFI-VM mit Q35, VirtIO-SCSI, einer EFI-Disk des Typs 4m und TPM 2.0 voraus. BIOS, Maschinenmodell, Controller, Disk-Anschlüsse, EFI-/TPM-Version und Disk-Optionen müssen zur Quell-VM passen. Bei einer BIOS-VM entfällt beispielsweise die EFI-Disk. Die VM wird zunächst ohne Netzwerkkarte angelegt.
qm create 900 --name recovery-vm100 --memory 4096 --cores 2 --bios ovmf --machine q35 --scsihw virtio-scsi-pci --onboot 0
qm set 900 --scsi0 zfs-clone:vm-900-disk-0
qm set 900 --scsi1 zfs-clone:vm-900-disk-1
qm set 900 --efidisk0 zfs-clone:vm-900-disk-2,efitype=4m,pre-enrolled-keys=1
qm set 900 --tpmstate0 zfs-clone:vm-900-disk-3,version=v2.0
qm set 900 --boot 'order=scsi0'
qm config 900
# Erst nach Prüfung aller Zuordnungen starten:
qm start 900
Die Befehle verbinden bestehende Clones; sie importieren oder kopieren keine neuen Disk-Inhalte. Die aktuelle Konfiguration der Quell-VM dient nur als Vorlage: Bei alten Datenständen kann die damalige Hardware-Konfiguration nötig sein. Bei verschlüsselten Gästen können außerdem Wiederherstellungsschlüssel erforderlich sein.
Über die Proxmox-Konsole prüfen wir den Start und die Daten. Für Dateirettung kann stattdessen eine vorhandene Wiederherstellungs-VM die geklonten Daten-Disks als zusätzliche Laufwerke erhalten. Erst wenn nötig, verbinden wir den Testgast mit einem isolierten Netz.
5. Abhängigkeiten und Speicherplatz nach der Rettung
Der Clone bleibt von seinem Ursprungssnapshot abhängig. Auto Snapshot kann diesen deshalb nicht sofort vollständig entfernen. Nicht mehr benötigte Recovery-VMs und ihre Clone-Disks werden nach geprüfter Datenrettung über Proxmox entfernt; anschließend kontrollieren wir rpool/clone und zpool list. Soll die Recovery-VM dauerhaft bestehen, planen wir eine unabhängige vollständige Kopie statt eines dauerhaften Recovery-Clones.
rpool/clone nutzt denselben Pool. Es ist eine separate Arbeitskopie, aber kein unabhängiges Backup und kein zusätzlicher physischer Speicher.Referenzen: Proxmox-ZFS-Storage, pvesm, qm, ZFS-Clone.