Handbuch auf MkDocs-Basis, mit Bildschirmfotos aus dem Programm

26 Kapitel in vier Teilen, in der Reihenfolge, in der man sie braucht:
erst sichern, dann Dateien holen, dann ganze Maschinen wiederherstellen,
dahinter der Nachschlagteil.

Gebaut wird mit MkDocs + Material. Bewusst ohne Netzabhaengigkeiten:
keine Schriften vom CDN (font: false), Volltextsuche mit deutschem
Stemming liegt neben den Seiten. Im Notfall steht vielleicht das halbe
Netz - dann nuetzt eine Doku im Internet nichts.

  handbuch/bauen.sh              baut handbuch/site/
  handbuch/bauen.sh ansehen      Vorschau auf 127.0.0.1:8000

install.sh nimmt das gebaute Handbuch mit nach
/usr/share/doc/pvesnap/handbuch/ - falls es vorliegt. Auf dem Host selbst
wird nichts gebaut, mkdocs gehoert nicht auf einen Hypervisor.

Die 28 Bildschirmfotos sind nicht abfotografiert, sondern erzeugt: Der
echte Programmcode laeuft in einem Pseudo-Terminal gegen einen erfundenen
Proxmox-Host (Attrappen fuer pvesh, perl und rbd), pyte baut den Bildschirm
nach, heraus faellt ein SVG. Damit stimmen sie garantiert mit dem Programm
ueberein, sind reproduzierbar und enthalten keine echten Daten. Die
Werkstatt dafuer liegt unter handbuch/werkstatt/ samt LIESMICH.md.

Nebenbei: die Schlussmeldung von install.sh warb noch mit --exchange,
das mit dem eingebauten Austauschlaufwerk weggefallen ist.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
duffyduck
2026-08-09 12:39:30 +02:00
co-authored by Claude Opus 5
parent c484596702
commit 59e7224297
72 changed files with 7355 additions and 2 deletions
+210
View File
@@ -0,0 +1,210 @@
# Welche Gäste?
Eine Gruppe sucht sich ihre Gäste über eine oder mehrere Regeln. Dabei gilt:
<div class="ablauf" markdown>
Alle Einschluss-Regeln wirken als **ODER** — wer *eine* davon erfüllt, ist dabei.
Alle Ausschluss-Regeln **gewinnen immer** — auch gegen `all = yes`.
</div>
```ini
all = yes # alle VMs und Container
vmids = 100,101,105-110 # nach ID, auch Bereiche
names = web-*, db-0? # nach Name, mit Platzhaltern
tags = produktion, wichtig # nach Proxmox-Tag
pools = Kunden # nach Proxmox-Pool
types = qemu # nur VMs (lxc = nur Container; leer = beides)
exclude_vmids = 999
exclude_names = *-test
exclude_tags = nosnap
```
Kontrollieren lässt sich das Ergebnis an zwei Stellen: unten in der
[Gruppenmaske](editor.md#eine-gruppe-bearbeiten) („Trifft aktuell zu auf …") und
mit `pvesnap vms`.
---
## Tags
**Der empfohlene Weg.** Die Auswahl steht dann bei der VM, nicht in der
Konfiguration — und eine neue Maschine ist mit einem Klick dabei, ohne dass
jemand `pvesnap.conf` anfassen muss.
```ini
tags = produktion
```
In Proxmox setzen:
```bash
qm set 101 --tags produktion,datenbank
pct set 110 --tags produktion
```
Oder in der Oberfläche unter **VM → Optionen → Tags**.
Groß- und Kleinschreibung ist egal; pvesnap vergleicht in Kleinbuchstaben.
Mehrere Tags an einer VM trennt Proxmox mit `;` oder `,` — beides wird gelesen.
!!! tip "Ein Tag je Zeitplan"
Bewährt hat sich, die Tags nach dem Sicherungsrhythmus zu benennen und
nicht nach der Funktion:
```ini
[group:stuendlich]
tags = stuendlich
[group:taeglich]
tags = produktion
```
Dann sieht man in der Proxmox-Oberfläche an jeder VM sofort, wie oft sie
gesichert wird — ohne die Konfiguration zu öffnen.
---
## VMIDs
```ini
vmids = 100,101,105-110,200
```
Einzelne IDs und Bereiche, durch Komma getrennt. Am bequemsten über die
[VM-Auswahl](editor.md#vms-aus-einer-liste-wahlen) im Editor.
Präzise, aber pflegeintensiv: Jede neue Maschine muss von Hand nachgetragen
werden. Für kleine, feste Zusammenstellungen in Ordnung, für alles Wachsende
sind Tags besser.
---
## Namensmuster
```ini
names = web-*, db-0?
```
| Zeichen | |
|---|---|
| `*` | beliebig viele Zeichen |
| `?` | genau ein Zeichen |
| `[abc]` | eines dieser Zeichen |
Praktisch bei sauberer Namenskonvention (`web-01`, `web-02`, `db-01`),
gefährlich ohne: Eine VM, die jemand `web-test-alt` nennt, fällt in `web-*`
hinein. Dagegen hilft ein `exclude_names = *-test`.
---
## Pools
```ini
pools = Kunden
```
Nach dem Proxmox-Pool. Sinnvoll, wenn die Pools ohnehin nach Kunde oder
Abteilung geschnitten sind — dann sichert eine Gruppe genau einen Mandanten.
---
## Gasttyp
```ini
types = qemu # nur virtuelle Maschinen
types = lxc # nur Container
types = # beides (Vorgabe)
```
Nützlich in Verbindung mit `vmstate = yes`, das ohnehin nur für QEMU gilt: Eine
Gruppe mit RAM-Sicherung für die VMs, eine ohne für die Container.
---
## Ausschlüsse
```ini
exclude_vmids = 999
exclude_names = *-test, temp-*
exclude_tags = nosnap, pvesnap-recovery
```
Ausschlüsse schlagen alles. Auch `all = yes`.
!!! success "Zwei Ausschlüsse, die in jede `all`-Gruppe gehören"
```ini
exclude_tags = nosnap, pvesnap-recovery
```
**`nosnap`** ist der Notausgang: Wer eine einzelne Maschine aus der
Sicherung nehmen will, setzt ihr das Tag — ohne die Konfiguration
anzufassen.
**`pvesnap-recovery`** trägt jede laufende
[Wiederherstellung](../wiederherstellen/index.md). Ohne den Ausschluss
bekämen diese kurzlebigen Maschinen eigene Snapshots — die dann wiederum
verhindern, dass sie sich sauber verwerfen lassen.
---
## Mehrere Regeln kombiniert
```ini
[group:taeglich]
tags = produktion
vmids = 300
exclude_names = *-test
exclude_tags = nosnap
```
Gelesen: *alles mit dem Tag `produktion`* **oder** *VM 300*, **aber nichts**,
was auf `-test` endet oder das Tag `nosnap` trägt.
---
## Gestoppte Gäste
```ini
skip_stopped = yes
```
Übergeht Gäste, die gerade aus sind. Vorgabe ist `no` — auch von einer
gestoppten Maschine wird ein Snapshot angelegt.
Beides ist vertretbar:
| | |
|---|---|
| `skip_stopped = no` | Der Stand ist gesichert, auch wenn die VM länger aus ist. Kostet bei kurzen Intervallen viele identische Snapshots. |
| `skip_stopped = yes` | Nur laufende Maschinen. Passt zu stündlichen Gruppen, spart Platz — aber eine über Wochen abgeschaltete VM bekommt gar nichts mehr. |
!!! note "Der Mischbetrieb"
Eine stündliche Gruppe mit `skip_stopped = yes`, eine monatliche mit
`skip_stopped = no`. Dann bekommt jede Maschine mindestens den monatlichen
Stand, und die laufenden zusätzlich die feine Auflösung.
---
## Nachsehen, was herauskommt
```bash
pvesnap vms
```
```
VMID Name Status Gruppen
100 web01 running stuendlich, taeglich, monatlich
101 db01 running stuendlich, taeglich, monatlich
120 build-test stopped (keine Gruppe)
```
Dasselbe im Editor unter Taste ++v++:
![Übersicht: welche VM in welcher Gruppe](../bilder/config-uebersicht.svg)
+175
View File
@@ -0,0 +1,175 @@
# Im Betrieb
## Der Dienst
```bash
systemctl status pvesnap # läuft er?
systemctl reload pvesnap # Konfiguration neu einlesen (SIGHUP)
systemctl restart pvesnap # kompletter Neustart
journalctl -u pvesnap -f # Protokoll mitlesen
```
`reload` ist der Normalfall nach einer Änderung: Der Dienst liest die
Konfiguration neu ein, ohne laufende Vorgänge abzubrechen und ohne den
gemerkten Zustand zu verlieren.
---
## Nachsehen
```bash
pvesnap status # Gruppen, letzte und nächste Läufe
pvesnap vms # welche VM landet in welcher Gruppe
pvesnap list # vorhandene pvesnap-Snapshots (-a = auch fremde)
pvesnap check # Konfiguration prüfen
```
### `pvesnap check`
Der Befehl, den man nach jeder Änderung laufen lassen sollte. Er findet unter
anderem:
* Gruppen ohne `keep_count` **und** ohne `keep_time` — die würden endlos wachsen
* zwei Gruppen mit demselben Kurznamen — die räumten sich gegenseitig ab
* Zeitpläne, die sich widersprechen (`interval` und `schedule` zugleich)
* eine Auswahl, die auf keinen einzigen Gast passt
* [Sandbox-Optionen in der systemd-Unit](../installation.md#die-systemd-unit),
an denen später jeder Snapshot scheitern würde
---
## Von Hand auslösen
```bash
pvesnap run # jetzt fällige Gruppen ausführen
pvesnap run --force -g taeglich # diese Gruppe sofort, egal ob fällig
pvesnap run --force --dry-run # Probelauf, ändert nichts
pvesnap prune -g stuendlich # nur aufräumen
```
`--force` heißt „auch wenn nicht fällig". Ohne das passiert bei einem Aufruf
zwischen zwei Terminen schlicht nichts.
!!! note "Parallel zum Dienst"
Ein manueller `pvesnap run` ist auch möglich, während der Dienst läuft.
Beide teilen sich eine Sperre und kommen sich nicht in die Quere — der
zweite wartet, bis der erste fertig ist.
### Eine andere Konfiguration ausprobieren
```bash
pvesnap -c /root/test.conf check
pvesnap -c /root/test.conf run --force --dry-run
```
`-c` gilt für alle Unterbefehle. Zusammen mit `--dry-run` ein gefahrloser Weg,
eine neue Gruppenstruktur durchzuspielen, bevor sie scharf geschaltet wird.
---
## Der Probelauf
```ini
[global]
dry_run = yes
```
oder einmalig:
```bash
pvesnap run --force --dry-run
```
Protokolliert, was geschähe, ohne etwas anzulegen oder zu löschen:
```
[TESTLAUF] wuerde Snapshot anlegen: VM 101 (db01) -> auto-taeglich-20260809-023000
[TESTLAUF] wuerde Snapshot loeschen: VM 101 (db01) -> auto-taeglich-20260719-023000
```
Besonders die zweite Zeilenart ist es wert, einmal angesehen zu werden, bevor
eine neue Vorhaltezeit produktiv geht.
---
## Protokoll
```ini
[global]
log_level = INFO
# log_file = /var/log/pvesnap.log
```
| Stufe | |
|---|---|
| `DEBUG` | jeder `pvesh`-Aufruf mit Argumenten — für die Fehlersuche |
| `INFO` | was angelegt und gelöscht wird (Vorgabe) |
| `WARNING` | nur Auffälligkeiten |
| `ERROR` | nur Fehler |
Ohne `log_file` geht alles ins Journal:
```bash
journalctl -u pvesnap -f # mitlesen
journalctl -u pvesnap --since "-1h" # letzte Stunde
journalctl -u pvesnap -p err # nur Fehler
journalctl -u pvesnap --since today | grep -i fehl
```
---
## Was im Protokoll normal ist
Nicht jede Meldung ist ein Problem:
| Meldung | Bedeutung |
|---|---|
| `storage does not support snapshots` | Diese VM liegt auf LVM-thick oder einem `raw`-Image. Sie wird übersprungen, die übrigen laufen weiter. |
| `got lock request timeout` | Das Storage war gerade belegt. Wird `retries`-mal wiederholt — erst danach ist es ein Fehler. |
| `VM is locked (backup)` | Ein `vzdump` läuft gerade. Ebenfalls vorübergehend. |
Dauerhaft wiederkehrende Lock-Fehler sind dagegen ein Zeichen — siehe
[Fehlersuche](../nachschlagen/fehlersuche.md#storage-lock).
---
## Wenn viele VMs auf demselben Storage liegen
```ini
[global]
pause_between = 10s # Pause zwischen zwei Gästen
retries = 2 # zusätzliche Versuche je Snapshot
retry_delay = 60s # Wartezeit davor
task_timeout = 15m # Geduld mit einem einzelnen Proxmox-Task
```
`pause_between` nimmt Druck vom Storage-Lock, wenn dreißig Maschinen im selben
Pool nacheinander drankommen. Vorgabe ist `0s`; bei Problemen sind `5s` bis
`15s` ein guter erster Versuch.
---
## Überwachen
Ein einfacher Weg, im Blick zu behalten, ob die Sicherung wirklich läuft:
```bash
# Gab es in den letzten 25 Stunden einen taeglichen Snapshot?
pvesnap list | grep auto-taeglich | tail -1
```
Oder gezielt über den Dienstzustand:
```bash
systemctl is-active pvesnap # active / failed
journalctl -u pvesnap --since "-25h" -p err -q # leer = keine Fehler
```
!!! warning "Der Klassiker"
Der Dienst läuft, das Protokoll ist ruhig — und trotzdem entsteht nichts,
weil alle Gruppen auf `enabled = no` stehen. Genau so wird ausgeliefert.
`pvesnap status` zeigt es sofort: Eine ausgeschaltete Gruppe hat keinen
nächsten Termin.
+186
View File
@@ -0,0 +1,186 @@
# Der Konfigurationseditor
```bash
pvesnap config
```
Braucht `root` — der Editor schreibt nach `/etc/pvesnap/` und fragt Proxmox nach
dem Inventar.
Alles, was hier geht, geht auch von Hand in der INI-Datei. Der Editor hat aber
zwei Vorteile, die man beim Tippen nicht hat: Er zeigt **live, auf wie viele
Gäste eine Auswahl gerade zutrifft**, und er rechnet den **nächsten Termin**
aus, bevor man speichert.
---
## Die Gruppenliste
![Die Gruppenliste](../bilder/config-gruppen.svg)
Der Einstiegsbildschirm. Oben steht die Datei, an der gearbeitet wird, und
rechts daneben, ob der Dienst gerade läuft. Ein `*` vor dem Dateinamen bedeutet:
ungespeicherte Änderungen.
| Taste | |
|---|---|
| ++enter++ | Gruppe bearbeiten |
| ++space++ | Gruppe ein- oder ausschalten |
| ++n++ | neue Gruppe |
| ++c++ | Gruppe kopieren — der schnellste Weg zu einer Variante |
| ++d++ | Gruppe löschen |
| ++g++ | [globale Einstellungen](#globale-einstellungen) |
| ++v++ | [Übersicht: welche VM in welcher Gruppe?](#die-ubersicht) |
| ++s++ | speichern |
| ++r++ | [Dienst neu laden](#dienst-neu-laden) |
| ++q++ | Ende |
Die Spalte **Auswahl** fasst zusammen, wie die Gruppe ihre Gäste findet —
`Tags: produktion`, `alle VMs`, `VMIDs: 100-110`. Wer viele Gruppen hat, sieht
hier auf einen Blick, wo eine Maschine hineinfallen könnte.
---
## Eine Gruppe bearbeiten
![Eine Gruppe bearbeiten](../bilder/config-gruppe.svg)
Eine lange Maske in vier Abschnitten: **Allgemein**, **Zeitplan**,
**Vorhaltezeit**, **Welche VMs?**, **Snapshot-Optionen**. Pfeiltasten bewegen
sich, ++enter++ ändert ein Feld, ++space++ schaltet Ja/Nein um.
Zwei Zeilen darin sind keine Einstellungen, sondern Antworten:
!!! tip "Nächster Termin (Vorschau)"
```
Naechster Termin (Vorschau) Mo 10.08.2026 02:30 (taeglich um 02:30)
```
Rechnet sofort nach, was der eingestellte Zeitplan bedeutet. Damit fällt
ein Denkfehler auf, bevor er drei Wochen lang unbemerkt bleibt — etwa
`day_of_month = 31` in einem 30-Tage-Monat.
!!! tip "Trifft aktuell zu auf"
```
Trifft aktuell zu auf 6 Gast/Gaeste (100, 101, 102, 105, 110, 130)
```
Die Auswahlregeln, angewendet auf das echte Inventar — mitsamt VMIDs. Steht
dort `0 Gast/Gaeste`, ist meist ein Tag falsch geschrieben.
Oben in der Kopfzeile steht außerdem, wie die Snapshots dieser Gruppe heißen
werden:
```
Kurzname im Snapshot: auto-taeglich-JJJJMMTT-HHMMSS
```
---
## VMs aus einer Liste wählen
Auf dem Feld **VMs aus Liste wählen …** öffnet ++enter++ das Inventar; aus der
Gruppenmaske heraus geht auch direkt ++v++:
![Die VM-Auswahl](../bilder/config-vms.svg)
| Taste | |
|---|---|
| ++space++ | Gast an- oder abwählen |
| ++a++ | alle |
| ++n++ | keine |
| ++i++ | Auswahl umkehren |
| ++slash++ | filtern (Name, VMID oder Tag) |
| ++enter++ | übernehmen |
Die Spalte **Tags** ist der eigentliche Grund, hier hereinzuschauen: Sie zeigt,
womit die Gäste in Proxmox markiert sind — und damit, ob eine Auswahl über
`tags = …` besser wäre als eine feste Liste von VMIDs.
!!! note "Feste Listen altern schlecht"
Eine Auswahl über VMIDs muss bei jeder neuen VM angefasst werden. Eine
Auswahl über Tags nicht. Für alles, was länger als ein paar Wochen leben
soll, sind [Tags](auswahl.md#tags) die bessere Wahl.
---
## Globale Einstellungen
Taste ++g++ in der Gruppenliste:
![Globale Einstellungen](../bilder/config-global.svg)
Das gilt für alle Gruppen — Präfix, Prüfintervall, Wiederholungen bei belegter
Sperre, Standard-Beschreibung. Was welcher Wert genau bedeutet, steht unter
[Alle Einstellungen](../nachschlagen/konfiguration.md#global).
Der wichtigste ist **Testlauf (nichts wirklich tun)** — das `dry_run = yes` der
INI-Datei. Damit protokolliert der Dienst nur, was er täte. Zum Ausprobieren
einer neuen Konfiguration ohne Risiko.
---
## Die Übersicht
Taste ++v++ in der Gruppenliste:
![Übersicht: welche VM in welcher Gruppe](../bilder/config-uebersicht.svg)
Die Gegenprobe von der anderen Seite: nicht „welche Gäste hat diese Gruppe",
sondern **„in welchen Gruppen steckt dieser Gast"**. Wer hier steht, wird
gesichert. Wer `(keine Gruppe)` daneben stehen hat, nicht.
Das ist der Bildschirm, den man nach jeder Änderung einmal ansehen sollte. Er
deckt beide typischen Fehler auf: eine vergessene Maschine — und eine, die
versehentlich in vier Gruppen gleichzeitig liegt.
!!! example "Was hier auffällt"
Im Bild trägt `build-test` das Tag `nosnap` und fällt damit überall heraus —
gewollt. Die beiden Maschinen `db01-live` und `warenwirtschaft-w` sind
laufende [Wiederherstellungen](../wiederherstellen/index.md); sie stehen
ebenfalls in keiner Gruppe, weil die monatliche Gruppe
`exclude_tags = nosnap, pvesnap-recovery` gesetzt hat.
**Das ist ein Griff, der sich lohnt.** Ohne ihn bekämen kurzlebige
Wiederherstellungsmaschinen eigene Snapshots — die dann wiederum verhindern,
dass ihre Klone sauber verworfen werden können.
---
## Dienst neu laden
Taste ++r++ — entspricht `systemctl reload pvesnap`, ohne den Editor zu
verlassen. Der Editor nimmt einem dabei das Mitdenken ab:
<div class="ablauf" markdown>
Ungespeicherte Änderungen? → bietet vorher das Speichern an
Dienst gestoppt? → bietet das Starten an
Neuladen scheitert? → bietet einen Neustart an
</div>
Nach ++s++ fragt er ohnehin gleich, ob neu geladen werden soll. In der Kopfzeile
steht jederzeit, ob der Dienst läuft.
---
## Beim Speichern
!!! warning "Die INI-Datei wird neu geschrieben"
Eigene Kommentare gehen dabei verloren. Ein `[defaults]`-Abschnitt
ebenfalls — inhaltlich bleiben die Werte erhalten, sie stehen danach nur in
jeder Gruppe einzeln.
Eine Sicherung der alten Fassung wird als **`pvesnap.conf.bak`** abgelegt.
Wer eine handgepflegte Konfiguration mit vielen Kommentaren hat, bearbeitet sie
besser weiter im Texteditor. Der ncurses-Editor ist für alle anderen da — und
für die beiden Vorschauzeilen, die es im Texteditor nicht gibt.
+176
View File
@@ -0,0 +1,176 @@
# Sichern
Alles, was pvesnap tut, steckt in **Gruppen**. Eine Gruppe beantwortet drei
Fragen:
<div class="ablauf" markdown>
**Wann?** — [Zeitplan](zeitplan.md): alle 30 Minuten, täglich um 02:30, am
Monatsersten
**Wer?** — [Auswahl](auswahl.md): diese VMIDs, alles mit dem Tag `produktion`,
alle außer `nosnap`
**Wie lange?** — [Vorhaltezeit](vorhaltezeit.md): die letzten 24, nichts älter
als zwei Tage
</div>
Davon darf es beliebig viele geben, und eine VM darf in mehreren stecken. Genau
das ist der Sinn: Die Datenbank bekommt stündliche Snapshots mit kurzer
Vorhaltezeit, dieselbe Datenbank zusätzlich einen monatlichen, der ein Jahr
liegen bleibt.
---
## Ein typischer Aufbau
```ini
[group:stuendlich]
interval = 1h
align = yes # an der Uhr: 00:00, 01:00, 02:00 ...
keep_count = 24
keep_time = 2d
tags = stuendlich
skip_stopped = yes
[group:taeglich]
schedule = daily
at = 02:30
keep_count = 14
keep_time = 21d
tags = produktion
exclude_tags = nosnap
[group:monatlich]
schedule = monthly
day_of_month = 1
at = 04:00
keep_count = 6
keep_time = 400d
all = yes
exclude_tags = nosnap
```
Drei Gruppen, drei Zeithorizonte. Die Datenbank mit den Tags
`produktion,stuendlich` landet in allen dreien — und hat damit den Stand von
vor einer Stunde, von gestern Nacht und vom Monatsersten.
So sieht das im Editor aus:
![Die Gruppenliste](../bilder/config-gruppen.svg)
---
## Namensschema
Jeder Snapshot heißt nach demselben Muster:
```
auto-taeglich-20260809-023000
│ │ │ └── Uhrzeit
│ │ └────────── Datum
│ └──────────────────── Kurzname der Gruppe
└─────────────────────────── prefix aus [global]
```
Das ist keine Kosmetik, sondern die **Sicherheitsgrenze** des ganzen Programms.
!!! success "pvesnap löscht ausschließlich, was exakt auf dieses Muster passt"
Und zusätzlich muss der Gruppen-Kurzname zu einer Gruppe gehören, die
gerade aufräumt. Ein Snapshot namens `vor-update-14.2` oder
`bkp_20260101` wird nie angefasst — egal wie alt er ist, egal wie voll das
Storage läuft.
Umlaute und Sonderzeichen im Gruppennamen werden für den Kurznamen
umgeschrieben (`täglich` → `taeglich`). Ergäben zwei Gruppen denselben
Kurznamen, meldet das `pvesnap check` — sonst würden sie sich gegenseitig die
Snapshots wegräumen.
!!! warning "Gruppe umbenennen"
Der neue Name bekommt einen eigenen Kurznamen. Snapshots unter dem alten
Namen passen dann zu keiner Gruppe mehr und werden **nicht mehr
aufgeräumt** — sie bleiben für immer liegen. Entweder vorher aufräumen
lassen oder die alten hinterher von Hand entfernen.
---
## Der Ablauf eines Laufs
Der Dienst schaut alle `check_interval` (Vorgabe: 60 s) nach, ob eine Gruppe
fällig ist. Ist sie es:
1. **Gäste bestimmen** — nach den Auswahlregeln der Gruppe
2. **Snapshot anlegen**, ein Gast nach dem anderen; dazwischen optional
`pause_between`
3. **Warten, bis Proxmox wirklich fertig ist** — nicht nur, bis der Aufruf
zurückkommt
4. **Aufräumen** — alles, was `keep_count` oder `keep_time` reißt
Schritt 3 ist wichtiger, als er aussieht. Proxmox nimmt beim Anlegen eine
Sperre auf dem Storage (`cfs-lock 'storage-<name>'`). Würde pvesnap gleich die
nächste VM anstoßen, sperrten sich die eigenen Läufe gegenseitig aus. Mehr dazu
unter [Fehlersuche](../nachschlagen/fehlersuche.md#storage-lock).
Wird ein Termin verpasst, weil der Host aus war, wird er beim nächsten Start
**nachgeholt** — einmal, nicht für jeden ausgefallenen Termin einzeln.
---
## Was in einen Snapshot gehört
| Einstellung | Vorgabe | |
|---|---|---|
| `vmstate` | `no` | Arbeitsspeicher mitsichern — nur QEMU, nur bei laufender VM |
| `skip_stopped` | `no` | gestoppte Gäste überspringen |
| `description` | siehe unten | Beschreibung, die am Snapshot hängt |
### `vmstate` — der Arbeitsspeicher
Mit `vmstate = yes` wird der RAM mitgeschrieben. Die Maschine friert dafür kurz
ein, und es braucht Platz in Höhe des zugewiesenen Arbeitsspeichers — bei einer
32-GB-Datenbank also 32 GB **pro Snapshot**.
Für regelmäßige Läufe ist das meist zu teuer. Es hat aber einen konkreten
Nutzen: Beim [Wiederherstellen](../wiederherstellen/index.md) läuft die
Maschine dann genau dort weiter, wo sie stand — statt zu booten wie nach einem
Stromausfall. Datenbanken sind dabei bereits offen und konsistent.
!!! tip "Der Mittelweg"
Eine eigene Gruppe mit `vmstate = yes`, die einmal täglich läuft und nur
zwei Stände vorhält. Kostet zweimal RAM-Größe und gibt im Ernstfall einen
warmen Einstiegspunkt.
### Die Beschreibung
Sie steht in der Proxmox-Oberfläche neben jedem Snapshot:
```ini
description = pvesnap | Gruppe: {group} | erstellt: {datetime} | Vorhaltezeit: {keep_time} | max: {keep_count}
```
Verfügbare Platzhalter:
| | | |
|---|---|---|
| `{group}` | `{group_slug}` | `{schedule}` |
| `{vmid}` | `{name}` | `{node}` |
| `{type}` | `{pool}` | `{tags}` |
| `{date}` | `{time}` | `{datetime}` |
| `{timestamp}` | `{keep_time}` | `{keep_count}` |
Ein unbekannter Platzhalter führt nicht zum Abbruch — es wird dann eine
brauchbare Ersatzbeschreibung eingesetzt.
---
## Weiter
* [Der Konfigurationseditor](editor.md) — alles das mit Menüs statt INI-Datei
* [Zeitpläne](zeitplan.md)
* [Welche Gäste?](auswahl.md)
* [Vorhaltezeit](vorhaltezeit.md)
* [Im Betrieb](betrieb.md) — Dienst, Protokoll, Probelauf
+159
View File
@@ -0,0 +1,159 @@
# Vorhaltezeit
Ohne Aufräumen wächst die Zahl der Snapshots ins Unendliche — und jeder hält
alte Blöcke fest. Die Vorhaltezeit ist deshalb keine Kür.
```ini
keep_count = 24 # höchstens 24 Snapshots je VM und Gruppe (0 = unbegrenzt)
keep_time = 7d # nichts älter als 7 Tage (0 = unbegrenzt)
keep_min = 1 # so viele bleiben in jedem Fall stehen
```
---
## Die beiden Grenzen
Beide sind kombinierbar. Gelöscht wird, was **eine** der beiden reißt — es ist
ein ODER, kein UND.
!!! example "Beispiel: `keep_count = 24`, `keep_time = 2d`"
Eine stündliche Gruppe. Nach zwei Tagen sind 48 Snapshots angefallen —
`keep_count` greift und lässt nur die letzten 24 stehen.
Läuft eine VM zwei Wochen lang nicht (mit `skip_stopped = yes`), sind ihre
Snapshots irgendwann älter als zwei Tage — `keep_time` greift und räumt sie
weg, auch wenn es weniger als 24 sind.
**Mindestens eine der beiden muss gesetzt sein.** Sonst würde die Zahl der
Snapshots unbegrenzt wachsen; `pvesnap check` meldet das als Fehler.
---
## `keep_min` — die Untergrenze
```ini
keep_min = 1
```
So viele Snapshots bleiben in jedem Fall stehen, auch wenn sie beide Grenzen
reißen.
Der Sinn: `keep_time = 2d` würde bei einer Maschine, die drei Tage aus war,
**alles** löschen — und damit den letzten bekannten Stand. Mit `keep_min = 1`
bleibt immer einer übrig.
!!! tip "Eine Empfehlung"
`keep_min = 1` in jeder Gruppe mit `keep_time`. Es kostet fast nichts und
verhindert den einen Fall, in dem das Aufräumen genau das wegräumt, was man
gebraucht hätte.
---
## Getrennt je VM und Gruppe
Beide Grenzen zählen **pro Gast und pro Gruppe**, nicht insgesamt.
`keep_count = 24` bei 30 Maschinen heißt also: bis zu 720 Snapshots — aber je
Maschine nur 24. Und eine VM, die in drei Gruppen steckt, hat 24 + 14 + 6
Snapshots nebeneinander, die sich nicht gegenseitig verdrängen.
---
## Was pvesnap anfasst — und was nicht
Aufgeräumt wird ausschließlich, was zum
[Namensschema](index.md#namensschema) der jeweiligen Gruppe passt:
```
auto-taeglich-20260809-023000 ← wird von der Gruppe "taeglich" gezählt
auto-stuendlich-20260809-100000 ← zählt für "stuendlich", nicht für "taeglich"
vor-update-14.2 ← wird nie angefasst
```
!!! success "Von Hand angelegte Snapshots bleiben"
Ein Snapshot, den jemand in der Proxmox-Oberfläche angelegt hat, passt nie
auf das Muster. Er zählt weder gegen `keep_count`, noch wird er jemals
gelöscht.
Das hat eine Kehrseite: Er wird auch nicht aufgeräumt. Wer sich vor einem
Update einen Sicherheitsstand anlegt, sollte ihn hinterher selbst wieder
entfernen — sonst hält er ewig alte Blöcke fest.
---
## Nur aufräumen, ohne Neues anzulegen
```bash
pvesnap prune # alle Gruppen
pvesnap prune -g stuendlich # nur diese
pvesnap prune --dry-run # zeigt, was wegkäme
```
Praktisch nach dem Verkürzen einer Vorhaltezeit: Der Dienst würde erst beim
nächsten regulären Termin aufräumen, `prune` macht es sofort.
---
## Platz im Blick behalten
```bash
pvesnap list # alle pvesnap-Snapshots
pvesnap list -a # auch fremde
```
Und auf dem Storage selbst:
=== "Ceph / RBD"
```bash
ceph df # MAX AVAIL beachten, nicht nur % RAW USED
rbd -p <pool> du # PROVISIONED gegen USED
```
=== "ZFS"
```bash
zfs list -o space # USEDSNAP zeigt, was die Snapshots kosten
```
=== "LVM-thin"
```bash
lvs -o lv_name,data_percent,metadata_percent
```
!!! danger "Ein volles Storage blockiert alles"
Läuft ein Ceph-Pool oder ein Thin-Pool voll, stehen **alle** Volumes darin
— nicht nur die schreibfreudige VM. Und das Aufräumen wird dann selbst
schwierig, weil Löschen ebenfalls ein Schreibvorgang ist.
Bei Ceph ist `MAX AVAIL` die Zahl, auf die es ankommt; `% RAW USED` täuscht,
weil es die Replikation nicht berücksichtigt.
---
## Wie viel kostet ein Snapshot?
Anfangs: nichts. Ein Snapshot ist ein Zeiger, kein Abbild.
Er wächst mit dem, was **danach** geschrieben wird — jeder geänderte Block
bedeutet, dass der alte Stand zusätzlich vorgehalten werden muss.
| VM | Verhalten |
|---|---|
| Ein Fileserver, auf dem selten geschrieben wird | Snapshots kosten fast nichts, lange Vorhaltezeiten sind billig |
| Eine Datenbank mit ständigem Schreibverkehr | Jeder Snapshot wächst spürbar; kurze Vorhaltezeit, dafür engmaschig |
| Eine VM, die gerade ein Update bekommt | Ein einzelner Snapshot kann in Minuten mehrere GB kosten |
Deshalb passen kurze Intervalle und lange Vorhaltezeiten schlecht zusammen. Ein
guter Ausgangspunkt:
```ini
[group:stuendlich] keep_count = 24 keep_time = 2d
[group:taeglich] keep_count = 14 keep_time = 21d
[group:monatlich] keep_count = 6 keep_time = 400d
```
+129
View File
@@ -0,0 +1,129 @@
# Zeitpläne
Jede Gruppe hat **entweder** ein Intervall **oder** einen festen Termin. Beides
gleichzeitig geht nicht — `pvesnap check` weist darauf hin.
---
## Intervall
```ini
interval = 30m # 30m, 1h, 6h, 2d12h, 1w ...
align = yes
```
Zeitangaben gelten überall im selben Format: `30m`, `1h`, `6h`, `2d12h`, `1w`.
`0` heißt „unbegrenzt".
Der Unterschied steckt in `align`:
| | |
|---|---|
| `align = yes` | **an der Uhr ausgerichtet** — 00:00, 00:30, 01:00 … Die Snapshots liegen auf runden Zeiten, unabhängig davon, wann der Dienst gestartet wurde. |
| `align = no` | **30 Minuten nach dem letzten Lauf.** Startet der Dienst um 14:07 neu, liegen die Snapshots danach bei :07 und :37. |
Für alles, was regelmäßig aussehen soll, ist `align = yes` die richtige Wahl.
`align = no` ist nur dann sinnvoll, wenn der Abstand wichtiger ist als der
Zeitpunkt.
---
## Fester Termin
```ini
schedule = daily
at = 02:30
```
| `schedule` | zusätzliche Angaben | ergibt |
|---|---|---|
| `hourly` | `minute = 15` | jede Stunde um :15 |
| `daily` | `at = 02:30` | täglich um 02:30 |
| `weekly` | `at`, `day_of_week = so` | sonntags um 03:00 |
| `monthly` | `at`, `day_of_month = 1` | am 1. jedes Monats |
| `yearly` | `at`, `day_of_month`, `month` | einmal jährlich |
Wochentage: `mo di mi do fr sa so` (auch `mon`, `tue` … funktionieren).
### Der 31. in kurzen Monaten
```ini
schedule = monthly
day_of_month = 31
```
Wird automatisch auf den **letzten Tag des Monats** gezogen — im Februar also
auf den 28. bzw. 29. Kein ausgefallener Lauf, keine Sonderbehandlung nötig.
---
## Verpasste Termine
Läuft der Host zum Termin nicht, wird der Lauf beim nächsten Start
**nachgeholt**. Einmal — nicht für jeden ausgefallenen Termin einzeln.
Ein Host, der eine Woche aus war, legt beim Hochfahren also einen täglichen
Snapshot an, nicht sieben.
Merken tut sich das die Zustandsdatei:
```ini
[global]
state_file = /var/lib/pvesnap/state.json
```
Wird sie gelöscht, gilt jede Gruppe als „noch nie gelaufen" und wird beim
nächsten Prüfintervall sofort ausgeführt.
---
## Beim Start sofort loslegen
```ini
[global]
run_on_start = no
```
Mit `yes` macht der Dienst direkt nach dem Start einen Durchlauf, statt auf den
nächsten regulären Termin zu warten.
Auf einem Host, der oft neu startet, führt das zu vielen zusätzlichen
Snapshots. Vorgabe ist deshalb `no`.
---
## Die Zeitumstellung
!!! warning "Gerechnet wird mit lokaler Zeit"
Ein täglicher Termin um 02:30 kann in der Umstellungsnacht **ausfallen**
(im Frühjahr existiert 02:30 nicht) oder **doppelt anstehen** (im Herbst
gibt es sie zweimal).
Wen das stört, legt den Termin auf eine Zeit außerhalb des Fensters —
04:00 statt 02:30 — oder nimmt ein Intervall statt eines festen Termins.
---
## Wie oft ist richtig?
Es gibt keine allgemeingültige Antwort, aber eine brauchbare Faustregel: Der
Abstand ist die Datenmenge, die du im Ernstfall verlierst.
| Abstand | Verlust im schlimmsten Fall | Passt zu |
|---|---|---|
| 15 min | eine Viertelstunde Arbeit | Datenbanken, Warenwirtschaft |
| 1 h | eine Stunde | Anwendungsserver |
| täglich | ein Arbeitstag | Fileserver, Infrastruktur |
| monatlich | — | der lange Rückweg, „wie war es vor dem Update?" |
Was dagegen spricht, öfter zu sichern, ist der **Platz**: Jeder Snapshot hält
die alten Blöcke fest. Bei einer schreibfreudigen VM wächst das schnell. Deshalb
gehören kurze Intervalle immer mit kurzer [Vorhaltezeit](vorhaltezeit.md)
zusammen — 24 stündliche Snapshots über zwei Tage sind billiger als sieben
tägliche über eine Woche.
!!! tip "Gestoppte Gäste überspringen"
Bei kurzen Intervallen lohnt sich `skip_stopped = yes`. Sonst sammelt eine
abgeschaltete Test-VM stündlich Snapshots vom immer gleichen Zustand.