Skip to content

Restore Operations

The VolumeRestore CRD restores data from a Restic repository to a new or existing PersistentVolumeClaim. Restores run as one-shot Kubernetes Jobs with configurable retries.

Source Options

A VolumeRestore can pull data from two types of sources:

From a VolumeBackup Reference

The simplest approach -- reference an existing VolumeBackup resource and the operator inherits the repository URL, credentials, host, and paths:

spec:
  sourceBackup:
    volumeBackupRef:
      name: my-volume-backup
      namespace: default    # Optional, defaults to same namespace

From a Direct Repository

Connect directly to a Restic repository without an existing VolumeBackup:

spec:
  sourceRepository:
    type: s3
    url: "s3:s3.amazonaws.com/my-bucket/backups"
    secretRef:
      name: backup-credentials
    host: "production-server"   # Filter snapshots by host

Target PVC

Create a New PVC

spec:
  targetPVC:
    createNew: true
    name: "restored-data"          # Optional, defaults to {restore-name}-restored
    size: "20Gi"                   # Optional, inherits from source
    storageClass: "fast-ssd"       # Optional, inherits from source
    accessMode: "ReadWriteOnce"    # Optional, default ReadWriteOnce
    labels:
      app: "postgres"
    annotations:
      description: "Restored from production backup"

Note

The restored PVC is not deleted when the VolumeRestore resource is deleted. This ensures restored data persists independently.

Restore to an Existing PVC

spec:
  targetPVC:
    createNew: false
    name: "existing-app-data"   # Must already exist

Snapshot Selection

By default, the latest snapshot is restored. You can select a specific snapshot:

By snapshot ID:

spec:
  sourceBackup:
    volumeBackupRef:
      name: my-backup
    snapshotId: "abc123def456"

By date (restores the snapshot closest to the specified time):

spec:
  sourceBackup:
    volumeBackupRef:
      name: my-backup
    snapshotDate: "2025-01-15T14:30:00Z"

Overwrite Modes

Control how existing files in the target PVC are handled:

Mode Description
always Overwrite all files unconditionally
if-changed Only overwrite if file content has changed
if-newer Only overwrite if the backup version is newer
never Never overwrite existing files (default)
spec:
  restoreSpec:
    overwrite: "if-changed"

Selective Restore

Restore specific paths or exclude patterns:

spec:
  restoreSpec:
    paths:
      - "/app/data"
      - "/app/config"
    exclude:
      - "*.tmp"
      - "*.log"
    targetPath: "/restored"   # Restore into a subdirectory

Cross-Namespace Restore

Restore data from a production backup into a staging namespace:

apiVersion: backups.k8s.bnerd.com/v1
kind: VolumeRestore
metadata:
  name: staging-restore
  namespace: staging
spec:
  sourceBackup:
    volumeBackupRef:
      name: production-database-backup
      namespace: production

  targetPVC:
    createNew: true
    name: "staging-database"
    size: "10Gi"
    storageClass: "standard"

  restoreSpec:
    paths: ["/"]
    overwrite: "always"

Job Configuration

Field Default Description
jobConfig.retries 3 Number of retry attempts (max 10)
jobConfig.backoffLimit 6 Kubernetes Job backoff limit
jobConfig.activeDeadlineSeconds -- Job timeout in seconds
jobConfig.keepSuccessfulJobs 3 Successful Jobs to retain (max 10)
jobConfig.keepFailedJobs 3 Failed Jobs to retain (max 10)

Monitoring a Restore

Watch the restore progress:

kubectl get volumerestore staging-restore -w
NAME              SOURCE                       TARGET PVC          PHASE       PROGRESS   DURATION   AGE
staging-restore   production-database-backup   staging-database    Running     45%        2m30s      3m

Check the restore Job logs:

kubectl logs job/staging-restore-restore -f

Status Phases

Phase Description
Pending Resource created, not yet processing
Running Restore Job is active
Succeeded Restore completed successfully
Failed All retries exhausted
Retrying A previous attempt failed, retrying