Inhoudsopgave
- Wat je leert
- Wat je al moet hebben
- Hoe Velero past in het Kubernetes-backupplaatje
- Velero installeren
- Je eerste backup maken
- Backups plannen met retentie
- Volume-backupmechanismen: welke kies je
- Databaseconsistentie met pre-backuphooks
- Restore naar hetzelfde of een nieuw cluster
- Backupgezondheid monitoren
- Veelvoorkomende problemen
- Wat je hebt geleerd
Wat je leert
Aan het einde van deze tutorial kun je Velero installeren, Kubernetes-namespaces en persistent volumes back-uppen naar objectopslag, die backups plannen met gestaffeld retentiebeleid, pre-backuphooks toevoegen zodat databasevolumes applicatie-consistent zijn, een namespace herstellen naar hetzelfde of een ander cluster, en Prometheus-monitoring opzetten voor backupgezondheid.
Wat je al moet hebben
Deze tutorial gaat ervan uit dat je beschikt over:
- Een draaiend Kubernetes-cluster (1.20+) met
kubectl-toegang - Een S3-compatibele objectopslagbucket (AWS S3, GCS, Azure Blob, of MinIO voor on-premises)
- Cloudprovider-credentials met lees- en schrijftoegang tot de bucket
- De Velero CLI lokaal geinstalleerd (v1.18+)
- Bekendheid met PersistentVolumes en PersistentVolumeClaims
- Bekendheid met StorageClasses en dynamische provisioning
Draai je een managed cluster (EKS, GKE, AKS), dan heb je al een objectopslagdienst beschikbaar. Voor zelf-beheerde clusters werkt MinIO als S3-compatibel doel binnen of buiten het cluster.
Hoe Velero past in het Kubernetes-backupplaatje
Velero (voorheen Heptio Ark) is een open-source tool onderhouden door VMware Tanzu die Kubernetes API-objecten en persistent-volume-data back-upt en herstelt. Het bevraagt de Kubernetes API-server voor resourcedefinities en uploadt ze als tarballs naar objectopslag. Het raakt etcd niet direct aan.
Dat verschil is belangrijk. Een etcd-snapshot vangt de volledige control-plane-status in een binaire blob: elke Deployment, Secret, RBAC-rule en CRD. Dat is het juiste gereedschap voor pre-upgrade rollback of volledige control-plane-recovery. Maar een etcd-snapshot kan geen individuele verwijderde namespace herstellen, kan niet filteren op label, en kan geen workloads verplaatsen naar een ander cluster. Op managed clusters (EKS, GKE, AKS) heb je helemaal geen etcd-toegang.
Velero vult dat gat. De backup werkt op API-niveau, wat betekent dat je individuele namespaces kunt back-uppen, kunt filteren op resourcetype of label, verouderde statusvelden kunt uitsluiten, en kunt herstellen naar een compleet ander cluster. De twee tools zijn complementair, niet uitwisselbaar.
Tweedelige architectuur. Velero draait een Deployment (de controller) en een optionele DaemonSet (de Node Agent, voor file-system-level volume-backups) in het cluster. De CLI op je werkstation stuurt commando's via de Kubernetes API.
Velero installeren
Dit gedeelte toont de CLI-installatie voor AWS. De pagina met ondersteunde providers bevat plugins voor GCP, Azure, vSphere en community-onderhouden providers.
Stap 1: maak een bucket en credentials aan
Maak een S3-bucket en een IAM-gebruiker met een policy die s3:GetObject, s3:PutObject, s3:DeleteObject en s3:ListBucket verleent op die bucket. Sla de access key op in een credentialsbestand:
cat > /tmp/credentials-velero <<EOF
[default]
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
EOF
Vervang de voorbeeldwaarden door je eigen IAM-credentials.
Stap 2: installeer Velero met CSI-ondersteuning en Node Agent
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.10.0 \
--bucket my-velero-backups \
--secret-file /tmp/credentials-velero \
--backup-location-config region=eu-west-1 \
--snapshot-location-config region=eu-west-1 \
--use-node-agent \
--features=EnableCSI
--use-node-agent deployt de DaemonSet die nodig is voor file system backup en CSI snapshot data movement. --features=EnableCSI schakelt de CSI snapshot-integratie in.
Verwachte output:
Velero is installed! ⛵ Use 'velero client config set ...' to configure the CLI.
Stap 3: verifieer de installatie
kubectl get deployments -n velero
kubectl get daemonsets -n velero
Je zou de velero Deployment moeten zien met 1/1 available en de node-agent DaemonSet met pods op elke schedulable node.
NAME READY UP-TO-DATE AVAILABLE
velero 1/1 1 1
NAME DESIRED CURRENT READY
node-agent 3 3 3
Checkpoint. Als de Velero-pod niet Ready is, check dan de logs: kubectl logs deploy/velero -n velero. Veelvoorkomende oorzaken: verkeerde S3-regio, ongeldige credentials, ontbrekende bucket.
Alternatief: Helm-installatie
Voor productieomgevingen die via GitOps worden beheerd is Helm een betere route. Configuratie leeft in een values.yaml die je naast je andere manifests commit.
helm repo add vmware-tanzu https://vmware-tanzu.github.io/helm-charts
helm install velero vmware-tanzu/velero \
--namespace velero \
--create-namespace \
-f velero-values.yaml
Zie de Helm chart-documentatie voor de volledige values.yaml-referentie.
Je eerste backup maken
Stap 4: back up een namespace
velero backup create first-backup \
--include-namespaces production \
--wait
--wait blokkeert totdat de backup klaar is. Zonder deze vlag keert het commando direct terug en poll je met velero backup describe.
Verwachte output:
Backup request "first-backup" submitted successfully.
Waiting for backup to complete. You may safely press ctrl-c...
Backup completed with status: Completed.
Stap 5: inspecteer de backup
velero backup describe first-backup --details
Dit toont welke resources zijn vastgelegd, welke volumes zijn gesnapshot, eventuele waarschuwingen of fouten, en de hook-uitvoerresultaten. Let op de Phase (moet Completed zijn) en het aantal Errors (moet 0 zijn).
Stap 6: verifieer de backupinhoud
velero backup logs first-backup | head -30
De log toont elke verwerkte resource. Je ziet regels als backup/production/Deployment/my-app, wat bevestigt dat API-objecten naar de tarball zijn geschreven. Volume-snapshots verschijnen als aparte regels die het gebruikte snapshotmechanisme tonen.
Checkpoint. Je hebt nu een werkende backup van een namespace in je S3-bucket. Het volgende deel voegt automatisering toe.
Backups plannen met retentie
Eenmalige backups zijn een begin, maar productie-workloads hebben geautomatiseerde, terugkerende backups nodig met gedefinieerde retentievensters.
Stap 7: maak een dagelijks schema
velero schedule create daily-production \
--schedule="CRON_TZ=Europe/Amsterdam 0 2 * * *" \
--include-namespaces production \
--ttl 168h
Dit draait elke dag om 02:00 Amsterdamse tijd een backup en bewaart die 168 uur (7 dagen). Velero's garbage collector verwijdert verlopen backups elk uur.
Tijdzoneondersteuning in het CRON_TZ=-prefix is beschikbaar sinds v1.18. Oudere versies gebruiken alleen UTC.
Stap 8: verifieer het schema
velero schedule get
NAME STATUS CREATED SCHEDULE BACKUP TTL
daily-production Enabled 2026-04-09 14:30:00 +0200 CRON_TZ=Europe/Amsterdam 0 2 * * * 168h0m0s
Om direct een backup vanuit een schema te triggeren (handig voor testen):
velero backup create --from-schedule daily-production
Gestaffelde retentiestrategie
Voor productie kun je meerdere schema's overwegen met verschillende retentievensters:
# Elk uur, bewaard voor 24 uur
velero schedule create hourly-production \
--schedule="0 * * * *" \
--include-namespaces production \
--ttl 24h
# Wekelijks, bewaard voor 28 dagen
velero schedule create weekly-production \
--schedule="CRON_TZ=Europe/Amsterdam 0 3 * * 0" \
--include-namespaces production \
--ttl 672h
# Maandelijks, bewaard voor 1 jaar (compliance)
velero schedule create monthly-production \
--schedule="CRON_TZ=Europe/Amsterdam 0 4 1 * *" \
--include-namespaces production \
--ttl 8760h
De standaard-TTL is 30 dagen wanneer --ttl niet is opgegeven.
Volume-backupmechanismen: welke kies je
Velero ondersteunt drie mechanismen voor het back-uppen van persistent-volume-data. Ze sluiten elkaar uit per volume.
Eigen cloudprovider-snapshots. Gebruikt cloud-API's (EBS, GCE Persistent Disk, Azure Managed Disks) voor point-in-time snapshots. Snelst, laagste overhead, maar snapshots zijn regio-gebonden. Je kunt ze niet gebruiken voor cross-regio of cross-cloud migratie.
CSI snapshot data movement. Maakt een CSI VolumeSnapshot, extraheert de data en uploadt die naar je objectopslagbucket via Kopia. Na de upload wordt de lokale CSI-snapshot verwijderd. Dit is het aanbevolen mechanisme wanneer je duurzaamheid nodig hebt buiten het opslagsysteem of cross-cloud portabiliteit.
velero backup create my-backup \
--include-namespaces production \
--snapshot-move-data
Monitor de uploadvoortgang met:
kubectl -n velero get datauploads -l velero.io/backup-name=my-backup
File system backup (FSB). Leest volumedata rechtstreeks van draaiende pods via de Node Agent DaemonSet. Gebruikt Kopia voor deduplicatie, compressie en upload. Gebruik FSB voor volumes zonder snapshot-ondersteuning: NFS, EFS, AzureFile, lokale volumes, emptyDir. Opt-in per pod:
metadata:
annotations:
backup.velero.io/backup-volumes: data-volume
Of installeer met FSB als standaard voor alle volumes:
velero install --use-node-agent --default-volumes-to-fs-backup
Beperking. FSB leest van live PVs, dus data wordt niet op een enkel tijdstip vastgelegd. Voor databases betekent dat crash-consistent op z'n best. Applicatie-consistente backup vereist hooks.
Kopia verving Restic
Velero's file system backup gebruikte oorspronkelijk Restic als data mover. Dat veranderde over meerdere releases:
| Versie | Wijziging |
|---|---|
| v1.10 | Kopia geintegreerd naast Restic |
| v1.12 | Standaard uploader overgeschakeld naar Kopia |
| v1.15 | Restic deprecated (waarschuwingen) |
| v1.17 | --uploader-type=restic verwijderd voor nieuwe backups |
Bestaande Restic-backups kunnen nog steeds worden hersteld in v1.17+. Nieuwe backups gebruiken uitsluitend Kopia.
Databaseconsistentie met pre-backuphooks
Een databasevolume back-uppen zonder de database eerst stil te leggen levert een crash-consistente snapshot op. Dat is min of meer hetzelfde als de stekker eruit trekken. De database herstelt waarschijnlijk wel, maar dat is niet gegarandeerd, en het kost tijd.
Velero pre-backup en post-backuphooks lossen dit op door commando's uit te voeren in pod-containers voor en na de backupverwerking.
Stap 9: voeg PostgreSQL-backuphooks toe
Pas deze annotaties toe op je PostgreSQL-pod (of het pod-template in een StatefulSet):
metadata:
annotations:
pre.hook.backup.velero.io/command: >-
["/bin/bash", "-c",
"psql -U postgres -c \"SELECT pg_backup_start('velero', true);\""]
pre.hook.backup.velero.io/container: postgres
pre.hook.backup.velero.io/timeout: 5m
pre.hook.backup.velero.io/on-error: Fail
post.hook.backup.velero.io/command: >-
["/bin/bash", "-c",
"psql -U postgres -c \"SELECT pg_backup_stop();\""]
post.hook.backup.velero.io/container: postgres
post.hook.backup.velero.io/timeout: 2m
post.hook.backup.velero.io/on-error: Continue
backup.velero.io/backup-volumes: pgdata
on-error: Fail op de pre-hook betekent dat de backup afbreekt als de database niet in backupmodus kan. on-error: Continue op de post-hook betekent dat de backupdata bewaard blijft, ook als het hervattingscommando faalt.
PostgreSQL-versienoot. pg_backup_start() / pg_backup_stop() is de huidige API sinds PostgreSQL 15. Oudere versies (14 en lager) gebruiken pg_start_backup() / pg_stop_backup().
MySQL/MariaDB-hooks
metadata:
annotations:
pre.hook.backup.velero.io/command: >-
["/bin/bash", "-c",
"mysql -u root -p$MYSQL_ROOT_PASSWORD -e 'FLUSH TABLES WITH READ LOCK;'"]
pre.hook.backup.velero.io/container: mysql
pre.hook.backup.velero.io/timeout: 3m
pre.hook.backup.velero.io/on-error: Fail
post.hook.backup.velero.io/command: >-
["/bin/bash", "-c",
"mysql -u root -p$MYSQL_ROOT_PASSWORD -e 'UNLOCK TABLES;'"]
post.hook.backup.velero.io/container: mysql
post.hook.backup.velero.io/timeout: 1m
post.hook.backup.velero.io/on-error: Continue
FLUSH TABLES WITH READ LOCK blokkeert alle writes voor de duur van de backup. Voor drukbezochte databases is het beter om een read replica te back-uppen in plaats van de primary te locken.
Alternatief: gecentraliseerde hooks in de Backup-spec
In plaats van elke pod te annoteren kun je hooks centraal definiëren in de Backup- of Schedule-resource:
apiVersion: velero.io/v1
kind: Backup
metadata:
name: production-with-hooks
namespace: velero
spec:
includedNamespaces:
- production
hooks:
resources:
- name: postgres-consistency
labelSelector:
matchLabels:
app: postgres
pre:
- exec:
container: postgres
command:
- /bin/bash
- -c
- "psql -U postgres -c \"SELECT pg_backup_start('velero', true);\""
onError: Fail
timeout: 5m
post:
- exec:
container: postgres
command:
- /bin/bash
- -c
- "psql -U postgres -c \"SELECT pg_backup_stop();\""
onError: Continue
timeout: 2m
Deze aanpak past beter bij GitOps-workflows waar pod-annotaties door een ander team worden beheerd.
Stap 10: verifieer hook-uitvoering
Controleer na afloop van een backup of hooks succesvol zijn uitgevoerd:
velero backup describe first-backup --details
Zoek naar het Hooks-gedeelte. Daar staat elke hook, de pod waarop die draaide, en of die is geslaagd of gefaald.
Checkpoint. Je hebt nu geplande, applicatie-consistente backups van database-workloads.
Restore naar hetzelfde of een nieuw cluster
Stap 11: herstel een verwijderde namespace
velero restore create --from-backup daily-production-20260409020000 \
--include-namespaces production
Velero herstelt resources in afhankelijkheidsvolgorde: eerst CRDs, dan Namespaces, StorageClasses, PersistentVolumes, PersistentVolumeClaims, Secrets, ConfigMaps, en tot slot workloads.
Standaard slaat Velero resources over die al bestaan (niet-destructief). Om bestaande resources te overschrijven:
velero restore create --from-backup daily-production-20260409020000 \
--existing-resource-policy update
Stap 12: herstel naar een andere namespace
velero restore create --from-backup daily-production-20260409020000 \
--namespace-mappings production:staging
Dit mapt elke resource van de production-namespace naar staging. Handig om productiedata te klonen naar een testomgeving.
Stap 13: cross-cluster restore (disaster recovery)
Voor een volledige clustervervanging wijs je een nieuw cluster naar dezelfde backup-opslaglocatie. Installeer Velero met dezelfde bucket en credentials, en dan:
# Zet opslag op read-only om writes te voorkomen tijdens recovery
kubectl patch backupstoragelocation default \
--namespace velero \
--type merge \
--patch '{"spec":{"accessMode":"ReadOnly"}}'
# Herstel
velero restore create --from-backup daily-production-20260409020000
# Verifieer
velero restore describe <restore-name> --details
kubectl get all -n production
# Terug naar read-write
kubectl patch backupstoragelocation default \
--namespace velero \
--type merge \
--patch '{"spec":{"accessMode":"ReadWrite"}}'
De opslaglocatie op ReadOnly zetten tijdens recovery voorkomt dat de Velero-instantie van het nieuwe cluster naar de backuprepository schrijft (en die mogelijk corrumpeert) terwijl de restore bezig is.
Cross-cloud noot. Eigen cloudprovider-snapshots zijn regio-gebonden en kunnen niet worden hersteld over providers heen. Voor cross-cloud migratie moeten de backups CSI snapshot data movement (--snapshot-move-data) of file system backup gebruiken. Beide slaan volumedata op in de objectopslagbucket, wat provideronafhankelijk is.
Post-restore hooks
Velero ondersteunt twee typen restore-hooks. InitContainer-hooks injecteren een init-container in herstelde pods (draait voor de applicatie start). Exec-hooks voeren commando's uit in containers nadat de pod Ready is.
Voorbeeld: importeer een databasedump na restore:
metadata:
annotations:
post.hook.restore.velero.io/container: postgres
post.hook.restore.velero.io/command: '["/bin/bash", "-c", "psql -U postgres < /backup/backup.sql"]'
post.hook.restore.velero.io/exec-timeout: 120s
post.hook.restore.velero.io/wait-for-ready: "true"
post.hook.restore.velero.io/on-error: Fail
wait-for-ready: true laat Velero wachten tot de pod Ready is voordat het commando wordt uitgevoerd. Voor databases die initialisatietijd nodig hebben is dat belangrijk.
Checkpoint. Je kunt nu namespaces herstellen naar hetzelfde cluster, een andere namespace, of een heel ander cluster.
Backupgezondheid monitoren
Een backup die je nooit test is geen backup. Monitoring vangt stille fouten op voordat ze ertoe doen.
Stap 14: Prometheus-metrics
Velero stelt metrics beschikbaar op poort 8085. Als je de Prometheus Operator draait, voeg dan een scrape-config toe:
- job_name: velero
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_name]
action: keep
regex: velero
- source_labels: [__meta_kubernetes_pod_container_port_number]
action: keep
regex: "8085"
Belangrijke metrics om op te alerteren:
velero_backup_failure_totalstijgt: een backupschema faaltvelero_backup_duration_secondspiekt: opslag- of netwerkproblemen- Geen nieuwe
velero_backup_success_total-toename in 25 uur: het schema draait niet meer
Stap 15: Grafana-dashboards
De community onderhoudt een aantal kant-en-klare dashboards:
Importeer een van deze in je Grafana-instantie voor een visueel overzicht van backupgezondheid, duurtrends en opslagverbruik.
Regelmatige restore-oefeningen
Plan een kwartaalse restore-oefening. Herstel een recente backup naar een wegwerp-namespace, verifieer dat de workloads opstarten, bevestig dat de database de verwachte data bevat, en ruim daarna op. Een backup die nooit is getest is een risico.
Veelvoorkomende problemen
PartiallyFailed backup, repository niet geinitialiseerd. Check velero repo get en verifieer dat de Node Agent DaemonSet op alle nodes draait. Controleer S3-credentials en buckettoegang. Ontbrekende node-agent pods zijn de meest voorkomende oorzaak.
Velero-pod OOMKilled. Grote backups met veel resources kunnen het geheugen uitputten. Verhoog --velero-pod-mem-limit bij de installatie. Velero v1.18 verplaatste repository-operaties buiten het serverproces om OOM-risico te verminderen.
Vastgelopen InProgress backup. Velero kan onderbroken backups niet hervatten. Verwijder de vastgelopen backup (kubectl delete backup <name> -n velero) en trigger een nieuwe.
LoadBalancer-DNS verandert na restore. Cloud load balancers krijgen nieuwe UIDs na restore, dus nieuwe DNS-namen. Werk CNAME-records handmatig bij, of stel spec.loadBalancerIP in op de Service waar de provider dat ondersteunt.
Admission-webhooks blokkeren restore. ValidatingWebhookConfigurations en MutatingWebhookConfigurations kunnen resources afwijzen of muteren tijdens restore. Schakel webhooks tijdelijk uit als restores falen met admission-fouten.
Voor dieper debuggen:
velero backup describe <name> --details # hookresultaten en fouten
velero backup logs <name> # per-resource verwerkingslog
kubectl -n velero get datauploads # CSI data movement voortgang
Volledige troubleshootingreferentie op velero.io.
Wat je hebt geleerd
Deze tutorial behandelde de volledige Velero-levenscyclus voor backup en disaster recovery op applicatieniveau in Kubernetes:
- Velero back-upt API-objecten en volumedata. Het is complementair aan etcd-snapshots, geen vervanging.
- Drie volume-backupmechanismen bestaan: eigen cloudprovider-snapshots (snelst, regio-gebonden), CSI snapshot data movement (duurzaam, cross-cloud), en file system backup via Kopia (voor niet-ondersteunde volumetypes).
- Databaseconsistentie vereist expliciete pre-backuphooks. Zonder die hooks zijn volume-backups crash-consistent op z'n best.
- Geplande backups met gestaffelde TTL geven retentie per uur, dag, week en maand.
- Restores werken naar dezelfde namespace, een andere namespace, of een ander cluster.
- Prometheus-metrics en regelmatige restore-oefeningen maken het verschil tussen een backupstrategie en een ramp in wording.
Velero dekt niet alles. Het back-upt het control plane zelf niet (dat vereist etcd-snapshots), het heeft geen multi-tenancy-ondersteuning (alleen clusterbeheerders kunnen het beheren), en cross-cloud migratie vereist CSI data movement of file system backup in plaats van eigen snapshots. Voor commerciele alternatieven met ingebouwde multi-tenancy en applicatiebewustzijn zijn Veeam Kasten K10 en TrilioVault de belangrijkste opties.