Back up cluster state with Velero
Velero is the fallback backup, for the narrow case where an application keeps its data in a filesystem volume and has no backup of its own. A database backs itself up, and files belong in object storage, so most workloads never need this. When you do, Velero copies the files inside each PVC out to an object storage bucket, along with the surrounding Kubernetes resources.
On Syself Autopilot you run it in file-copy mode: the node agent reads the files inside each volume and writes them to your bucket, which works the same on cloud volumes and local disks. Point it at SeaweedFS or any S3-compatible endpoint. The Syself Consulting team can set up backups for you or run them as a full service if you would rather not operate Velero yourself.
Install the CLI #
Download the velero client for your platform from the Velero releases, then confirm it runs:
$ velero version --client-only
Give Velero bucket credentials #
Velero talks to Hetzner Object Storage through the aws provider, because the endpoint speaks the S3 API. Put your access key and secret in a file in AWS credentials format:
[default]
aws_access_key_id=<access-key>
aws_secret_access_key=<secret-key>
Generate a key scoped to the backup bucket rather than reusing a broad one. Run SeaweedFS covers creating least-privilege keys.
Install the server #
Install Velero with the node agent and file-copy backups, and turn CSI volume snapshots off:
$ velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.10.0 \
--bucket cluster-backups \
--secret-file ./credentials-velero \
--use-volume-snapshots=false \
--use-node-agent \
--default-volumes-to-fs-backup \
--backup-location-config region=hel1,s3ForcePathStyle=true,s3Url=https://<your-s3-endpoint>
Two flags carry the design:
--use-volume-snapshots=falseturns off CSI snapshots. Cloud volumes have no snapshot API to call, and a local snapshot never leaves the node, so Velero copies files instead. See Volume snapshots and their limits .--use-node-agentwith--default-volumes-to-fs-backupruns a node agent that copies every volume's files by default, so you do not annotate each pod by hand.
Confirm the backup location is reachable:
$ velero backup-location get
NAME PROVIDER BUCKET/PREFIX PHASE LAST VALIDATED ACCESS MODE DEFAULT
default aws cluster-backups Available 2026-08-17 09:14:22 +0000 UTC ReadWrite true
Take a backup #
Back up a namespace, volumes included:
$ velero backup create app-backup --include-namespaces my-app
$ velero backup describe app-backup --details
If you installed without --default-volumes-to-fs-backup, opt a pod's volumes in with an annotation naming the volumes to copy:
$ kubectl -n my-app annotate pod/<pod> backup.velero.io/backup-volumes=<volume-name>
Schedule recurring backups #
An on-demand backup is fine for a one-off, but a workload's recovery point depends on how often a backup runs. Create a Schedule so Velero backs the namespace up on a fixed cadence:
$ velero schedule create app-recurring --schedule="0 */6 * * *" --include-namespaces my-app
The schedule interval is what sets a workload's recovery point: back up every six hours and you can lose at most six hours of files.
Databases need a native backup instead#
A file copy of a running database is crash-consistent, not application-consistent , so the database can refuse to load it. Back databases up with their own tooling (a dump or an operator backup) and store the result in object storage, and let Velero cover the surrounding Kubernetes resources and volumes that hold plain files.
A backup you have never restored proves nothing. Rehearse recovery in Run a restore drill .