Backup-Strategie
Funktionsweise von K8up: K8up ist ein Kubernetes-nativer Backup-Operator, der auf dem Restic-Framework basiert und Backups über deklarative Custom Resources (CRs) verwaltet. Der K8up-Operator läuft kontinuierlich im Cluster und überwacht Schedule-Ressourcen, die Cron-basierte Backup-Zeitpläne definieren. Wenn ein definierter Zeitpunkt erreicht wird, erstellt der Operator automatisch entsprechende Kubernetes Jobs für verschiedene Backup-Operationen:
-
Backup: Sichert PersistentVolumes und führt optionale PreBackupPods aus (z.B. für Datenbank-Dumps)
-
Check: Überprüft die Integrität des Backup-Repositories
-
Prune: Entfernt alte Snapshots basierend auf definierten Retention-Policies
-
Archive: Erstellt langfristige Archivierungen (z.B. zu S3 Glacier) für Compliance-Anforderungen
-
Restore: Ein CRD, das den Prozess der Datenwiederherstellung definiert.
Einschränkung: K8up automatisiert ausschließlich die Wiederherstellung von Daten auf Persistent Volume Claims (PVCs) ("File-Level Restore"). Eine anwendungsspezifische Logik (z.B. Import von Datenbank-Dumps nach dem Dateirestore) wird von K8up nicht nativ unterstützt und erfordert nachgelagerte manuelle oder skriptgesteuerte Schritte.
openDesk SaaS Backup Prozedur mit K8up
Alle Backup-Daten werden verschlüsselt und dedupliziert über Restic in ein S3-kompatibles Object Storage geschrieben. K8up unterstützt dabei verschiedene Backup-Methoden: PVC-Backups durch direktes Mounting der Volumes, Backup-Commands die via STDOUT ausgegeben werden, und PreBackupPods für Application-Aware-Backups.
Die folgende Darstellung zeigt eine High-Level-Übersicht der K8up-Backup-Architektur in openDesk:
graph TB
GitRepo[Git Repository<br/>git.intern.b1-systems.de<br/>K8up Konfiguration & Werte]
subgraph Cluster[Stackit Kubernetes Cluster]
subgraph ArgoCD_NS[Namespace: argocd]
ArgoCD[ArgoCD<br/>GitOps Controller]
end
subgraph K8up_NS[Namespace: k8up]
K8upOp[K8up Operator<br/>Überwacht alle Namespaces]
end
subgraph Row1[" "]
direction LR
subgraph OtherNS[Weitere Namespaces]
Other[cert-manager, ingress-nginx,<br/>monitoring, mariadb-operator,<br/>fluentbit, oauth2-proxy, etc.]
end
subgraph ControlPlane[Control Plane]
direction LR
ETCD[(etcd)]
API[kube-apiserver]
Scheduler[kube-scheduler]
Controller[kube-controller-manager]
end
end
subgraph Tenant[Namespace: kunde-opndsk-de]
direction LR
SpaceNode[ ]:::hidden
subgraph Resources[Ressourcen]
Schedule[Schedule CR<br/>Täglich 23:00]
PreBackupPods[PreBackupPod CRs<br/>10 Definitionen]
Apps[Anwendungen<br/>Nextcloud,ox,xwiki etc.]
PVCs[PersistentVolumes<br/>skip backup if k8up.io/backup=false, default=true]
MariaDB[(MariaDB<br/>Self-Managed)]
Cassandra[(Cassandra<br/>Self-Managed)]
end
subgraph JobsExec[Job Ausführung]
PreBackupJob[PreBackup Job<br/>pg_dump / mysqldump]
BackupJobs[Backup Jobs<br/>3 Workers for PVC Backup]
end
end
end
subgraph StackitServices[Stackit Managed Services]
direction LR
PostgreSQL[(PostgreSQL<br/>Managed Database)]
BlockStorage[(Block Storage<br/>Cinder)]
S3App[(S3 Object Storage<br/>Anwendungsdaten)]
S3Backup[(S3 Bucket<br/>Backup Repository)]
end
GitRepo -->|Quelle| ArgoCD
ArgoCD -->|Deployed| K8upOp
K8upOp -->|Überwacht| Schedule
Schedule -->|Erstellt| PreBackupJob
Schedule -->|Erstellt| BackupJobs
PreBackupPods -.->|Definiert| PreBackupJob
PreBackupJob -->|Verbindet| PostgreSQL
PreBackupJob -->|Verbindet| MariaDB
PreBackupJob -->|Verbindet| Cassandra
PreBackupJob -->|Backup mit Restic| S3Backup
BackupJobs -->|Liest| PVCs
BackupJobs -->|Backup mit Restic| S3Backup
Apps -->|Nutzt| PostgreSQL
Apps -->|Nutzt| MariaDB
Apps -->|Nutzt| Cassandra
Apps -->|Nutzt| PVCs
Apps -->|Schreibt Daten| S3App
PVCs -->|Nutzt| BlockStorage
MariaDB -->|Speichert auf| PVCs
Cassandra -->|Speichert auf| PVCs
%% Styling
classDef hidden fill:none,stroke:none,color:none;
style ArgoCD fill:#ff6b6b,stroke:#c92a2a,color:#fff
style K8upOp fill:#4a5568,stroke:#2d3748,color:#fff
style Schedule fill:#2563eb,stroke:#1e40af,color:#fff
style PreBackupJob fill:#ec4899,stroke:#db2777,color:#fff
style BackupJobs fill:#10b981,stroke:#059669,color:#fff
style S3Backup fill:#f59e0b,stroke:#d97706,color:#fff
style S3App fill:#f59e0b,stroke:#d97706,color:#fff
style PostgreSQL fill:#3b82f6,stroke:#1e40af,color:#fff
style MariaDB fill:#3b82f6,stroke:#1e40af,color:#fff
style Cassandra fill:#3b82f6,stroke:#1e40af,color:#fff
style ArgoCD_NS fill:#ffe0e6,stroke:#ff6b6b,color:#000
style K8up_NS fill:#e8e9ed,stroke:#4a5568,color:#000
style OtherNS fill:#64748b,stroke:#334155,color:#fff
style ControlPlane fill:#1e293b,stroke:#0f172a,color:#fff
style Row1 fill:none,stroke:none
SpaceNode ~~~ Resources
openDesk nutzt K8up für mandantenspezifische Backups in jedem dedizierten Kubernetes-Cluster.
Hinweis zu etcd: Ein separates Backup des Kubernetes-Key-Value-Stores (etcd) ist in diesem Konzept nicht vorgesehen. Da es sich um einen Managed-Kubernetes-Service handelt, liegt die Verantwortung für die Control-Plane-Verfügbarkeit beim Cloud-Provider. Zudem erfolgt die Wiederherstellung des Cluster-Zustands (Workloads) primär über den GitOps-Ansatz (ArgoCD), was ein etcd-Restore für Disaster-Recovery-Zwecke obsolet macht.
Tägliches Backup
Die folgende Erklärung vermittelt ein detailliertes Verständnis davon, wie K8up täglich automatisierte Backups im Namespace kunde-opndsk-de ausführt.
sequenceDiagram
autonumber
participant S as Schedule CR<br/>(backup)
participant O as K8up Operator
participant B as Backup CR<br/>(backup-backup-qfsth)
participant PBJ as PreBackup Job<br/>(backup-prebackup)
participant PBP as PreBackup Pod<br/>(backup-prebackup-4rpmw)
participant PBCRD as PreBackupPod CRDs
participant APP as Application Pods
participant PVJ as PVC Backup Jobs<br/>(Anzahl abhängig von PVCs)
participant S3 as S3 Bucket<br/>(Restic Repository)
Note over S: Täglich um 23:00 Uhr
S->>O: Schedule löst aus
O->>B: Erstellt Backup CR
Note over B: ownerReferences:<br/>Schedule = backup
O->>PBJ: Erstellt PreBackup Job
PBJ->>PBP: Erzeugt Pod
Note over PBP: Umgebungsvariablen:<br/>BACKUPCOMMAND_ANNOTATION<br/>FILEEXTENSION_ANNOTATION
PBP->>PBCRD: Entdeckt PreBackupPod CRDs<br/>im Namespace
loop Für jeden PreBackupPod
PBP->>APP: kubectl exec<br/>führt backupCommand aus
APP-->>PBP: Backup-Ausgabe<br/>(z.B. DB-Dump auf PVC)
end
PBP->>B: Aktualisiert Status:<br/>PreBackupPodReady: True
O->>PVJ: Erstellt parallele Jobs<br/>(SKIP_PREBACKUP: true)
Note over PVJ: Anzahl der Jobs abhängig<br/>von Anzahl der zu sichernden PVCs.<br/>Jeder Job mountet verschiedene<br/>PVC-Batches im Read-Only-Modus
PVJ->>S3: Sichert alle PVCs<br/>mit Restic
S3-->>B: Snapshots Erstellt
Note over O: Bereinigung basierend auf<br/>successfulJobsHistoryLimit:
O->>B: Löscht alte Backup CRs<br/>und zugehörige Jobs
Note over S: Wartet auf nächsten Schedule<br/>(morgen um 23:00 Uhr)
K8up Täglicher Backup-Prozess: Schritt für Schritt:
1. Schedule-Auslösung um 23:00 Uhr: Der Schedule CR mit dem Namen backup im Namespace kunde-opndsk-de enthält die Cron-Expression 0 23 * * *. Jeden Tag um 23:00 Uhr überwacht der K8up-Operator diesen Schedule und aktiviert den Backup-Prozess automatisch.
Beispiel-YAML (Schedule):
apiVersion: k8up.io/v1
kind: Schedule
metadata:
name: backup
namespace: kunde-opndsk-de
spec:
backend:
repoPasswordSecretRef:
name: backup-repo
key: password
s3:
endpoint: https://object.storage.eu01.onstackit.cloud
bucket: <some-bucket-name>
accessKeyIDSecretRef:
name: backup-bucket-credentials
key: username
secretAccessKeySecretRef:
name: backup-bucket-credentials
key: password
backup:
schedule: '0 23 * * *'
successfulJobsHistoryLimit: 0
failedJobsHistoryLimit: 0
2. Automatische Erstellung des Backup CR: Der Schedule erstellt automatisch ein neues Backup Custom Resource (CR) mit einem Namen wie z.B backup-backup-qfsth. Dieses Backup-CR übernimmt alle Konfigurationen vom Schedule, einschließlich Backend-Einstellungen (S3-Endpoint, Bucket, Zugangsdaten) und Job-History-Limits. Das ownerReferences-Feld verweist auf den Schedule als Ersteller.
3. K8up-Operator erkennt neues Backup: Der K8up-Operator beobachtet kontinuierlich neue Backup-CRs. Sobald backup-backup-qfsth erstellt wird, startet er den Backup-Workflow.
4. Erstellung des PreBackup Jobs: Der Operator erstellt einen Kubernetes Job z.b. backup-backup-backup-qfsth-prebackup. Dieser Job ist für die Orchestrierung der PreBackupPod-Befehle zuständig.
5. Erzeugung des PreBackup Pods: Der PreBackup Job erzeugt einen Pod (z.B. backup-backup-backup-qfsth-prebackup-4rpmw). Dieser Pod enthält den K8up-Container mit dem Image ghcr.io/k8up-io/k8up:v2.12.0 und führt den Befehl "/usr/local/bin/k8up", "restic" aus.
6. Entdeckung der PreBackupPod CRDs: Der PreBackup Pod durchsucht den Namespace kunde-opndsk-de nach allen PreBackupPod Custom Resource Definitions. Diese PreBackupPods definieren Backup-Befehle, die vor der PVC-Sicherung ausgeführt werden müssen (z.B. Datenbank-Dumps).
Beispiel PreBackupPod YAML:
apiVersion: k8up.io/v1
kind: PreBackupPod
metadata:
name: nextcloud-pre-backup-postgres
namespace: kunde-opndsk-de
spec:
backupCommand: sh -c 'PGDATABASE="$POSTGRES_DB" PGUSER="$POSTGRES_USER" PGPASSWORD="$POSTGRES_PASSWORD" PGHOST="$POSTGRES_HOST" PGPORT="$POSTGRES_PORT" pg_dump --clean'
pod:
spec:
containers:
- env:
- name: POSTGRES_DB
value: nextcloud
- name: POSTGRES_USER
value: nextcloud
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: opendesk-nextcloud-management-database
key: password
- name: POSTGRES_PORT
value: "5432"
- name: POSTGRES_HOST
value: <postgres host url>
image: docker.io/library/postgres:16
command:
- 'sleep'
- 'infinity'
imagePullPolicy: Always
name: nextcloud-pre-backup-postgres
7. Ausführung der Backup-Befehle: Für jeden gefundenen PreBackupPod führt der Orchestrator-Pod kubectl exec in die Ziel-Application-Pods aus. Dabei wird der im PreBackupPod definierte backupCommand ausgeführt. Beispiel: Ein MariaDB-Pod erhält den Befehl mysqldump --all-databases > /backup/dump.sql, um die Datenbank auf ein PVC zu dumpen. Die Backup-Ausgabe wird auf dem entsprechenden PVC gespeichert, das später zusammen mit den anderen PVCs gesichert wird.
8. Status-Aktualisierung: Nach erfolgreicher Ausführung aller PreBackupPod-Befehle aktualisiert der PreBackupPod den Status des Backup CR
9. Erstellung paralleler PVC-Backup-Jobs: Der K8up-Operator erstellt nun mehrere parallele Backup-Jobs (z.B. backup-backup-backup-qfsth-0). Die Anzahl dieser Jobs hängt von der Anzahl der zu sichernden PVCs im Namespace kunde-opndsk-de ab. Jeder Job mountet verschiedene PVC-Batches im Read-Only-Modus, um Datenkonsistenz während der Sicherung zu gewährleisten.
10. Sicherung aller PVCs mit Restic: Die PVC-Backup-Jobs nutzen Restic, um die Inhalte aller gemounteten PVCs in das S3-Repository zu sichern. Restic erstellt dabei inkrementelle, deduplizierte Snapshots. Die Daten werden verschlüsselt mit dem Passwort aus dem Secret backup-repo gespeichert.
11. Snapshot-Erstellung und Status-Abschluss: Nach erfolgreicher Sicherung aller PVCs aktualisiert der K8up-Operator den Backup-CR-Status. Die Snapshots sind nun im S3-Bucket unter s3:https://object.storage.eu01.onstackit.cloud/kunde-opndsk-de-backup-manual verfügbar.
12. Automatische Bereinigung: Basierend auf der Konfiguration successfulJobsHistoryLimit: im Schedule löscht der K8up-Operator alle alten Backup CRs und zugehörigen Jobs sofort nach Abschluss. Normalerweise wird successfulJobsHistoryLimit auf 0 gesetzt ausser zu Debugging-zwecken.
Dieser automatisierte Prozess stellt sicher, dass täglich konsistente Backups aller PVCs im Namespace kunde-opndsk-de erstellt werden, wobei zuerst anwendungsspezifische Backup-Befehle (wie Datenbank-Dumps) ausgeführt werden, bevor die eigentliche PVC-Sicherung erfolgt.
Wöchentliche Integritätsprüfung (Check Job)
Der Check-Job wird automatisch jeden Montag um 01:00 Uhr ausgeführt und überprüft die Integrität des Backup-Repositories.
sequenceDiagram
autonumber
participant S as Schedule CR
participant O as K8up Operator
participant C as Check CR
participant CJ as Check Job
participant CP as Check Pod
participant S3 as S3 Repository
Note over S: Montag um 01:00 Uhr
S->>O: Schedule löst aus (Cron: 0 1 * * 1)
O->>C: Erstellt Check CR
O->>CJ: Erstellt Check Job
CJ->>CP: Erzeugt Check Pod
CP->>S3: Verbindung zum Repository & Integritätsprüfung
S3-->>CP: Prüfung abgeschlossen (erfolgreich/fehlgeschlagen)
CP->>C: Status-Aktualisierung
O->>C: Automatische Bereinigung (History-Limits)
1. Schedule-Auslösung um 01:00 Uhr (Montag): Der Schedule CR mit dem Namen backup im Namespace kunde-opndsk-de enthält die Cron-Expression 0 1 * * 1 für Check-Jobs. Jeden Montag um 01:00 Uhr beobachtet der K8up-Operator diesen Schedule und aktiviert den Check-Prozess automatisch.
Beispiel-YAML (Schedule mit Check-Konfiguration):
check:
schedule: '0 1 * * 1'
resources: {}
2. Automatische Erstellung des Check CR: Der Schedule erstellt automatisch ein neues Check Custom Resource (CR) mit einem Namen wie z.B backup-check-xm9k2. Dieses Check-CR übernimmt alle Backend-Konfigurationen vom Schedule, einschließlich S3-Endpoint, Bucket und Zugangsdaten. Das ownerReferences-Feld verweist auf den Schedule als Ersteller.
3. K8up-Operator erkennt neues Check CR: Der K8up-Operator beobachtet kontinuierlich neue Check-CRs. Sobald backup-check-xm9k2 erstellt wird, startet er den Check-Workflow.
4. Erstellung des Check Jobs: Der Operator erstellt einen Kubernetes Job namens backup-backup-check-xm9k2. Dieser Job ist für die Integritätsprüfung des Restic-Repositories zuständig.
5. Erzeugung des Check Pods: Der Check Job erzeugt einen Pod (z.B. backup-backup-check-xm9k2-7bmqw). Dieser Pod enthält den K8up-Container mit dem Image ghcr.io/k8up-io/k8up:v2.12.0 und führt den Restic-Check-Befehl aus.
6. Ausführung der Integritätsprüfung: Der Check-Pod verbindet sich zum S3-Repository unter s3:https://object.storage.eu01.onstackit.cloud/kunde-opndsk-de-backup-manual und führt folgende Prüfungen durch:
- Repository-Struktur-Validierung: Überprüfung der grundlegenden Repository-Struktur und Config-Dateien
- Snapshot-Metadaten-Prüfung: Validierung aller Snapshot-IDs, Zeitstempel und Referenzen
- Index-Konsistenz-Check: Überprüfung der Index-Dateien auf Vollständigkeit
- Pack-File-Validierung: Stichprobenartige Überprüfung der Pack-Dateien auf Lesbarkeit
- Blob-Referenz-Check: Verifizierung, dass alle Blob-Referenzen aufgelöst werden können
Ausgeführter Befehl im Pod:
restic check --repo s3:https://object.storage.eu01.onstackit.cloud/kunde-opndsk-de-backup-manual
7. Status-Aktualisierung: Nach erfolgreicher oder fehlgeschlagener Prüfung aktualisiert der K8up-Operator den Status des Check CR.
8. Automatische Bereinigung: Der K8up-Operator verwaltet die Job-Historie basierend auf den konfigurierten successfulJobsHistoryLimit und failedJobsHistoryLimit Werten im Schedule. Wenn diese Werte explizit gesetzt sind, werden entsprechend viele abgeschlossene Check-CRs und zugehörige Jobs aufbewahrt. Bei einem Wert von 0 werden alle Jobs sofort nach Abschluss gelöscht. Sind keine expliziten Limits konfiguriert, verwendet K8up die Kubernetes-Standardwerte (typischerweise 3 erfolgreiche und 1 fehlgeschlagener Job). Normalerweise wird successfulJobsHistoryLimit auf 0 gesetzt ausser zu Debugging-zwecken.
2.1.3 Wöchentliche Bereinigung (Prune Job)
Der Prune-Job wird automatisch jeden Sonntag um 01:00 Uhr ausgeführt und entfernt alte Snapshots aus dem S3-Repository, um Speicherplatz freizugeben und die Backup-Kosten zu optimieren
sequenceDiagram
autonumber
participant S as Schedule CR
participant O as K8up Operator
participant P as Prune CR
participant PJ as Prune Job
participant PP as Prune Pod
participant S3 as S3 Repository
Note over S: Sonntag um 01:00 Uhr
S->>O: Schedule löst aus (Cron: 0 1 * * 0)
O->>P: Erstellt Prune CR
O->>PJ: Erstellt Prune Job
PJ->>PP: Erzeugt Prune Pod
PP->>S3: Verbindung & Ausführung der Snapshot-Bereinigung
S3-->>PP: Bereinigung abgeschlossen (Snapshots gelöscht, Speicher freigegeben)
PP->>P: Status-Aktualisierung mit Statistiken
O->>P: Automatische Bereinigung (History-Limits)
1. Schedule-Auslösung um 01:00 Uhr (Sonntag): Der Schedule CR mit dem Namen backup im Namespace kunde-opndsk-de enthält die Cron-Expression 0 1 * * 0 für Prune-Jobs. Jeden Sonntag um 01:00 Uhr beobachtet der K8up-Operator diesen Schedule und aktiviert den Prune-Prozess automatisch.
Beispiel-YAML (Schedule mit Prune-Konfiguration):
prune:
schedule: '0 1 * * 0'
retention:
keepLast: 5
keepDaily: 14
keepWeekly: 4
keepMonthly: 12
keepYearly: 2
resources: {}
2. Automatische Erstellung des Prune CR: Der Schedule erstellt automatisch eine neue Prune Custom Resource (CR) mit einem Namen wie z.B backup-prune-8tn4p. Dieses Prune-CR übernimmt alle Backend-Konfigurationen und die Retention-Policy vom Schedule. Das ownerReferences-Feld verweist auf den Schedule als Ersteller.
3. K8up-Operator erkennt die neue Prune CR: Der K8up-Operator beobachtet kontinuierlich neue Prune-CRs. Sobald backup-prune-8tn4p erstellt ist, startet er den Prune-Workflow.
4. Erstellung des Prune Jobs: Der Operator erstellt einen Kubernetes Job (z.B backup-backup-prune-8tn4p). Dieser Job ist für die Bereinigung alter Snapshots gemäß der Retention-Policy zuständig.
5. Erzeugung des Prune Pods: Der Prune Job erzeugt einen Pod (z.B. backup-backup-prune-8tn4p-9xk7m). Dieser Pod enthält den K8up-Container mit dem Image ghcr.io/k8up-io/k8up:v2.12.0 und führt den Restic-Forget- und Prune-Befehl mit den definierten Retention-Parametern aus.
6. Ausführung der Snapshot-Bereinigung: Der Prune-Pod verbindet sich zum S3-Repository unter s3:https://object.storage.eu01.onstackit.cloud/kunde-opndsk-de-backup-manual und führt folgende Schritte aus:
- Repository-Verbindung: Verbindung zum S3-Repository mit den hinterlegten Credentials
- Snapshot-Inventarisierung: Abruf aller vorhandenen Snapshots mit ihren Zeitstempeln und Metadaten
- Retention-Policy-Anwendung: Identifikation der zu behaltenden Snapshots basierend auf:
keepLast: 5- Die letzten 5 Snapshots werden immer behalten, unabhängig von ihrem AlterkeepDaily: 14- Für die letzten 14 Tage wird ein Snapshot pro Tag behaltenkeepWeekly: 4- Für die letzten 4 Wochen wird ein Snapshot pro Woche behalten (typischerweise der letzte Snapshot der Woche)keepMonthly: 12- Für die letzten 12 Monate wird ein Snapshot pro Monat behalten (typischerweise der letzte Snapshot des Monats)keepYearly: 2- Für die letzten 2 Jahre wird ein Snapshot pro Jahr behalten (typischerweise der letzte Snapshot des Jahres)
- Snapshot-Markierung: Alle Snapshots, die nicht unter die oben genannten Retention-Regeln fallen, werden zum Löschen markiert
- Forget-Operation: Restic entfernt die Snapshot-Referenzen aus dem Repository-Index
- Prune-Operation: Physische Löschung der nicht mehr referenzierten Datenblöcke (Pack-Files) aus dem S3-Storage
- Repository-Reorganisation: Defragmentierung und Optimierung des Repository-Layouts für verbesserte Performance
Ausgeführter Befehl im Pod:
restic forget --prune \
--keep-last 5 \
--keep-daily 14 \
--keep-weekly 4 \
--keep-monthly 12 \
--keep-yearly 2 \
--repo s3:https://object.storage.eu01.onstackit.cloud/kunde-opndsk-de-backup-manual
- Status-Aktualisierung mit Statistiken: Nach erfolgreicher Bereinigung aktualisiert der K8up-Operator den Status des Prune CR mit detaillierten Statistiken über die entfernten Snapshots und freigegebenen Speicherplatz
status:
conditions:
- type: Completed
status: "True"
message: "Prune operation completed: 15 snapshots removed, 2.3 GB freed"
reason: Succeeded
lastTransitionTime: "2025-11-03T01:12:45Z"
- Automatische Bereinigung: Die Aufbewahrung abgeschlossener Prune-Jobs wird durch die Parameter
successfulJobsHistoryLimitundfailedJobsHistoryLimitim Schedule gesteuert. Ist der Wert auf 0 gesetzt, erfolgt die Löschung sofort nach Abschluss. Bei anderen Werten wird die entsprechende Anzahl an Jobs aufbewahrt, wobei ältere Jobs automatisch entfernt werden. Normalerweise wirdsuccessfulJobsHistoryLimitauf0gesetzt ausser zu Debugging-zwecken.
Backup-Ziele
Die Backup-Daten werden in einen dedizierten S3-Bucket (Backup Repository) im STACKIT Object Storage geschrieben, getrennt vom produktiven S3-Storage für Anwendungsdaten. Die Repository-Credentials werden als Kubernetes Secrets verschlüsselt im Cluster gespeichert.
Hybride Speicher-Strategie
K8up Archive-Jobs
K8up bietet neben regulären Backup-Jobs auch Archive-Jobs an. Während ein normales Backup die Daten aus Persistent Volume Claims in einem Restic-Repository speichert – verschlüsselt, dedupliziert und inkrementell – extrahiert ein Archive-Job bestehende Snapshots aus diesem Repository und speichert sie als tar-Archive in einem separaten S3-Bucket. Dieser Prozess wird als Rehydrierung bezeichnet: Die deduplizierten Datenblöcke im Restic-Repository werden wieder zu vollständigen, lesbaren Dateien zusammengesetzt. Der Vorteil liegt darin, dass diese tar-Archive ohne Restic-Tooling direkt lesbar sind und in günstigeren Cold Storage verschoben werden können. Der Nachteil ist jedoch, dass durch die Rehydrierung die Deduplizierung verloren geht – jedes Archiv enthält die vollständigen Daten, was den Speicherbedarf im Vergleich zum deduplizierten Restic-Repository deutlich erhöht.
Retention-Strategie mit Cold Storage
Eine kostenoptimierte Strategie kombiniert das Restic-Repository für kurzfristige Backups mit Archive-Jobs für die Langzeitaufbewahrung in günstigerem Cold Storage. Nachfolgend wird eine mögliche hybride Speicherstrategie beschrieben.
Hot Storage (Restic-Repository)
Im primären Restic-Repository auf STACKIT Object Storage werden die Backups für schnellen Zugriff vorgehalten:
retention:
keepLast: 3
keepDaily: 14
keepWeekly: 4
keepMonthly: 3
Diese Konfiguration deckt die letzten drei Monate mit granularer Wiederherstellungsmöglichkeit ab.
Cold Storage (Archive-Jobs)
Für die Langzeitaufbewahrung werden monatliche und jährliche Snapshots nach Ablauf von drei Monaten als tar-Archive in Cold Storage verschoben:
archive:
keepMonthly: 9 # Monate 4-12
keepYearly: 2
Der Archive-Job extrahiert die älteren Snapshots aus dem Restic-Repository und speichert sie im Cold Storage. Anschließend können diese Snapshots im Restic-Repository durch den Prune-Job entfernt werden.
Cold-Storage-Optionen
Für die Archivierung kommen u.a. folgende Optionen in Frage, die die Anforderungen an Cloud-Souveränität erfüllen:
| Anbieter | Service | S3-kompatibel |
|---|---|---|
| Scaleway | Glacier | Ja |
| OVHcloud | Cold Archive | Ja |
Hinweis: STACKIT bietet derzeit kein Cold-Storage-Tier an. Der STACKIT Archiving Service ist nicht S3-kompatibel und für revisionssichere Compliance-Archivierung konzipiert, nicht für operative Backups. US-amerikanische Anbieter (AWS S3 Glacier, Azure Archive) erfüllen aufgrund des US CLOUD Act nicht die Souveränitätsanforderungen.
Zu sichernde Komponenten
---
config:
sankey:
showValues: false
width: 1200
height: 800
nodeColors:
ClamAV: "#6baed6"
Dovecot: "#9ecae1"
Element/Synapse: "#9e9ac8"
Intercom-Service: "#ff8c00"
Jitsi: "#c6dbef"
Nextcloud: "#de2d26"
Nubus: "#9e9ac8"
OpenProject: "#756bb1"
Open-Xchange: "#bcbddc"
Postfix: "#dadaeb"
XWiki: "#c6dbef"
PVC: "#fdae6b"
PostgreSQL: "#74c476"
Memcached: "#c084fc"
S3: "#bdbdbd"
Cassandra: "#f5e27f"
Redis: "#9ecae1"
MariaDB: "#a1d99b"
---
sankey-beta
%% === ClamAV ===
ClamAV,PVC,2
%% === Dovecot ===
Dovecot,PVC,2
Dovecot,S3,2
Dovecot,Cassandra,2
%% === Element/Synapse ===
Element/Synapse,PostgreSQL,2
Element/Synapse,PVC,2
%% === Intercom-Service ===
Intercom-Service,Redis,2
%% === Jitsi ===
Jitsi,PVC,2
%% === Nextcloud ===
Nextcloud,PostgreSQL,2
Nextcloud,S3,2
Nextcloud,Redis,2
%% === Nubus ===
Nubus,PostgreSQL,2
Nubus,S3,2
Nubus,PVC,2
Nubus,Memcached,2
%% === OpenProject ===
OpenProject,PostgreSQL,2
OpenProject,S3,2
OpenProject,Memcached,2
OpenProject,PVC,2
%% === Open-Xchange ===
Open-Xchange,MariaDB,2
Open-Xchange,S3,2
Open-Xchange,Redis,2
Open-Xchange,PVC,2
%% === Postfix ===
Postfix,PVC,2
%% === XWiki ===
XWiki,PostgreSQL,2
XWiki,PVC,2
Eine detaillierte Auflistung aller derzeit in das Backup einbezogenen Systeme und Datenquellen ist in der openDesk-Dokumentation unter "Data Storage" dokumentiert.
Grundsätzlich verfolgt openDesk im Rahmen des Backup-Konzepts die Strategie "Backup Everything"
Entscheidungsgrundlage: Eine granulare Unterscheidung zwischen temporären Dateien (Cache, Temp) und persistenten Nutzdaten ist aufgrund der komplexen, monatlichen Release-Zyklen der openDesk-Komponenten mit hohem Wartungsaufwand verbunden. Da sich Pfade und Datenstrukturen der einzelnen Microservices ändern können, wird bewusst darauf verzichtet, einzelne Verzeichnisse exklusiv auszuschließen (außer explizit definierte Ausnahmen). Dies minimiert das Risiko von Datenverlust durch fehlkonfigurierte Excludes und reduziert den operativen Aufwand bei Upgrades.
Gesichert werden daher standardmäßig:
- Alle Persistent Volume Claims (PVCs) der Stateful-Anwendungen.
- Datenbank-Dumps (via PreBackupPods erstellt und auf PVCs abgelegt).
- Konfigurationsdaten (sofern nicht rein über GitOps wiederherstellbar).
Explizit ausgeschlossen:
- Caching-Dienste (Redis, Memcached): Diese Komponenten sind vom Backup ausgenommen, da sie ausschließlich temporäre Daten beinhalten (Cache).
- PVCs mit
backup=false: Volumes, die über die Annotationk8up.io/backup: "false"explizit als nicht sicherungswürdig markiert wurden (z.B. reine temporäre Verzeichnisse).
Schwächen und Risiken der Strategie
Die beschriebene Backup-Strategie bietet eine solide Grundlage für die Datensicherung. Dennoch gibt es einige Bereiche, die bei der Weiterentwicklung des Konzepts Beachtung finden sollten.
Manueller Restore-Prozess
Die Wiederherstellung von Backups erfolgt derzeit über manuelle Schritte, die durch erfahrene Administratoren koordiniert werden. Dies umfasst die Identifikation des Snapshots, die Wiederherstellung der PVCs sowie den Import der Datenbank-Dumps.
Optimierungspotenzial: Die manuelle Ausführung dieser Schritte kann im Zeitdruck zu Verzögerungen führen. Typische Herausforderungen umfassen die Auswahl des korrekten Snapshots, die Einhaltung der richtigen Reihenfolge bei der Wiederherstellung abhängiger Komponenten sowie die Sicherstellung der Kompatibilität zwischen gesicherten und wiederhergestellten Versionen.
Siehe Kapitel 4: Die detaillierte Beschreibung des Restore-Prozesses, einschließlich geplanter Automatisierungsstrategien und Testverfahren, findet sich im Kapitel Backup- und Restore-Automatisierung.
Ein einzelner Speicherort - Single Point of Failure
Alle Backup-Daten werden aktuell in einem S3-Bucket (STACKIT Managed S3) gespeichert. Dies bedeutet, dass die gesamte Wiederherstellungsfähigkeit von der Verfügbarkeit und Integrität dieses einen Speicherorts abhängt.
Optimierungspotenzial: Die Evaluierung einer georedundanten Replikation zu einem zweiten S3-Standort (z.B. Regio Cloud oder Hetzner) ist bereits in Planung. Dies würde die Verfügbarkeit im Falle eines Ausfalls des Primärspeichers zusätzlich absichern.
Application-Level Consistency
K8up erstellt PVC-Snapshots auf File-Ebene. Die logische Konsistenz wird durch PreBackupPods (Datenbank-Dumps) sichergestellt. Bei einem Fehlschlag dieser Pods kann es zu Inkonsistenzen im Backup kommen.
Optimierungspotenzial: Eine automatische Validierung der erstellten Dumps (z.B. Größenprüfung, Schema-Check) würde zusätzliche Sicherheit bieten. Das bestehende Monitoring über Prometheus/Alertmanager deckt bereits den Job-Status ab, könnte jedoch um inhaltliche Prüfungen erweitert werden.
Restic-Repository-Integrität
Die Backup-Daten sind vollständig im Restic-Repository gespeichert. Die wöchentlichen Check-Jobs überwachen die strukturelle Integrität, jedoch nicht die Verwendbarkeit der gesicherten Daten.
Optimierungspotenzial: Ein stichprobenartiger Restore einzelner Dateien oder Snapshots könnte die Validierung ergänzen und zusätzliche Sicherheit bieten, dass die Backups im Bedarfsfall verwendbar sind.