Je homelab draait je GitLab, je wachtwoorden, je foto’s, je home automation. Wat gebeurt er als de disk faalt?
Als je die vraag niet met vertrouwen kunt beantwoorden, heb je geen backups. Je hebt hoop.
De 3-2-1 regel bestaat al decennia omdat hij werkt. Drie kopieën, twee verschillende media, één offsite. Hier is hoe je het daadwerkelijk implementeert.
De 3-2-1 Regel Uitgelegd
flowchart TD
subgraph rule["3-2-1 Backup Regel"]
Data["Originele Data"]
subgraph three["3 Kopieën"]
C1["Kopie 1<br/>(Origineel)"]
C2["Kopie 2<br/>(Lokale Backup)"]
C3["Kopie 3<br/>(Offsite)"]
end
subgraph two["2 Media Types"]
M1["NVMe/SSD"]
M2["HDD/NAS"]
end
subgraph one["1 Offsite"]
Off["Cloud/Remote"]
end
end
Data --> C1
Data --> C2
Data --> C3
C1 --> M1
C2 --> M2
C3 --> Off
Waarom Drie Kopieën?
- Kopie 1: Je live data (origineel)
- Kopie 2: Lokale backup (snelle restore)
- Kopie 3: Offsite backup (disaster recovery)
Eén kopie is geen backup. Twee kopieën kunnen allebei falen in dezelfde ramp (brand, overstroming, ransomware). Drie kopieën met separatie geeft je echte resilience.
Waarom Twee Media Types?
Verschillende failure modes:
- SSDs kunnen stilletjes falen (bit rot)
- HDDs hebben mechanische failures
- RAID is geen backup (beschermt tegen drive failure, niet data corruptie)
Verschillende media betekent dat verschillende failure scenarios niet alle kopieën uitschakelen.
Waarom Eén Offsite?
Je huis kan afbranden. Je buurt kan overstromen. Je hele stad kan stroom verliezen. Offsite betekent overleven zelfs wanneer alles lokaal weg is.
Wat Back-uppen
Kritiek (Dagelijkse Backup)
| Data | Waarom | Tool |
|---|---|---|
| Databases | Kan niet herstellen | pg_dump, Velero |
| Secrets/credentials | Security kritiek | Vault export, External Secrets |
| Configuratie | Systeem staat | Git (al offsite) |
| Persoonlijke bestanden | Onvervangbaar | Restic |
Belangrijk (Wekelijkse Backup)
| Data | Waarom | Tool |
|---|---|---|
| Container images | Rebuild kost tijd | Registry backup |
| Persistent volumes | Stateful workloads | Longhorn/Velero |
| Logs (gecomprimeerd) | Forensics | Loki snapshots |
Herbouwbaar (Niet Back-uppen)
- Basis OS (herinstalleer van ISO)
- Gedownloade packages (opnieuw downloaden)
- Gecachete data (regenereert)
- Tijdelijke bestanden
Verspil geen backup ruimte aan data die je kunt herstellen.
Backup Tools
Restic: File-Level Backups
Restic is mijn go-to voor file backups. Het is snel, versleuteld, dedupliceert, en ondersteunt meerdere backends.
# Initialiseer repository
restic init --repo /mnt/backup/restic
# Of met S3 backend
restic init --repo s3:s3.amazonaws.com/my-bucket
# Backup een directory
restic backup /home/user/documents
# Backup met exclusies
restic backup /data \
--exclude="*.tmp" \
--exclude=".cache" \
--exclude="node_modules"
# Lijst snapshots
restic snapshots
# Restore
restic restore latest --target /restore/location
Geautomatiseerde Restic Backups
#!/bin/bash
# /usr/local/bin/backup.sh
export RESTIC_REPOSITORY="s3:s3.eu-west-1.amazonaws.com/homelab-backups"
export RESTIC_PASSWORD_FILE="/etc/restic/password"
export AWS_ACCESS_KEY_ID="your-key"
export AWS_SECRET_ACCESS_KEY="your-secret"
# Backup
restic backup /data/important \
--exclude-caches \
--tag homelab \
--tag daily
# Prune oude snapshots (bewaar 7 dagelijks, 4 wekelijks, 12 maandelijks)
restic forget \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 12 \
--prune
# Check repository integriteit
restic check
Cron job:
# /etc/cron.d/restic-backup
0 3 * * * root /usr/local/bin/backup.sh >> /var/log/restic-backup.log 2>&1
Velero: Kubernetes Backups
Velero back-upt Kubernetes resources en persistent volumes.
# Installeer Velero met S3 backend
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.8.0 \
--bucket velero-backups \
--backup-location-config region=eu-west-1 \
--secret-file ./credentials-velero \
--use-volume-snapshots=true \
--snapshot-location-config region=eu-west-1
Geplande Backups
apiVersion: velero.io/v1
kind: Schedule
metadata:
name: daily-backup
namespace: velero
spec:
schedule: "0 3 * * *"
template:
includedNamespaces:
- production
- gitlab
- monitoring
excludedResources:
- events
- pods
ttl: 720h # Bewaar 30 dagen
storageLocation: default
volumeSnapshotLocations:
- default
Restore vanuit Velero
# Lijst backups
velero backup get
# Beschrijf een backup
velero backup describe daily-backup-20260518030000
# Restore gehele backup
velero restore create --from-backup daily-backup-20260518030000
# Restore specifieke namespace
velero restore create --from-backup daily-backup-20260518030000 \
--include-namespaces gitlab
Longhorn Backups
Longhorn heeft ingebouwde backup naar S3:
# Configureer backup target
apiVersion: longhorn.io/v1beta1
kind: Setting
metadata:
name: backup-target
namespace: longhorn-system
value: "s3://longhorn-backups@eu-west-1/"
---
apiVersion: longhorn.io/v1beta1
kind: Setting
metadata:
name: backup-target-credential-secret
namespace: longhorn-system
value: "longhorn-s3-secret"
Plan terugkerende backups:
apiVersion: longhorn.io/v1beta1
kind: RecurringJob
metadata:
name: daily-backup
namespace: longhorn-system
spec:
cron: "0 3 * * *"
task: backup
groups:
- default
retain: 7
concurrency: 2
Offsite Opties
Cloud Storage
| Provider | Kosten | Voordelen | Nadelen |
|---|---|---|---|
| Backblaze B2 | $0.005/GB | Goedkoop, S3-compatible | US-gebaseerd |
| Wasabi | $0.0059/GB | Geen egress kosten | 90-dagen minimum |
| AWS S3 Glacier | $0.004/GB | Zeer goedkoop | Trage retrieval |
| Hetzner Storage Box | €3.81/1TB | EU-gebaseerd, goedkoop | Alleen SFTP/WebDAV |
Tweede Locatie
Als je een vriend/familielid hebt met een homelab:
flowchart LR
subgraph your["Jouw Huis"]
YourData["Jouw Data"]
YourBackup["Hun Backup<br/>(versleuteld)"]
end
subgraph their["Hun Huis"]
TheirData["Hun Data"]
TheirBackup["Jouw Backup<br/>(versleuteld)"]
end
YourData -->|Versleuteld| TheirBackup
TheirData -->|Versleuteld| YourBackup
Wederzijdse offsite backup. Beide versleuteld zodat geen van beiden elkaars data kan lezen.
Self-Hosted Cloud
Draai je eigen S3-compatible storage op een tweede locatie:
# MinIO op remote locatie
apiVersion: apps/v1
kind: Deployment
metadata:
name: minio
spec:
template:
spec:
containers:
- name: minio
image: minio/minio
args:
- server
- /data
env:
- name: MINIO_ROOT_USER
valueFrom:
secretKeyRef:
name: minio-credentials
key: user
- name: MINIO_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: minio-credentials
key: password
Toegang via Tailscale voor security.
Database Backups
PostgreSQL
#!/bin/bash
# Kubernetes PostgreSQL backup
NAMESPACE="gitlab"
POD=$(kubectl get pod -n $NAMESPACE -l app=postgresql -o jsonpath='{.items[0].metadata.name}')
DATE=$(date +%Y%m%d_%H%M%S)
# Dump alle databases
kubectl exec -n $NAMESPACE $POD -- \
pg_dumpall -U postgres | \
gzip > /backup/postgres_${DATE}.sql.gz
# Upload naar S3
restic backup /backup/postgres_${DATE}.sql.gz --tag postgres --tag daily
Vault Backup
# Export Vault data (vereist root token)
vault operator raft snapshot save /backup/vault_$(date +%Y%m%d).snap
# Versleutel en upload
gpg --encrypt --recipient backup@example.com /backup/vault_$(date +%Y%m%d).snap
restic backup /backup/vault_$(date +%Y%m%d).snap.gpg --tag vault
Restores Testen
Een backup die je niet getest hebt is geen backup.
Maandelijkse Restore Test
#!/bin/bash
# test-restore.sh
# Maak test namespace
kubectl create namespace restore-test
# Restore vanuit Velero
velero restore create test-restore \
--from-backup $(velero backup get -o json | jq -r '.items[0].metadata.name') \
--include-namespaces gitlab \
--namespace-mappings gitlab:restore-test
# Wacht op restore
velero restore wait test-restore
# Verifieer pods draaien
kubectl get pods -n restore-test
# Test applicatie (voorbeeld: GitLab)
kubectl port-forward -n restore-test svc/gitlab 8080:80 &
curl -s http://localhost:8080/health | grep "ok"
# Cleanup
kubectl delete namespace restore-test
Documenteer Recovery Procedures
Voor elk kritiek systeem:
# GitLab Recovery Procedure
## Vereisten
- Toegang tot Velero backups
- Toegang tot PostgreSQL backups
- GitLab Helm values
## Stappen
1. Restore PostgreSQL vanuit backup
2. Restore GitLab PVCs met Velero
3. Deploy GitLab met zelfde Helm values
4. Verifieer user login werkt
5. Verifieer repositories bereikbaar zijn
## Geschatte Tijd: 45 minuten
## Laatst Getest: 2026-05-01
Backups Monitoren
Prometheus Alerts
groups:
- name: backup-alerts
rules:
- alert: BackupFailed
expr: restic_backup_last_successful_timestamp < (time() - 86400)
for: 1h
labels:
severity: critical
annotations:
summary: "Backup niet geslaagd in 24 uur"
- alert: BackupStorageLow
expr: restic_repository_size_bytes / restic_repository_max_bytes > 0.9
for: 1h
labels:
severity: warning
annotations:
summary: "Backup storage boven 90% vol"
Backup Dashboard
Track in Grafana:
- Laatste succesvolle backup tijd
- Backup duur trend
- Storage gebruik
- Restore test resultaten
Mijn Backup Setup
flowchart TD
subgraph homelab["Homelab (K3s)"]
PV["Persistent Volumes"]
DB["Databases"]
Config["Configs (Git)"]
end
subgraph local["Lokale Backup (NAS)"]
Longhorn["Longhorn Snapshots"]
Restic1["Restic Repository"]
end
subgraph offsite["Offsite (Backblaze B2)"]
Velero["Velero Backups"]
Restic2["Restic Offsite"]
end
PV --> Longhorn
PV --> Velero
DB --> Restic1
Restic1 --> Restic2
Config --> Git["GitLab (self-hosted)"]
Git --> GitMirror["GitHub Mirror"]
Schema
| Wat | Frequentie | Retentie | Locatie |
|---|---|---|---|
| Longhorn snapshots | Per uur | 24 uur | Lokale NVMe |
| Longhorn backups | Dagelijks | 7 dagen | NAS |
| Velero volledige backup | Dagelijks | 30 dagen | Backblaze B2 |
| Database dumps | Dagelijks | 30 dagen | Backblaze B2 |
| Git repos | Push | Altijd | GitHub mirror |
Kosten
- Backblaze B2: ~€5/maand voor 200GB
- NAS storage: Al in bezit
- Totaal: ~€5/maand voor gemoedsrust
Veelgemaakte Fouten
“RAID is mijn backup”
RAID beschermt tegen drive failure. Het beschermt niet tegen:
- Per ongeluk verwijderen
- Ransomware
- Software bugs die data corrumperen
- Brand/overstroming/diefstal
“Ik restore wel als ik het nodig heb”
Als je nooit gerestored hebt, weet je niet of je backups werken. Test minimaal per kwartaal.
“Ik backup alles”
10TB aan films back-uppen die je opnieuw kunt downloaden verspilt geld en tijd. Prioriteer onvervangbare data.
“Mijn backup is in dezelfde kamer”
Een brand haalt je server EN je backup drive uit. Offsite is niet onderhandelbaar.
Waarom Dit Ertoe Doet
Dataverlies is geen kwestie van of, maar wanneer:
- Drives falen (3-5% jaarlijks failure rate)
- Mensen maken fouten (rm -rf verkeerde directory)
- Software heeft bugs (database corruptie)
- Slechte dingen gebeuren (brand, overstroming, diefstal)
Het verschil tussen “klein ongemak” en “catastrofaal verlies” is een geteste backup strategie.
Je homelab slaat dingen op die ertoe doen. Bescherm ze dienovereenkomstig.
De beste tijd om backups in te stellen was voordat je ze nodig had. De op een na beste tijd is nu.
