Der Nachtfahrplan: Backups und Jobs ohne Kollisionen

Schema: Nachtfahrplan von 01:00 bis 08:00 Uhr mit Datenbank-Dumps vor dem Proxmox-Backup und anschließenden Wartungsjobs ohne Kollisionen

Verfasst von

in

In meinem Homelab sammeln sich über die Monate dutzende Hintergrundaufgaben an: der Proxmox Backup Server sichert jede Nacht die VMs und Container, davor schreiben Datenbanken und Domänencontroller ihre Stände weg, danach räumen Prune-Jobs und Prüfungen auf. Solange jeder Dienst seinen Zeitplan nur in der eigenen Crontab oder Aufgabenplanung kennt, merkt niemand, wenn ein Datenbank-Dump mitten in die laufende VM-Sicherung fällt oder die Zeitumstellung zwei Jobs ineinander schiebt. Ich habe deshalb alle Zeitpläne in einer zentralen Datenbank zusammengeführt, die echten Laufzeiten über mehrere Nächte gemessen und die stillen Kollisionen aufgelöst.

Schema: Nachtfahrplan von 01:00 bis 08:00 Uhr mit Datenbank-Dumps vor dem Proxmox-Backup und anschließenden Wartungsjobs ohne Kollisionen

Verstreute Zeitpläne und zwei Zeitzonen

Wer in einer gewachsenen Umgebung nachschauen will, was nachts zwischen ein und acht Uhr passiert, muss an mehreren Stellen suchen. Je nach Betriebssystem und Dienst liegen die Auslöser getrennt: klassische Crontabs (crontab -l) und Systemd-Timer (systemctl list-timers) unter Linux, die clusterweite Sicherungs- und Replikationsplanung in Proxmox VE, eigene Wartungsjobs für Prune, Verify und Garbage Collection auf dem Proxmox Backup Server (proxmox-backup-manager prune-job list und verify-job list), interne Zeitpläne in der GitLab-Instanz sowie die Aufgabenplanung auf den Windows-Servern (Get-ScheduledTask -TaskPath \).

Zu den verstreuten Ablageorten kam in meinem Aufbau ein zweites Problem: gemischte Zeitzonen. Während die Proxmox-Knoten, der Backup-Server und die Windows-Maschinen in mitteleuropäischer Zeit (Europe/Berlin, im Sommer CEST = UTC+2) liefen, standen der Admin-Container und die GitLab-Instanz auf UTC. Ein Cronjob, der auf GitLab für 03:00 eingetragen ist, startet im Sommer um 05:00 Uhr Ortszeit und im Winter um 04:00 Uhr.

Noch tückischer verhält sich die Windows-Aufgabenplanung. Setzt man beim Anlegen eines Triggers den Haken bei „Über Zeitzonen synchronisieren“, speichert Windows die Startzeit mit festem Versatz (zum Beispiel +02:00). Nach dem Wechsel auf Normalzeit laufen diese Aufgaben plötzlich eine Stunde früher in Ortszeit. Bei mir betraf das die System-State-Sicherung der Domänencontroller, eine nächtliche Laufwerksprüfung und den wöchentlichen SMART-Kurztest.

Bestandsaufnahme: Typische Kollisionen im alten Plan

Für die erste Bestandsaufnahme habe ich die nächtlichen Termine aus der Dokumentation und den Systemen in eine Datenbank übernommen. Weil in den bestehenden Listen fast überall nur die Startzeit stand, musste ich das späteste Ende zunächst schätzen – für die nächtliche PBS-Sicherung aller Gäste ab 02:15 Uhr standen pauschal 04:00 Uhr im Plan. Schon beim ersten Abgleich zwischen den Systemen und meinen Notizen tauchte zudem ein Synchronisationsjob in einer Crontab auf, der in der handgepflegten Übersicht komplett fehlte.

Mit einfachen Ausschlussregeln in der Datenbank – während eines Backups darf am selben System weder ein zweites Backup noch eine Wartung, Migration oder Prüfung laufen – habe ich den Plan über mehrere Wochen durchgerechnet. Dabei zeigten sich vier typische Überschneidungen:

Beteiligte JobsAlte ZeitenProblem im Betrieb
PBS-Sicherung × Datenbank-Dumps02:15–04:00 × 03:30 / 03:50Datenbank-Sicherungen in den Gästen starten mitten im geschätzten VM-Backup-Fenster
GitLab-Backup × Abholen03:00 UTC × 03:40 UTCAbhol-Job zieht das Archiv nach starrer Uhrzeit ab, ohne das echte Ende der Erstellung zu kennen
Wartungsfenster × PBS-Sicherung00:30–02:30 UTC × 02:15 OrtszeitFester UTC-Job verschiebt sich mit der Normalzeit in das lokale Backup-Fenster
PBS-Verify × Prune und GC04:00 (am 1.) × 05:30 / 06:00Monatlicher Verify läuft über den Start von täglichem Prune und sonntäglicher Garbage Collection hinaus

Besonders der erste Punkt ist ein Klassiker: Wenn der Datenbank-Dump auf einem Server erst um 03:30 Uhr oder 03:50 Uhr anläuft, hat der Proxmox Backup Server die virtuelle Maschine ab 02:15 Uhr längst gesichert. Im Backup auf dem PBS landet damit der Datenbankstand der vorigen Nacht, oder der Dump schreibt genau in dem Moment auf die Platte, in dem vzdump den Snapshot zieht.

Messen statt schätzen: Wie lang laufen die Jobs wirklich?

Bevor ich Zeiten blind verschoben habe, wollte ich wissen, wie lang die Aufgaben in der Praxis brauchen. Ein Plan, der jedem Job pauschal eine bis zwei Stunden reserviert, blockiert die halbe Nacht, obwohl die Systeme die meiste Zeit leerlaufen. Deshalb melden die wichtigen Jobs ihren echten Start und ihr Ende an die Datenbank.

Die Anbindung richtet sich nach dem jeweiligen Dienst. Auf den Proxmox-Knoten klinkt sich ein Hook-Skript in vzdump bei den Phasen job-start, job-end und job-abort ein; weil alle Knoten denselben Cluster-Job abarbeiten, gilt der Termin erst als beendet, wenn der letzte Knoten sein Ende gemeldet hat. Bei Cronjobs und Systemd-Timern übernimmt ein kleiner Wrapper vor dem eigentlichen Befehl die Start- und Endemeldung. Der Proxmox Backup Server bietet für interne Aufgaben wie Prune, Verify und Garbage Collection keine eigenen Hooks an – hier liest ein Skript alle zehn Minuten die Aufgabenliste des PBS aus und trägt Start und Ende anhand der Task-UPID nach. Schlägt eine Meldung fehl, läuft der eigentliche Sicherungs- oder Wartungsjob trotzdem normal weiter.

Nach fünf Nächten mit echten Messwerten sah das Bild deutlich anders aus als meine Schätzungen:

TerminStartzeitGemessene Laufzeit (5 Nächte)Spätestes Ende (neu vs. alt)
Datenbank-Dump in VM01:45 Ortszeit35 Sekunden (01:45:16 bis 01:45:50)01:50 (vorher 02:00 geschätzt)
PBS-Sicherung aller Gäste02:15 Ortszeitlängster Knoten 20,5 min, Ende bis 02:35:3803:00 (vorher 04:00 geschätzt)
GitLab-Sicherung erstellen03:00 UTC24 Sekunden (0,4 Minuten)03:15 UTC (Reserve bleibt)
GitLab-Sicherung abholen03:20 UTC6 Sekunden (0,1 Minuten)03:25 UTC (vorher 03:30 UTC)
Nächtlicher Inventarlauf04:15 UTCnormal 6 bis 7 min (einmalig 299 min Hänger)05:30 UTC bleibt bis Ursache geklärt

Die wichtigste Erkenntnis war die Dauer des großen PBS-Laufs: Die gesicherten VMs und Container über die Knoten hinweg sind dank Deduplizierung und Dirty-Bitmaps nach gut 20 Minuten durch. Um 02:36 Uhr ist der Backup-Server fertig; fast anderthalb Stunden der alten Sperrzeit waren reine Schätzreserve.

Gleichzeitig haben die fünf Messnächte sofort einen Ausreißer sichtbar gemacht: Ein täglicher Dokumentations- und Inventarlauf braucht normalerweise sechs bis sieben Minuten, hing aber in einer Nacht für 299 Minuten fest. Solche Hänger sieht man ohne zentrale Laufzeiterfassung erst, wenn am nächsten Morgen Folgejobs in den noch laufenden Prozess krachen. Statt das Zeitfenster blind zu verkürzen, bleibt dort das späteste Ende stehen, bis der Hänger im Skript abgestellt ist.

Der aufgeräumte Nachtfahrplan

Mit den Messwerten ließen sich die Kollisionen gezielt beseitigen. Den ersten Datenbank-Dump (35 Sekunden Laufzeit) habe ich von 03:30 Uhr auf 01:45 Uhr Ortszeit vorgezogen und den Trigger in der Windows-Aufgabenplanung ohne festen UTC-Versatz gespeichert, damit er auch nach der Zeitumstellung auf 01:45 Uhr bleibt. Ein zweiter Datenbank-Dump auf einem Linux-Server wanderte per Systemd-Drop-in von 03:50 Uhr auf 01:50 Uhr. Wenn um 02:15 Uhr der Proxmox-Backup-Job startet, liegen beide Datenbankstände frisch auf der jeweiligen virtuellen Platte und wandern direkt mit in den PBS.

Am anderen Ende der Nacht ist die GitLab-Kette entzerrt: Um 03:00 UTC erzeugt die GitLab-Instanz ihr Backup in knapp einer halben Minute. Der Abhol-Job startet um 03:20 UTC statt 03:40 UTC, kopiert das Archiv in sechs Sekunden auf einen anderen Server und ist um 03:25 UTC fertig – mit genug Abstand, bevor um 05:30 Uhr Ortszeit die täglichen Vergleichsläufe starten, der PBS sein tägliches Prune (7 tägliche, 4 wöchentliche, 6 monatliche Stände) anstößt und die Zertifikatsprüfung läuft. Wo zwei Schritte direkt voneinander abhängen, ist der Start nach dem gemeldeten Ende des Vorgängers ohnehin zuverlässiger als ein starrer Uhrzeit-Abstand mit geratenem Puffer.

Auch für Dienste, die tagsüber im Minuten- oder Halbstundentakt laufen, lohnt sich ein Blick auf die Nachtstunden. Der Build-Dienst der Dokumentation prüft zwar jede Minute auf Dateiänderungen, pausiert aber komplett zwischen 02:00 und 04:00 Uhr Ortszeit sowie während des nächtlichen Inventarlaufs. ZFS-Replikationen zwischen den Proxmox-Knoten (je nach Dienst alle 15, 30 oder 60 Minuten) laufen dagegen auf Storage-Ebene durch.

Damit der aufgeräumte Plan im Alltag nicht wieder auseinanderläuft, dient der Betriebskalender in der Datenbank gleichzeitig als aktive Sperre vor Wartungen und Neustarts (wie der Kalender selbst aufgebaut ist, steht in einem eigenen Artikel). Ein nächtlicher Job gleicht außerdem die realen Crontabs, Timer und Aufgabenplanungen lesend mit der Datenbank ab und meldet Abweichungen sofort. Überzieht ein Job sein geplantes Ende oder bleibt wie beim 299-Minuten-Hänger die Endemeldung aus, schlägt Checkmk an, während für geplante Wartungen automatisch vorab Downtimes im Monitoring eingetragen werden.

Was noch offen ist

Drei Punkte arbeite ich in den nächsten Tagen noch ab. Erstens ziehe ich die letzten auf UTC konfigurierten Linux-Systeme komplett auf Europe/Berlin nach, damit sich feste Wartungsfenster bei der Zeitumstellung nicht mehr gegen die lokale PBS-Sicherung um 02:15 Uhr verschieben. Zweitens steht für den monatlichen PBS-Verify am Monatsersten ab 04:00 Uhr noch das geschätzte Ende von 08:00 Uhr im Plan, was rechnerisch mit dem täglichen Prune um 05:30 Uhr und der sonntäglichen Garbage Collection um 06:00 Uhr überlappt – dort warte ich den nächsten Lauf am Ersten ab, um die tatsächliche Dauer aus der Aufgabenliste des Backup-Servers zu übernehmen. Drittens bekommt der Systemd-Timer für den Datenbank-Dump um 01:50 Uhr noch den Melde-Wrapper, damit nachfolgende Aufgaben direkt auf die echte Fertigstellung statt auf die Uhrzeit prüfen können.

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht, deine IP-Adresse wird nicht gespeichert. Kommentare erscheinen erst nach Freigabe. Was mit deinen Angaben passiert, steht in der Datenschutzerklärung. Pflichtfelder sind mit * markiert.