In „Kanboard im Container“ habe ich einen Pod ins Leben gerufen, welcher die Anwendung Kanboard und eine dazugehörige Postgresql-Datenbank mittels Container bereitstellt. Backup und Restore zu konfigurieren und zu testen, habe ich letztes Wochenende nicht mehr geschafft. Dies hole ich in diesem Artikel nach.
Da die Container selbst zustandslos sind, interessieren mich nur die persistent gespeicherten Daten, welche außerhalb der Container im Dateisystem des Hosts gespeichert werden.
Umgebung
Auf einer virtuellen Maschine mit dem Gastbetriebssystem RHEL 8 läuft ein podman
-Pod namens kanboardpod. Dieser Pod beinhaltet neben dem Infrastruktur-Container, einen Kanboard-Container namens kanboard und einen Postgresql-Container namens pgsql_db.
Die persistenten Daten des Kanboard-Containers werden in den Volumes kanboard_data und kanboard_plugins gespeichert. Die Datenbank-Dateien der Postgresql-DB liegen im Volume pgsql_data.
Die Namen des Pods und der Container sind hilfreich, da die Container darüber referenziert werden können. So muss man nicht mit den sperrigen IDs hantieren.
Backup
Kein Restore ohne Backup! Kein Backup, kein Mitleid!
Ich habe im Folgenden beschriebe Ansätze für ein Backup. Wenn ihr noch weitere habt, freue ich mich über eure Eingaben.
Ansatz 1: Backup auf Dateiebene — verworfen
Dieser Ansatz liegt nahe und ist einfach umzusetzen.
- Container stoppen
- Verzeichnisse im Dateisystem sichern
- Container wieder starten
Für meinen konkreten Anwendungsfall wäre dies auch ausreichend. Einen Dienst für die Dauer einer Datensicherung komplett stoppen zu müssen, ist jedoch nicht ideal. Daher schaue ich nach weiteren Möglichkeiten.
Ansatz 2: DB-Dump und Datei-Backup — Praktikabel aber möglicherweise inkonsistent.
Bei diesem Ansatz bleibt die Anwendung während der Datensicherung verfügbar. Während das Volume kanboard_data auf Dateiebene mittels tar
gesichert wird, wird die Datenbank mittels pg_dump
aus dem Container heraus gesichert. Das Backup-Skript sieht wie folgt aus:
#!/bin/bash
kanboard_data=$(podman volume inspect kanboard_data --format {{.Mountpoint}})
kanboard_plugins=$(podman volume inspect kanboard_plugins --format {{.Mountpoint}})
tar czf kanboardfiles.tgz $kanboard_data $kanboard_plugins
podman exec -t pgsql_db /usr/bin/pg_dump kanboard | gzip > ~/kanboard.sql.gz
Hinweis: Obiger Code-Schnipsel stammt aus der Kategorie Schnell-und-Schmutzig und sollte nicht in produktiven Umgebungen verwendet werden.
Der DB-Dump wird dabei direkt aus dem Container in mein Home-Verzeichnis geschrieben. Am Ende habe ich zwei unabhängige Dateien, die nun außerhalb der Container-Umgebung liegen. Da diese jedoch immer noch auf dem gleichen Host liegen, handelt es sich um kein richtiges Backup. Doch ist es nun nicht mehr schwer, sie auf ein anderes, entferntes Medium zu übertragen.
Der größte Nachteil dieses Ansatzes besteht darin, dass die Konsistenz der Sicherung nicht garantiert ist. Die Datenbank enthält Referenzen in das Dateisystem. Referenzen in der Datenbank und Inhalt des gesicherten Dateisystems müssen nicht in jedem Fall zueinander passen, da während der Sicherung weiter in der Anwendung gearbeitet werden kann.
Nun kann man natürlich vor der Sicherung den Container kanboard stoppen und anschließend wieder starten. Damit erhält man eine konsistente Sicherung zu dem Preis, dass die Anwendung temporär nicht verfügbar ist. Damit unterscheidet sich der Ansatz gegenüber Ansatz 1 nur noch darin, dass der Container pgsql_db online bleibt und man die DB mit pg_dump
sichert, statt eine Sicherung auf Dateisystemebene zu machen.
Schön ist das nicht, doch mache ich es meiner Umgebung genau so.
Ansatz 3: Backup auf Basis eines konsistenten Dateisystem-Snapshots
Dies ist in meinen Augen der vernünftigste Ansatz.
Die persistenten Daten der Container liegen in einem Dateisystem. Unterstützt dieses Dateisystem Snapshots, können diese genutzt werden, um die Dateisysteminhalte zum Zeitpunkt des Snapshots auf das Backup-Medium zu übertragen und den Snapshot anschließend wieder zu entfernen. Anwendung und Datenbank können bei diesem Verfahren während der Sicherung weiterlaufen.
Das so erstellte Datenbank-Backup befindet sich allerdings in einem Zustand, als wäre die Datenbank unsauber beendet worden. Nach einem Restore werden demnach die WAL-Logs benötigt (siehe PostgreSQL 9.6.20 Documentation: 25.2. File System Level Backup).
Ich habe mich gegen diesen Ansatz entschieden, da mir in meiner Test-Umgebung noch die Erfahrung mit Dateisystem-Snapshots fehlt. Dies werde ich evtl. zu einem späteren Zeitpunkt unter die Lupe nehmen.
Restore
Ich habe mich für den Ansatz 2 entschieden. Damit habe ich folgende zwei Dateien:
- kanboard.tgz – Enthält die persistenten Daten des Kanboards
- kanboard.sql.gz – Enthält den Dump der Kanboard-Datenbank
Das tar
-Archiv wird extrahiert und fertig. Um den DB-Dump mit dem Werkzeug pg_restore
wieder einspielen zu können, muss dieser zuvor in ein Volume kopiert werden, das innerhalb des Postgresql-Containers zur Verfügung steht. Anschließend kann die Datenbank mit folgendem Befehl wiederhergestellt werden:
# pg_restore -C -d kanboard kanboard.sql
Fazit
Grundsätzlich habe ich Ziel Nummer 5 „Backup und Restore“ ebenfalls erreicht.
Der Restore erfordert noch einiges an Handarbeit und ist etwas fummelig. Soetwas möchte man in einer angespannten Situation nicht gerne haben. Hier ist noch etwas Feinschliff nötig.
Darüber hinaus kann ich mir vorstellen auch noch einen automatisierten Restore-Test zu etablieren, welcher prüft, ob sich ein erstellter DB-Dump auch wieder herstellen lässt. Das ist dann aber sicher ein eigenes Wochenendprojekt. Und nächstes Wochenende mache ich mal frei.
Pingback: Mit Dokumentation zum Datenverlust | My-IT-Brain
Pingback: Kanboard im Container… | My-IT-Brain
Pingback: Nextcloud im Container – Teil 5: Backup und Restore | My-IT-Brain
Pingback: Nextcloud im Container – Teil 1: Der Plan | My-IT-Brain