Kubernetes Backups with Velero and OtterStorage
Configure Velero to back up and restore your Kubernetes clusters using OtterStorage as an S3-compatible object store.
Velero is the standard tool for backing up, restoring, and migrating Kubernetes resources and their persistent volumes. This guide explains how to point Velero at an OtterStorage bucket using the AWS plugin, schedule recurring backups, restore from a copy, and protect your backups with Object Lock.
Before you start
You need to have the following ready:
- A running Kubernetes cluster with
kubectlconfigured against it. - The Velero CLI installed on your local machine (v1.12 or later recommended).
- A bucket created in OtterStorage that will serve as the backup target, for example
mi-bucket-velero. See the documentation to create buckets and generate keys. - A credential pair (access key and secret key) with permissions on that bucket. In OtterStorage, credentials are issued per bucket.
The OtterStorage S3 endpoint is https://es-mad-1.s3.otterstorage.io and the examples use the region eu-mad. Because we don't charge for requests or deletions, you can run frequent backups and apply aggressive expiration policies without per-operation cost getting out of hand: you only pay for the storage you use.
1. Create the credentials file
Velero reads credentials from a file in the AWS profile format. Create a file named credentials-velero with your bucket's access key and secret key:
[default]
aws_access_key_id=YOUR_ACCESS_KEY
aws_secret_access_key=YOUR_SECRET_KEY
Replace YOUR_ACCESS_KEY and YOUR_SECRET_KEY with the keys you generated for mi-bucket-velero. Keep this file out of your version control; Velero will load it into a Secret inside the cluster during installation.
2. Install Velero pointing to OtterStorage
Use the official AWS plugin (velero/velero-plugin-for-aws), which is fully compatible with OtterStorage. The key is the --backup-location-config block, where you specify the region, the custom endpoint, and the path style (path-style), which is required for S3-compatible storage:
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws \
--bucket mi-bucket-velero \
--secret-file ./credentials-velero \
--use-volume-snapshots=false \
--use-node-agent \
--backup-location-config region=eu-mad,s3ForcePathStyle=true,s3Url=https://es-mad-1.s3.otterstorage.io
Breakdown of the most relevant options:
--use-volume-snapshots=false: disables the cloud provider's native volume snapshots. OtterStorage is an object store; it doesn't manage disk snapshots, so volume data is backed up via the node-agent.--use-node-agent: deploys the node agent (based on Kopia) that copies the contents of persistent volumes directly to the bucket. Essential when not using volume snapshots.s3ForcePathStyle=true: forces path-style addressing (https://es-mad-1.s3.otterstorage.io/mi-bucket-velero) instead of subdomain-based addressing.s3Url=https://es-mad-1.s3.otterstorage.io: defines the OtterStorage endpoint.region=eu-mad: the bucket's region.
Verify that the backup store became available:
velero backup-location get
The PHASE field should show Available. If it shows Unavailable, check the credentials, the bucket name, and that the URL is exactly https://es-mad-1.s3.otterstorage.io.
3. Create a manual backup
To back up all the cluster's resources:
velero backup create backup-completo
To back up only one or more namespaces:
velero backup create backup-app --include-namespaces produccion,staging
Check the backup's status and details:
velero backup describe backup-completo --details
velero backup logs backup-completo
When the backup moves to Completed, its objects (resource metadata and volume data) are stored in mi-bucket-velero.
4. Schedule recurring backups
Use schedule create with a cron expression to automate backups. The following example creates a daily backup at 02:00 that is kept for 30 days (a TTL of 720 hours):
velero schedule create diario \
--schedule="0 2 * * *" \
--ttl 720h0m0s \
--include-namespaces produccion
List and review your schedules:
velero schedule get
velero schedule describe diario
Each run produces an independent backup with a date suffix. Because OtterStorage doesn't charge for requests or deletions, keeping a short retention with automatic expiration via Velero's TTL adds no extra cost for cleanup operations; you simply free up space.
5. Restore from a backup
To restore the full contents of a backup, use restore create with --from-backup:
velero restore create --from-backup backup-completo
You can restore selectively, for example only one namespace, or remap it to a different one:
velero restore create restauracion-app \
--from-backup backup-app \
--include-namespaces produccion \
--namespace-mappings produccion:produccion-restore
Track the restore's progress:
velero restore describe restauracion-app --details
velero restore logs restauracion-app
6. Protect backups with Object Lock
Object Lock adds WORM-style immutability (Write Once, Read Many) to your backups: once written, objects cannot be modified or deleted until their retention period expires. It's an effective defense against ransomware and accidental deletions, since not even compromised credentials can destroy the locked copies.
Requirements
- The bucket must be created with Object Lock enabled from the start; it cannot be enabled on an existing bucket. Create a dedicated bucket for this (for example
mi-bucket-velero) in OtterStorage with the Object Lock option enabled. - Define a default retention rule (
GOVERNANCEorCOMPLIANCEmode) consistent with how long your backups must remain immutable.
Align Velero with the lock period
Make sure the TTL of Velero's backups is consistent with the Object Lock retention. If Velero tries to purge an expired backup before the lock period ends, the deletion will fail until the object is no longer protected. Set the TTL equal to or greater than the bucket's retention:
velero schedule create diario-inmutable \
--schedule="0 2 * * *" \
--ttl 720h0m0s \
--include-namespaces produccion
With a bucket locked for 30 days and a TTL of 30 days, Velero will clean up copies right when they stop being immutable. Remember that requests and deletions are free in OtterStorage, so the only cost variable with Object Lock is the storage taken up by the retained versions while the lock lasts.
Troubleshooting
- The backup-location appears as
Unavailable: verifys3Url=https://es-mad-1.s3.otterstorage.io,s3ForcePathStyle=true, and that the credentials in thecredentials-velerofile correspond to the bucket. SignatureDoesNotMatchor403errors: check that the access key and secret key are correct and that theregionmatches (eu-mad).- Volumes are not being backed up: confirm that you installed with
--use-node-agentand that the node-agent pods areRunningviakubectl -n velero get pods.
For more details on buckets, keys, and endpoints, see the OtterStorage documentation.
Ready to try it out?
Create your account and get your keys in minutes.