pvesnap-recovery: Snapshots als Maschine starten
Zwei Betriebsarten:
live abgeschottet ohne Netzwerk - zum Hineinschauen ueber die
noVNC-Konsole, Dump ziehen, Daten ueber ein Austauschlaufwerk
herausholen
recovery mit Netzwerk und gleicher Identitaet (SMBIOS-UUID, vmgenid,
MAC-Adressen, Hostname) - warnt, wenn das Original noch laeuft
Die Datentraeger werden ueber PVE::Storage::vdisk_clone geklont, also mit
derselben Funktion und Cluster-Sperre, die Proxmox selbst verwendet. Auf
Ceph/ZFS/LVM-thin ist das Copy-on-Write: 32 GiB waren im Test in 0,8s
geklont, das Original bleibt unberuehrt.
Enthaelt der Snapshot den Arbeitsspeicher, wird er mitkopiert - die Maschine
laeuft dann genau dort weiter, wo sie stand, statt zu booten. Dafuer muss die
Geraeteausstattung exakt passen:
- vmgenid und smbios1 bleiben erhalten (ohne vmgenid bricht das Laden mit
"Unknown savevm section" ab)
- runningmachine/runningcpu werden uebernommen
- die Netzwerkkarte wird abgeklemmt statt entfernt
- das Austauschlaufwerk kommt erst nach dem Fortsetzen per Hotplug dazu,
sonst bemerkt der Gast es nie (nachgewiesen ueber "info virtio-status")
Proxmox meldet einen fehlgeschlagenen RAM-Ladevorgang als TASK OK und laesst
die Maschine angehalten stehen - deshalb wird das Task-Protokoll mitgelesen,
fortgesetzt und deutlich gemeldet, wenn stattdessen kalt gebootet wurde.
Austausch mit dem Host: bei VMs eine formatierte Zusatzplatte, bei
Containern ein durchgereichtes Verzeichnis - dort passt auch ein bereits
eingehaengtes Netzlaufwerk.
Verworfen wird restlos, samt Aufheben des rbd-Snapshot-Schutzes, den das
Klonen setzt - sonst koennte die Vorhaltezeit den Snapshot nie mehr loeschen.
Angefasst wird nur, was den Tag pvesnap-recovery traegt.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
8577b23b0c
commit
725fbf8732
@@ -12,10 +12,12 @@ löscht. Alles wird über **eine INI-Datei** gesteuert, die sich auch bequem in
|
||||
* Läuft cluster-weit (alle Nodes) über `pvesh`
|
||||
* Nur Python-Standardbibliothek — keine zusätzlichen Pakete nötig
|
||||
|
||||
Dazu zwei Werkzeuge, um wieder **an die Daten im Snapshot** zu kommen:
|
||||
Dazu drei Werkzeuge, um wieder **an die Daten im Snapshot** zu kommen:
|
||||
|
||||
* `pvesnap-explorer` — zwei Fenster im Terminal wie im Midnight Commander
|
||||
* `pvesnap-web` — im Browser durchsehen und herunterladen, auch vom anderen Rechner
|
||||
* `pvesnap-recovery` — den Snapshot als **laufende Maschine** starten, abgeschottet
|
||||
ohne Netzwerk oder als vollwertige Wiederherstellung mit gleicher Identität
|
||||
|
||||
---
|
||||
|
||||
@@ -46,6 +48,7 @@ Das Skript legt an:
|
||||
| `/usr/local/bin/pvesnap` | Dienst und Konfiguration |
|
||||
| `/usr/local/bin/pvesnap-explorer` | Zwei-Fenster-Explorer |
|
||||
| `/usr/local/bin/pvesnap-web` | Web-Oberfläche |
|
||||
| `/usr/local/bin/pvesnap-recovery` | Snapshot als Maschine starten |
|
||||
| `/etc/pvesnap/pvesnap.conf` | Konfiguration (wird bei Updates **nicht** überschrieben) |
|
||||
| `/var/lib/pvesnap/state.json` | merkt sich die letzten Läufe |
|
||||
| `/etc/systemd/system/pvesnap.service` | systemd-Unit des Snapshot-Dienstes |
|
||||
@@ -546,6 +549,193 @@ Snapshot wieder ausgehängt.
|
||||
|
||||
---
|
||||
|
||||
## Einen Snapshot als Maschine starten — `pvesnap-recovery`
|
||||
|
||||
Manchmal reicht es nicht, einzelne Dateien herauszukopieren. Eine Datenbank zum
|
||||
Beispiel liegt im Snapshot als Haufen halbfertiger Dateien — brauchbar wird sie
|
||||
erst, wenn der Datenbankserver läuft und selbst einen Dump schreibt. Genau dafür
|
||||
ist `pvesnap-recovery` da: Es startet den Snapshot als **eigenständige Maschine**,
|
||||
ohne das Original anzufassen.
|
||||
|
||||
Zwei Betriebsarten:
|
||||
|
||||
| | **live** | **recovery** |
|
||||
|---|---|---|
|
||||
| Netzwerk | keins | volles Netz |
|
||||
| Identität | bleibt (UUID, MACs, Hostname) | bleibt (UUID, MACs, Hostname) |
|
||||
| Wofür | hineinschauen, Dump ziehen, Daten holen | die Maschine wirklich wieder in Betrieb nehmen |
|
||||
| Risiko | keins — sie kann nichts erreichen | hoch, solange das Original läuft |
|
||||
|
||||
Bedient wird das Ganze mit `pvesnap-recovery` (ncurses-Oberfläche mit Übersicht
|
||||
und Assistent) oder direkt über Parameter.
|
||||
|
||||
### Warum das schnell geht
|
||||
|
||||
Die Datenträger werden nicht kopiert, sondern **geklont**. Auf Ceph/RBD, ZFS und
|
||||
LVM-thin ist das ein Copy-on-Write-Klon: Er ist in Sekunden fertig, egal wie groß
|
||||
die Platte ist, und belegt anfangs keinen zusätzlichen Platz. Eine 32-GB-Platte
|
||||
war im Test nach **0,8 Sekunden** geklont.
|
||||
|
||||
Dafür wird `PVE::Storage::vdisk_clone` benutzt — dieselbe Funktion, die auch
|
||||
Proxmox selbst für Klone verwendet, samt Cluster-Sperre auf dem Storage. Es wird
|
||||
also nichts nachgebaut, was Proxmox schon kann.
|
||||
|
||||
> Auf Datei-Storages (`dir`, `nfs`, `cifs`) geht das nicht — dort lässt sich aus
|
||||
> einem qcow2-internen Snapshot kein Klon ziehen. Für diese Storages bleibt der
|
||||
> Weg über `pvesnap-explorer`.
|
||||
|
||||
### Der Arbeitsspeicher kommt mit
|
||||
|
||||
Enthält der Snapshot den Arbeitsspeicher (`vmstate`, in der Konfiguration
|
||||
`snapshot_vmstate = yes`), wird der mitgenommen. Die Maschine **bootet dann
|
||||
nicht**, sondern läuft genau dort weiter, wo sie beim Snapshot stand:
|
||||
|
||||
* kein Crash-Recovery, kein `fsck`, kein Journal-Rollback
|
||||
* Datenbanken sind bereits offen und konsistent
|
||||
* die Uhr im Gast steht auf dem Snapshot-Zeitpunkt
|
||||
|
||||
Im Test war das nachweisbar: Die Konsole zeigte 10:38 — die Uhrzeit des
|
||||
Snapshots — während auf dem Host längst 11:24 war.
|
||||
|
||||
Damit das klappt, muss die Geräteausstattung exakt zum gespeicherten Zustand
|
||||
passen. `pvesnap-recovery` sorgt selbst dafür:
|
||||
|
||||
* `vmgenid` und `smbios1` bleiben erhalten (fehlen sie, bricht das Laden mit
|
||||
`Unknown savevm section or instance 'vmgenid'` ab)
|
||||
* `runningmachine` und `runningcpu` aus dem Snapshot werden übernommen
|
||||
* die Netzwerkkarte bleibt **vorhanden**, wird aber abgeklemmt (`link_down=1`)
|
||||
statt entfernt — herausnehmen würde den Zustand unbrauchbar machen
|
||||
* das Austauschlaufwerk wird erst **nach** dem Fortsetzen angesteckt (Hotplug),
|
||||
weil der Gast in einem Zustand aufwacht, in dem es die Platte noch nicht gab
|
||||
|
||||
Ein Detail, das Proxmox nicht selbst meldet: Schlägt das Laden des
|
||||
Arbeitsspeichers fehl, quittiert Proxmox den Start trotzdem mit `TASK OK` und
|
||||
lässt die Maschine angehalten stehen. `pvesnap-recovery` liest das Task-Protokoll
|
||||
mit, setzt die Maschine fort und sagt deutlich, wenn statt des RAM-Standes kalt
|
||||
gebootet wurde.
|
||||
|
||||
Mit `--no-resume` lässt sich der Arbeitsspeicher bewusst weglassen.
|
||||
|
||||
### Daten aus einer Maschine ohne Netzwerk holen
|
||||
|
||||
Ohne Netz kommt nichts heraus — dafür gibt es das **Austauschlaufwerk**.
|
||||
|
||||
**Bei virtuellen Maschinen** wird eine leere, formatierte Zusatzplatte angelegt
|
||||
(Bezeichnung `PVESNAP`, mit einer kurzen `LIESMICH.txt` darauf):
|
||||
|
||||
```bash
|
||||
# Snapshot abgeschottet starten, mit 20 GB Austauschplatte
|
||||
pvesnap-recovery live 802 --exchange 20G
|
||||
|
||||
# im Gast (über die noVNC-Konsole):
|
||||
mount /dev/disk/by-label/PVESNAP /mnt
|
||||
mysqldump --all-databases > /mnt/dump.sql
|
||||
umount /mnt && poweroff
|
||||
|
||||
# auf dem Host:
|
||||
pvesnap-recovery pull 9802 # gibt den Pfad aus, z. B. /run/pvesnap/exchange/9802
|
||||
pvesnap-recovery release 9802 # wieder lösen
|
||||
pvesnap-recovery destroy 9802 # alles verwerfen
|
||||
```
|
||||
|
||||
**Bei Containern** ist es einfacher: Ein Host-Verzeichnis wird direkt
|
||||
durchgereicht und erscheint im Container unter `/mnt/pvesnap`. Was der Container
|
||||
hineinschreibt, liegt sofort auf dem Host — kein Ein- und Aushängen nötig.
|
||||
|
||||
```bash
|
||||
pvesnap-recovery live 100 --exchange ja
|
||||
pct exec 9100 -- sh -c 'pg_dumpall > /mnt/pvesnap/dump.sql'
|
||||
ls /var/lib/pvesnap/exchange/9100/
|
||||
```
|
||||
|
||||
Und hier passt auch die Idee mit dem **Netzlaufwerk**: Ist auf dem Host ohnehin
|
||||
schon eine NFS- oder CIFS-Freigabe eingehängt, lässt sie sich direkt
|
||||
durchreichen — der Container schreibt dann quasi aufs Netzlaufwerk, obwohl er
|
||||
selbst kein Netzwerk hat:
|
||||
|
||||
```bash
|
||||
pvesnap-recovery live 100 --exchange-dir /mnt/nfs/dumps
|
||||
```
|
||||
|
||||
Bei virtuellen Maschinen geht das nicht: Ein Host-Verzeichnis lässt sich nicht in
|
||||
eine VM hineinreichen. Dort bleibt es bei der Austauschplatte.
|
||||
|
||||
### An die Konsole kommen
|
||||
|
||||
```
|
||||
https://<node>:8006/?console=kvm&novnc=1&vmid=9802&node=<node>&resize=off&cmd=
|
||||
```
|
||||
|
||||
Diese Adresse gibt `pvesnap-recovery` nach dem Anlegen aus, ebenso
|
||||
`pvesnap-recovery console <VMID>`. Es ist die ganz normale noVNC-Konsole von
|
||||
Proxmox — die Maschine taucht auch in der Weboberfläche auf, markiert mit dem Tag
|
||||
`pvesnap-recovery`. Bei Containern geht zusätzlich `pct enter <VMID>`.
|
||||
|
||||
### Wiederherstellung mit Netzwerk
|
||||
|
||||
```bash
|
||||
pvesnap-recovery recover 802 autosnap-g5min-20260731-103800 --newid 9802
|
||||
```
|
||||
|
||||
Hier bleibt alles erhalten, was die Maschine ausmacht: SMBIOS-UUID, `vmgenid`,
|
||||
MAC-Adressen, bei Containern der Hostname. Für alles im Netz ist sie dieselbe
|
||||
Maschine — inklusive Lizenzbindungen, AD-Mitgliedschaft und DHCP-Reservierungen.
|
||||
|
||||
**Genau deshalb ist sie gefährlich.** `pvesnap-recovery` prüft vorher, ob das
|
||||
Original läuft, und warnt unmissverständlich. Zwei Maschinen mit derselben MAC
|
||||
und derselben IP im selben Netz geben Chaos. Das Original also **vorher
|
||||
stoppen** — oder mit `--net down` starten und die Karte erst zuschalten, wenn
|
||||
klar ist, dass die Luft rein ist.
|
||||
|
||||
### Parameter
|
||||
|
||||
| Parameter | Bedeutung |
|
||||
|---|---|
|
||||
| `live <VMID> [snapshot]` | abgeschottet starten (ohne Snapshot: der neueste) |
|
||||
| `recover <VMID> [snapshot]` | mit Netzwerk und gleicher Identität starten |
|
||||
| `--newid <ID>` | VMID der neuen Maschine (Vorgabe: nächste freie) |
|
||||
| `--node <name>` | auf welchem Node sie laufen soll |
|
||||
| `--net none\|down\|on` | keine Karte / Karte ohne Leitung / voll am Netz |
|
||||
| `--resume` / `--no-resume` | Arbeitsspeicher laden bzw. bewusst kalt starten |
|
||||
| `--exchange <größe>` | Austauschplatte, z. B. `20G` (Container: `ja` genügt) |
|
||||
| `--exchange-storage <name>` | Storage dafür (Vorgabe: wie die erste Platte) |
|
||||
| `--exchange-fs <fs>` | `ext4` (Vorgabe), `ext3`, `xfs`, `vfat`, `ntfs` |
|
||||
| `--exchange-dir <pfad>` | nur Container: dieses Host-Verzeichnis durchreichen |
|
||||
| `--memory <MB>`, `--cores <n>` | abweichende Ausstattung (nicht mit `--resume`) |
|
||||
| `--name <name>` | Name der neuen Maschine |
|
||||
| `--keep-binds` | durchgereichte Host-Verzeichnisse des Originals übernehmen |
|
||||
| `--no-start` | nur einrichten, nicht starten |
|
||||
| `-y`, `--yes` | nicht nachfragen |
|
||||
|
||||
| Befehl | Bedeutung |
|
||||
|---|---|
|
||||
| `pvesnap-recovery` | ncurses-Oberfläche mit Übersicht und Assistent |
|
||||
| `list` | vorhandene Wiederherstellungen anzeigen |
|
||||
| `start` / `stop` | hoch- bzw. herunterfahren |
|
||||
| `console <VMID>` | noVNC-Adresse ausgeben |
|
||||
| `pull <VMID>` | Austauschlaufwerk auf den Host holen |
|
||||
| `release <VMID>` | es wieder lösen |
|
||||
| `destroy <VMID>` | restlos verwerfen |
|
||||
|
||||
### Was beim Verwerfen passiert
|
||||
|
||||
`destroy` räumt vollständig auf: Maschine stoppen, Gast samt aller Klone
|
||||
entfernen, Austauschverzeichnis löschen — und den **Schutz der Quell-Snapshots
|
||||
wieder aufheben**.
|
||||
|
||||
Dieser letzte Punkt ist wichtig: Ceph verlangt für einen Klon, dass der
|
||||
Quell-Snapshot geschützt ist (`rbd snap protect`), und Proxmox setzt das beim
|
||||
Klonen selbst. Bliebe der Schutz stehen, könnte die Vorhaltezeit diesen Snapshot
|
||||
später nicht mehr löschen — im Protokoll stünde dann immer wieder
|
||||
`snapshot is protected`. Solange eine Wiederherstellung existiert, ist ihr
|
||||
Quell-Snapshot also bewusst unlöschbar; danach nicht mehr.
|
||||
|
||||
Zur Sicherheit fasst `destroy` nur Maschinen an, die den Tag `pvesnap-recovery`
|
||||
tragen. Eine von Hand angelegte VM lässt sich damit nicht versehentlich löschen.
|
||||
`uninstall.sh` warnt ebenfalls, wenn noch Wiederherstellungen offen sind.
|
||||
|
||||
---
|
||||
|
||||
## Aufbau
|
||||
|
||||
```
|
||||
@@ -563,6 +753,8 @@ pvesnap/
|
||||
tui.py ncurses-Konfigurationseditor
|
||||
snapfs.py Snapshots einbinden und mounten (rbd/zfs/lvm/qcow2)
|
||||
explorer.py Zwei-Fenster-Explorer im Terminal
|
||||
recovery.py Snapshot als Maschine starten (Klone, Konfiguration, Aufräumen)
|
||||
recovery_ui.py ncurses-Oberfläche und Kommandozeile dazu
|
||||
web/ Web-Oberfläche zum Herunterladen
|
||||
server.py HTTP-Server, ZIP im Strom, Zugangsschlüssel
|
||||
assets.py Stylesheet und HTML-Gerüst
|
||||
|
||||
Reference in New Issue
Block a user