Build Daily

Tinley Park · October 29, 2026
toolThe Velero project (originally Heptio, then VMware)applied

Velero

Open-source backup, restore and migration for Kubernetes. A controller in the cluster turns Backup and Schedule objects into a tarball of Kubernetes objects in an S3-compatible bucket, and its node-agent copies pod volume data with Kopia into the same bucket. Apache 2.0 and free; the only costs are object storage and the CPU of the data movers. It fits any cluster that needs namespace-level restores, disaster recovery to a new cluster, or migration between clusters.

Updated October 17, 2026

Velero backs up the objects in a Kubernetes cluster and the data in its persistent volumes, and restores both into the same cluster or a different one. It covers the gap that etcd snapshots leave: a restore of one namespace, a rebuild of a lost cluster from a bucket, or a move of workloads to new hardware. The official docs at velero.io/docs own the full API reference.

What it is

A Kubernetes controller (the Velero server, one Deployment in the velero namespace), an optional DaemonSet (the node-agent) for volume data, a set of CRDs in the velero.io API group, and a velero CLI. Storage providers come as plugins: AWS (any S3-compatible store), Azure and GCP are maintained by the project. Licence is Apache 2.0.

The current line is v1.18 (v1.18.4 shipped 2026-09-28). v1.18 added concurrent backup processing, cache volumes for data-mover pods on restore, glob wildcards in namespace filters, and a volume-policy condition on PVC phase. It runs on Kopia 0.22. The repository now lives under the velero-io GitHub organization; links to the old vmware-tanzu repo redirect, and the Helm chart is still published from vmware-tanzu/helm-charts.

The most recent breaking change came in v1.17: the Restic uploader is gone for new backups. --uploader-type=restic is no longer a valid install option, and Kopia is the only file-system backup path. Backups taken with Restic can still be restored until v1.19.

How it works

Every action is a custom resource. A Schedule creates Backup objects on a cron. A Backup names what to include (namespaces, resource types, label selectors) and how to handle volumes. A BackupStorageLocation (BSL) points at a bucket and prefix. A Restore names a backup to read from. The server watches these objects; the CLI only creates and reads them.

Volume data takes one of three routes. Volume snapshots call the storage provider's snapshot API. CSI snapshot data movement takes a CSI snapshot and copies it to the bucket. File-system backup (FSB) has the node-agent read the files of a mounted volume straight from the node and write them with Kopia into a backup repository in the bucket, one repository per namespace. FSB works on any volume type except hostPath, which is why it is the default choice on clusters with local-path storage and no snapshot support.

How a Velero backup and restore run

Step 1 of 6. At the cron time the schedule controller creates a Backup object from its template, with the TTL that decides when it expires.

File-system backup path. Snapshot-based backups replace the node-agent hops with calls to the storage provider.

Two background loops matter for operations. The garbage collector runs hourly and deletes expired backups: the Backup object, its files in the bucket, its snapshots and its Restore objects. The default TTL is 30 days. The bucket sync treats object storage as the source of truth: a valid backup in the bucket with no matching object in the cluster is re-created. That second loop is what makes disaster recovery work. Install Velero on an empty cluster, point it at the same bucket, and the old backups appear.

Backups are not atomic. Objects created or changed during a backup can be missed, and FSB reads a live filesystem, so files in one volume are not captured at the same instant.

When to use it

Reach for it when:

  • A namespace, or a whole cluster, must come back after a bad deploy, a deleted resource or a lost node.
  • Workloads have to move to a new cluster, a new distro or new hardware.
  • Volumes live on local-path or other storage with no snapshot API, and file-level copies are acceptable.
  • One tool should cover several clusters, each writing to its own prefix in a shared bucket.

Skip it when:

  • The data is a database with its own backup tooling. Write-ahead-log archiving restores to a point in time; a file copy of a running data directory does not.
  • The cluster is stateless and fully described in Git. Re-syncing from Git is the restore.
  • Only etcd is at stake on a single-node control plane. The distro's own etcd snapshot covers that case.

At a glance

Core concepts

  • Backup — one run. Holds the include/exclude filters, TTL, volume handling and storage location.
  • Schedule — a cron expression plus a Backup template. Supports CRON_TZ=<IANA zone> prefixes.
  • BackupStorageLocation — bucket, prefix, provider config and credentials. ReadOnly mode is for restores during a migration.
  • Restore — reads one backup; supports namespace mapping, resource filters and an existing-resource policy.
  • Resource policy — a ConfigMap with volumePolicies that map conditions (storage class, CSI driver, volume type, PVC labels, PVC phase) to an action: skip, snapshot or fs-backup. The first match wins.
  • BackupRepository — the Kopia repository for one namespace. Needs periodic maintenance to free space.

Key facts (v1.18)

Item Value
Licence Apache 2.0
Latest release v1.18.4 (2026-09-28)
Uploader Kopia 0.22 (Restic removed for new backups in v1.17)
AWS plugin for v1.18 v1.14.x
Default backup TTL 30 days
GC interval 1 hour
FSB timeout 4 hours (--fs-backup-timeout)
Unsupported volume hostPath
Metrics Prometheus, velero_ prefix

Scope compared

Aspect Velero Rancher Backups Database-native backup
Covers Any objects and volumes Rancher's own CRDs and secrets One database
Volume data Kopia file copy or snapshots None WAL and base backups
Point-in-time restore No No Yes
Restore into new cluster Yes, from the bucket Yes, to migrate Rancher Yes, new instance

How to integrate

Helm values for an S3-compatible store

helm repo add vmware-tanzu https://vmware-tanzu.github.io/helm-charts
helm install velero vmware-tanzu/velero -n velero --create-namespace -f values.yaml
initContainers:
  - name: velero-plugin-for-aws
    image: velero/velero-plugin-for-aws:v1.14.4   # match the Velero minor (1.18 -> 1.14.x)
    volumeMounts:
      - mountPath: /target
        name: plugins

configuration:
  backupStorageLocation:
    - name: default
      provider: aws
      bucket: velero
      prefix: cluster-a          # one prefix per cluster in a shared bucket
      default: true
      config:
        region: us-east-1        # required by the plugin, ignored by most S3-compatible stores
        s3ForcePathStyle: "true"
        s3Url: http://s3.example.svc:8333
  volumeSnapshotLocation: []
  uploaderType: kopia
  defaultVolumesToFsBackup: true

snapshotsEnabled: false
deployNodeAgent: true

credentials:
  existingSecret: velero-s3      # key "cloud" holds an AWS-style credentials file

A volume policy

version: v1
volumePolicies:
  - conditions:
      volumeTypes: [emptyDir]
    action:
      type: skip
  - conditions:
      pvcLabels:
        backup: skip
    action:
      type: skip
kubectl -n velero create configmap volume-policy --from-file=policy.yaml

A nightly schedule

apiVersion: velero.io/v1
kind: Schedule
metadata:
  name: nightly
  namespace: velero
spec:
  schedule: "CRON_TZ=America/New_York 0 3 * * *"
  template:
    ttl: 336h                   # 14 days
    includedNamespaces: ["*"]
    excludedNamespaces: [velero]
    defaultVolumesToFsBackup: true
    resourcePolicy:
      kind: configmap
      name: volume-policy

Check and restore

velero backup get
velero backup describe nightly-20261017030000 --details
velero restore create --from-backup nightly-20261017030000 \
  --include-namespaces app --namespace-mappings app:app-restored
velero restore describe <restore-name>

A restore into a scratch namespace with --namespace-mappings is the cheapest way to prove a backup works without touching the live copy.

In the GL stack

Velero v1.18.4 runs on all three clusters, with the AWS plugin and Kopia file-system backup. Each cluster has one schedule, velero-nightly, that fires at 02:00 Chicago time and keeps backups for 14 days. It covers every namespace except the one that holds the backup store itself, since a copy of the bucket written into the same bucket protects nothing.

A volume policy decides what is worth copying. It skips the CloudNativePG volumes (a file copy of a running Postgres is not a consistent backup), Prometheus data, caches and emptyDirs. What is left is the state that cannot be rebuilt from Git or re-scraped.

Backups go to an S3 bucket named velero on SeaweedFS, with one prefix per cluster, so any cluster can be rebuilt by pointing a fresh Velero at its prefix. Two alerts watch the result: VeleroBackupFailed for a failed run and VeleroBackupTooOld for a schedule that has stopped producing backups.

Gotchas

  • Spring-forward skips the 02:00 run. The docs warn that jobs scheduled inside a daylight-saving leap-ahead do not run. In US zones the clocks jump from 02:00 to 03:00, so a 02:00 local schedule misses one night a year. An age alert catches it; a 03:00 slot avoids it.
  • One shared encryption key. Velero uses a static, common key for every Kopia repository it creates, stored in the velero-repo-credentials secret. Change it before the first backup; changing it later makes older backups unreadable. Anyone with bucket access can decrypt the data, so lock down the bucket.
  • Deleted backups do not free space at once. Kopia space is reclaimed only after full repository maintenance jobs succeed. Watch that maintenance runs.
  • Plugin and server versions are paired. AWS plugin v1.14.x goes with Velero v1.18.x. Upgrade both together.
  • S3-compatible quirks. Since plugin v1.13 (AWS SDK v2), some stores (Ceph, Backblaze B2) need checksumAlgorithm: "" in the BSL config to avoid checksum errors. Non-AWS stores also need s3ForcePathStyle and s3Url.
  • Restores do not overwrite. Existing objects are skipped unless --existing-resource-policy=update is set, and even then PV data is not overwritten. Delete the namespace, or map to a new one, for a clean restore.
  • API versions must exist on the target. Each object is stored at the source cluster's preferred version. A restore fails for any resource whose group and version the target cluster does not serve.
  • Restic leftovers. Clusters upgraded from older versions with --uploader-type=restic must switch to Kopia; old Restic backups stay restorable only until v1.19.

Risks

  • Licence and stewardship. Apache 2.0 with no paid tier in the core project. The project moved from the vmware-tanzu organization to velero-io; the code stays open and forkable, but release timing and plugin support depend on a small maintainer group.
  • Silent coverage gaps. A backup that completes is not a backup that restores. Excluded volumes, missed hostPath data and non-atomic captures only show up on a restore test.
  • Bucket is the single point of truth. Losing or corrupting the bucket loses every backup, and the bucket sync will then delete Completed backups from the cluster to match. Keep a copy of the store off the cluster it protects.
  • Security. The node-agent mounts every pod's volumes from the host, and the BSL secret can read all backed-up data. Both deserve the same care as cluster-admin credentials.

Alternatives

  • Kasten K10 (Veeam) — pick it for a commercial product with a policy UI and vendor support.
  • KubeStash (AppsCode) — pick it for per-application backup CRDs and database add-ons; check its licence terms first.
  • Database-native backup (CloudNativePG, pgBackRest) — pick it for Postgres; WAL archiving gives point-in-time recovery that a volume copy cannot.
  • Rancher Backups — pick it only to protect or migrate a Rancher install; it does not touch workloads or volumes.

Related