Proxmox-Backup mit ZFS_SEND sowie RAW -> Restic
Wer virtuelle Maschinen und LXC-Container unter Proxmox betreibt, steht früher oder später vor der Frage nach einem verlässlichen, platzsparenden Backup. Genau dafür ist dieses Skript gedacht: Es sichert VMs, Container und ausgewählte Verzeichnisse automatisiert auf eine externe Festplatte – und kombiniert dabei die Stärken zweier bewährter Werkzeuge.
Die Idee dahinter
Gesichert wird alles, was zu einer Maschine gehört: die Laufwerke der VMs, die Dateisysteme der LXC-Container sowie deren Proxmox-Konfiguration. Optional lassen sich zusätzliche lokal auf dem Host liegendene Verzeichnisse (LOCAL_DIRS) einbeziehen. Über eine schlanke Konfigurationsdatei bestimmt man, welche Maschinen ausgeschlossen werden, ob Templates übersprungen werden und welche Ordner unberücksichtigt bleiben sollen.
Restic-Repository und Passwortdatei werden beim ersten Lauf automatisch erzeugt – eine manuelle Einrichtung ist nicht nötig.
Snapshotsicherung
Das Programm sichert nicht das aktuelle Live Image, sondern aus Konsistenzgründen den letzten, vorliegenden Snapshot.
Die vom Programm gesicherten Snapshots erstellt das Programm NICHT selbst, diese müssen mit externen Mitteln erstellt werden. Ich behelfe mir hier seit jeher mit cv4pve-autosnap , welches ich täglich abends VOR DEM BACKUP aufrufe.
Sollte der letzte vorgefundene Snapshot älter als 86400 Sekunden (1 Tag) sein, gibt es eine Warnung, auf die mit einem E-Mail Programm gefiltert werden kann.
Die Snapshot-Retention sollte bei der Nutzung der zfs_send Funktion aus naheliegenden Gründen größer sein als das Intervall von Full-Snapshots.
Technik / Full- und Differential-Backups
LXC Container:
LXC Container werden dateibasiert gesichert und lassen sich hervorragend durch restic deduplizieren.
VM im zfs send Modus:
Statt jedes Mal alles komplett zu sichern, arbeitet das Skript mit einem Full/Differential-Konzept. Jedes Differential ist ein Delta gegen das letzte Voll-Backup – das spart erheblich Speicherplatz und Zeit. Ein neues Voll-Backup wird nur geschrieben, wenn es wirklich nötig ist: an einem optional festgelegten Wochentag, wenn das letzte Full älter als eine einstellbare Anzahl Tage ist, oder wenn die Grundlage für ein Differential fehlt.
Das Programm nutzt zfs send, um konsistente Snapshots der ZFS-Datasets zu erzeugen, und übergibt diese Streams an Restic, das die Daten verschlüsselt und versioniert im Backup-Repository ablegt. Deduplizierung funktioniert mit zfs send Snapshots nicht.
VM im RAW Modus:
Darüber hinaus kann das Programm alternativ einen RAW Stream sichern und über Restic deduplizieren.
Vor- und Nachteile:
Wiegen sich auf:
- RAW benötigt am wenigsten Platz auf dem Zieldatenträger, da es hervorragend dedupliziert wird
- RAW erzeugt ausschießlich full Backups
- RAW spart Schreib I/O ggü. VZDump und somit i.d.R. auch Zeit
- RAW spart keine Lese I/O ggü. VZDump
- zfs_send benötigt weniger Lese und Schreib I/O
- Ggü. VZDump insbesondere bei diffs erheblich weniger Zeitbedarf.
- Bei full Backups nur dann Zeitersparnis, wenn der Backup-Datenträger schnell oder die CPU langsam ist
zfs_send ist die bessere Methode, wenn es um Lese- und Schreib I/O sowie um Geschwindigkeit geht.
RAW ist die bessere Methode, wenn es um Platteneffizienz und vermeiden von Diff-Backups geht.
Beide Varianten sind VZDump in jeder Hinsicht überlegen.
zfs_send funktioniert nur beim Einsatz von ZFS und auch nur, wenn der Zieldatenträger groß genug ist (mind. ~ 2,3x größer als die zu sichernde Datenmenge, damit immer 2x Full + ein paar Diffs aufs Ziel passen).
Deshalb wird bei Sicherungsmedien < 2,3x der zu sichernden Datenmenge automatisch auf RAW zurückgegriffen, ansonsten auf zfs_send.
Automatische Aufräum-Logik
Alte Sicherungen werden nach einer konfigurierbaren Aufbewahrungsregel (täglich, wöchentlich, monatlich) automatisch entfernt. Dabei achtet das Programm darauf, keine Voll-Backups zu löschen, von denen noch benötigte Differentials abhängen.
Wird ein neues Voll-Backup fällig und der Platz auf dem Datenträger reicht nicht aus, baut das Skript die Historie selbstständig ab – vom ältesten Backup an, notfalls bis das Medium leer ist – und warnt deutlich, falls ein größerer Datenträger nötig wird.
Sicherheit und Betrieb
Vor jedem Lauf prüft das Programm Systemzustand, Pool-Status und Speicherbelegung. Ein Lock verhindert parallele Läufe, nach dem Backup folgt eine Integritätsprüfung der neu geschriebenen Daten. Auf Wunsch verschickt das Skript eine E-Mail mit dem Ergebnis und versetzt die Backup-Platte anschließend in den Standby.
So entsteht ein Backup, das ohne tägliches Zutun läuft, sparsam mit Speicher umgeht und sich im Ernstfall zuverlässig zurückspielen lässt.
Installation und Konfiguration
Abhängigkeiten:
Code:
apt install restic jq pv
Alle drei Dateien nach /usr/local/bin/ kopieren und .txt Endung entfernen.
Code:
chmod +x ResticBackup.sh
chmod +x ResticRestore.sh
UUID der ext. Festplatte herausfinden und in die /usr/local/bin/config.cfg eintragen.
Code:
blkid
Alle auskommentierten Parameter in der Restic Restore entsprechen dem optionalen Default.
Sicherung aller VMs, LXC Container und den optionalen zu sichernden LOCAL_DIRS durchführen:
Code:
./ResticBackup.sh
Sicherung von Maschine 115 durchführen:
Code:
./ResticBackup.sh 115
Restore
Code:
./ResticRestore.sh --help
# z.B.
./ResticRestore.sh --machine 115 --target 9115
Lizenz
Gemeinfrei nach CC-0
Beispiel:
Code:
VM:
600 GB machine storage
300 GB used
5 GB diff per day
Backup-Storage: 930 GB
| Read I/O VM | Write I/O Backup | max Backup count | runtime
| 500 MB/s | 100 MB/s | on disk |
------------------------------------------------------------------------------------
VZDump | 600 GB | 250 GB * | | 42 min
------------------------------------------------------------------------------------
20-backup-sum | 12 TB | 5 TB | 2 ** | 840 min
RAW first time | 600 GB | 250 GB * | | 42 min
RAW following | 600 GB | 5 GB | | 20 min
------------------------------------------------------------------------------------
20-backup-sum | 12 TB | 345 GB | > 100 *** | 422 min
zfs_s 1. full | 300 GB | 300 GB * | | 50 min
zfs_s 1. diff | 5 GB | 5 GB | | 1 min
zfs_s 2. diff | 10 GB | 10 GB | | 2 min
zfs_s 3. diff | 15 GB | 15 GB | | 2.5 min
...
zfs_s 9. diff | 45 GB | 45 GB | | 7.5 min
zfs_s 2. full | 300 GB | 300 GB | | 50 min
zfs_s 10. diff | 5 GB | 5 GB | | 1 min
...
------------------------------------------------------------------------------------
20-backup-sum | 1.1 TB | 1.1 TB | 13 **** | 175 min
* 300 GB used storage can compress to approx 250 GB; if you store via zfs_send, further reduction is not possible
** I you use the prune process of VZdump, which only prune after backup your total number is 2.
You can increment this to 3 if you use your own prune process, which prune directly before creation
*** (930 - 250)/5 = 137, but you would not conserve 137 dailys,
so the difference between individual backups eventually become larger than 5 GB
****Initial you can add 17 backups, but worst case would be: 300+40+45+300+5+10+15+20+25+30+35+40+45 = 910 => 13 backups
Attachments
Last edited: