Skip to content

Backup CRD

The Backup Custom Resource Definition defines a one-off or on-demand backup of Kubernetes resources and persistent volumes. Retour discovers volumes automatically when you reference a Deployment, StatefulSet, or Namespace — no need to manually list PVCs.

Overview

  • API Group: retour.thebackup.company/v1
  • Kind: Backup
  • Scope: Namespaced
  • Default behavior: When namespacedResources and clusterResources are empty, the Backup has no resources to back up. You must specify at least one resource.

Spec

Required Fields

Field Type Description
storageBackend string Name of the StorageBackend to use. Must exist in the same namespace as the Backup.

Optional Fields (with defaults)

Field Type Default Description
namespacedResources array [] List of namespaced resources to backup (Deployment, StatefulSet, PersistentVolumeClaim, etc.).
clusterResources array [] List of cluster-scoped resources (Namespace, PersistentVolume, StorageClass, etc.).
excludePVs bool false If true, skip PV data — backup manifests only. Useful for configuration backup.
resourceFilter object nil Include/exclude rules for discovered resources when backing up a Namespace or cluster.

NamespacedResource

Field Type Required Default Description
resourceType string Yes — Resource type (e.g., Deployment, StatefulSet, PersistentVolumeClaim).
name string Yes — Name of the resource.
namespace string Yes — Namespace of the resource.
apiGroup string No inferred API group (e.g., apps, storage.k8s.io). Omitted for core resources.
pvFilters array No [] Path filters for PVCs attached to this resource.

ClusterResource

Field Type Required Default Description
resourceType string Yes — Resource type (e.g., Namespace, PersistentVolume, StorageClass).
name string Yes — Name of the resource.
apiGroup string No inferred API group (e.g., storage.k8s.io).
pvFilters array No [] Path filters for PVs.

ResourceFilter

Field Type Default Description
excludeResourceTypes []string [] Resource types to exclude (e.g., Secret, ConfigMap, Pod).
excludeResourceNames []string [] Regex patterns for resource names to exclude (e.g., ^debug-, ^test-).
excludeResourceLabels LabelSelector nil Label selector for resources to exclude.

PVFilter

Field Type Required Default Description
name string Yes* — Name of the PV/PVC. (*Not required when skip: true.)
include []string No [] Directories/files to include.
exclude []string No [] Directories/files to exclude.
filterRules []string No [] Glob patterns (e.g., /data/*, *.log).
skip bool No false If true, skip this PVC entirely.

Scope and Discovery

Field Type Default Description
scope string Namespaced Namespaced protects exactly what the resource lists name. Cluster sweeps every namespace plus cluster-scoped resources (CRDs, StorageClasses, PriorityClasses, IngressClasses), and is mutually exclusive with the explicit lists.
excludedNamespaces []string [] Namespaces to leave out of a Cluster sweep. kube-system, kube-public, kube-node-lease and the operator's own namespace are out by default, as is any namespace annotated retour.io/exclude-from-backup: "true".
includedSystemNamespaces []string [] System namespaces to sweep after all, one by one.
includeWebhookConfigurations bool false Include Validating/MutatingWebhookConfigurations in a Cluster sweep. Off by default: a restored webhook whose backing service is not up yet, with failurePolicy: Fail, blocks the API writes the rest of the restore needs.
resourceDiscovery string Registry Registry enumerates Retour's fixed kind registry. Dynamic also discovers every namespaced resource the API server serves, so operator CRs are captured instead of missed. Secrets, ServiceAccounts and RBAC objects are never captured either way.

Data and Consistency

Field Type Default Description
skipVerification bool false Turns off the post-upload check of the stored data against the source and the decode of the stored metadata document. Verification is on by default and a failure fails the backup.
bandwidthLimit string — Overrides the backend's transfer.bandwidthLimit for this run. Full rclone --bwlimit syntax, timetables included.
volumeGroups array [] Label-selected groups of PVCs captured in one CSI VolumeGroupSnapshot, so several volumes share an instant. Where the cluster has no VolumeGroupSnapshot API the fallback to individual snapshots is recorded, not assumed.
hooks object nil pre and post commands executed in application containers around the snapshot. A hook can hold one exec session across the whole snapshot window, which is what pg_backup_start / pg_backup_stop need. Profiles ship for PostgreSQL, MySQL, MongoDB, Redis and qemu-guest freeze.
databases object nil databases.cnpg.mode: Delegate hands CloudNativePG clusters to the database operator's own backup, and takes their PVCs out of the snapshot set. Two systems protecting the same volume cannot agree on one consistent point.
secrets object nil secrets.mode: EncryptedOptIn adds the encrypted Secrets stream. It needs three things: the operator-level admin switch, a crypt backend, and a passphrase of its own that differs from the main one.

Lifetime

Field Type Default Description
ttl string — Deletes this Backup once it has been terminal for that long (72h, 720h). Standalone backups only; on schedule-owned backups retention governs and the TTL is ignored with a TTLIgnored condition.
deletionPolicy string Retain What happens to the data on the backend when the Backup CR is deleted. Delete purges the backup's operation directories; Object Lock retention still defers the purge until the lock expires.

Status

The worker pod writes status as the backup runs; the operator only writes a terminal phase if the worker dies without reporting (condition reason OperatorFallback).

Field Type Description
phase string Pending, Running, Completed, or Failed.
backupUUID string Unique ID of this backup, assigned by the worker.
jobUUID string Unique ID of the worker job that produced this backup. A Restore can reference it via spec.backupJobUUID.
backendPath string Base path on the storage backend under which this backup's data was written.
operations array Per-PVC operation references: operationID, pvcName, namespace, and the backend destination holding that PVC's data and metadata.
startTime string When backup started.
completionTime string When backup finished.
backupSize int64 Total size in bytes.
progress object Per-PV progress: totalPVs, completedPVs, and pvDetails with file and byte counters per volume.
error string Error message if failed.
conditions array Standard Kubernetes conditions (e.g., Complete).
engine string Data plane that wrote this backup, rclone or kopia. A restore through a backend configured for the other engine is refused: the two store data in different layouts.
retainedUntil string When Object Lock retention on this backup's objects expires. Deletion is deferred until then.
secretsCaptured int How many Secrets the encrypted stream captured. Names and values appear nowhere in status, events or logs.
hookStatuses array Per-hook outcome: which container ran what, and whether it succeeded.

Examples

Minimal: Single Deployment

apiVersion: retour.thebackup.company/v1
kind: Backup
metadata:
  name: webapp-backup
spec:
  storageBackend: s3-production
  namespacedResources:
    - resourceType: Deployment
      namespace: production
      name: webapp

Full Namespace

apiVersion: retour.thebackup.company/v1
kind: Backup
metadata:
  name: production-namespace-backup
spec:
  storageBackend: s3-production
  clusterResources:
    - resourceType: Namespace
      name: production

Manifests Only (No PV Data)

apiVersion: retour.thebackup.company/v1
kind: Backup
metadata:
  name: manifests-only
spec:
  storageBackend: s3-production
  excludePVs: true
  namespacedResources:
    - resourceType: Deployment
      namespace: production
      name: webapp

With Resource Filter

apiVersion: retour.thebackup.company/v1
kind: Backup
metadata:
  name: filtered-backup
spec:
  storageBackend: minio
  clusterResources:
    - resourceType: Namespace
      name: my-app
  resourceFilter:
    excludeResourceTypes:
      - Secret
      - Pod
    excludeResourceNames:
      - "^debug-"
      - "^test-"
    excludeResourceLabels:
      matchLabels:
        exclude-from-backup: "true"

With PV Path Filters

apiVersion: retour.thebackup.company/v1
kind: Backup
metadata:
  name: selective-paths-backup
spec:
  storageBackend: s3-production
  namespacedResources:
    - resourceType: StatefulSet
      namespace: production
      name: database
      pvFilters:
        - name: data-pvc
          include:
            - /var/lib/mysql
          exclude:
            - /var/lib/mysql/tmp
            - /var/lib/mysql/logs

StatefulSet with Explicit API Group

apiVersion: retour.thebackup.company/v1
kind: Backup
metadata:
  name: statefulset-backup
spec:
  storageBackend: s3-production
  namespacedResources:
    - resourceType: StatefulSet
      apiGroup: apps
      namespace: production
      name: redis

Whole Cluster, with Dynamic Discovery

apiVersion: retour.thebackup.company/v1
kind: Backup
metadata:
  name: cluster-sweep
spec:
  scope: Cluster
  storageBackend: s3-production
  resourceDiscovery: Dynamic
  excludedNamespaces:
    - staging
    - sandbox

Application-Consistent Database Backup

apiVersion: retour.thebackup.company/v1
kind: Backup
metadata:
  name: postgres-backup
spec:
  storageBackend: s3-production
  namespacedResources:
    - resourceType: StatefulSet
      namespace: production
      name: postgres
  hooks:
    profiles:
      - name: freeze-postgres
        profile: postgres-backup-mode
        namespace: production
        podSelector:
          app: postgres

The profile supplies the commands; you supply the pod targeting. mysql-flush, mongodb-fsynclock, redis-bgsave and qemu-guest-freeze ship alongside it. Session-shaped profiles hold one exec session open across the snapshot window; the others expand to ordinary pre and post hooks.

Encrypted Secrets Stream

The operator gate operator.allowSecretsBackup must be on, and the backend must be crypt:

apiVersion: retour.thebackup.company/v1
kind: Backup
metadata:
  name: app-with-secrets
spec:
  storageBackend: s3-encrypted
  clusterResources:
    - resourceType: Namespace
      name: my-app
  secrets:
    mode: EncryptedOptIn

Expiring Backup

apiVersion: retour.thebackup.company/v1
kind: Backup
metadata:
  name: pre-upgrade-snapshot
spec:
  storageBackend: s3-production
  ttl: 168h
  deletionPolicy: Delete
  clusterResources:
    - resourceType: Namespace
      name: production