S3 Backup Setup¶
This guide covers configuring VolumeBackup with S3-compatible storage backends including AWS S3, MinIO, Ceph RGW, Wasabi, and b'nerd Object Storage.
Repository URL Format¶
The URL format varies by provider:
| Provider | URL Format |
|---|---|
| AWS S3 | s3:s3.amazonaws.com/bucket/path |
| AWS S3 (specific region) | s3:s3.eu-central-1.amazonaws.com/bucket/path |
| MinIO | s3:https://minio.example.com/bucket/path |
| Ceph RGW | s3:https://rgw.example.com/bucket/path |
| Wasabi | s3:s3.eu-central-1.wasabisys.com/bucket/path |
| b'nerd Object Storage | s3:https://storage.muc1.de.bnerd.com/bucket/path |
Credentials Secret¶
Create a Secret with your S3 credentials and Restic repository password:
apiVersion: v1
kind: Secret
metadata:
name: s3-backup-credentials
namespace: default
type: Opaque
stringData:
AWS_ACCESS_KEY_ID: "your-access-key-id"
AWS_SECRET_ACCESS_KEY: "your-secret-access-key"
RESTIC_PASSWORD: "your-restic-repository-password"
For region-specific endpoints, you can optionally include:
Warning
The RESTIC_PASSWORD encrypts your repository. If lost, your backups cannot be decrypted. Store it securely outside of the cluster.
Full Example¶
apiVersion: backups.k8s.bnerd.com/v1
kind: VolumeBackup
metadata:
name: app-data-backup
namespace: default
spec:
volumeClaimRef:
name: app-data-pvc
schedule: "0 3 * * *" # Daily at 3 AM
repository:
type: s3
url: s3:s3.eu-central-1.amazonaws.com/my-bucket/app-data
secretRef:
name: s3-backup-credentials
paths:
- /data
- /config
exclude:
- "*.tmp"
- "*.log"
- "lost+found"
retention:
keepLast: 15
keepDaily: 7
keepWeekly: 4
keepMonthly: 6
cache:
enabled: true
size: "5Gi"
resources:
requests:
memory: "256Mi"
cpu: "200m"
limits:
memory: "1Gi"
cpu: "1000m"
Retention Policy¶
The retention policy controls how many snapshots are kept after each backup run. Restic applies these rules in order, keeping the union of all matching snapshots:
| Field | Default | Description |
|---|---|---|
keepLast |
15 |
Always keep the N most recent snapshots |
keepDaily |
7 |
Keep one snapshot per day for N days |
keepWeekly |
4 |
Keep one snapshot per week for N weeks |
keepMonthly |
6 |
Keep one snapshot per month for N months |
After applying the retention policy, Restic runs forget --prune to reclaim storage.
Cache Configuration¶
The operator creates a persistent cache PVC to speed up incremental backups. Restic stores repository metadata in the cache, avoiding repeated downloads from the remote backend.
| Field | Default | Description |
|---|---|---|
cache.enabled |
true |
Enable/disable the cache PVC |
cache.size |
5Gi |
Cache volume size |
cache.storageClass |
(cluster default) | Storage class for the cache PVC |
cache.accessMode |
ReadWriteOnce |
PVC access mode |
The cache PVC is named {backup-name}-cache and is automatically cleaned up when the VolumeBackup is deleted.
Integrity Checks¶
Enable periodic repository integrity checks to detect corruption early:
spec:
check:
enabled: true
schedule: "0 4 * * *" # Daily at 4 AM, after backups
readDataSubset: "10%" # Verify 10% of data per run
resources:
requests:
memory: "256Mi"
cpu: "200m"
limits:
memory: "1Gi"
cpu: "1000m"
This creates a separate CronJob ({name}-check) that runs restic check --read-data-subset. Over multiple runs, different subsets are checked, eventually covering the entire repository.
Restore Testing¶
Enable automated restore testing to verify your backups are actually recoverable:
spec:
restoreTest:
enabled: true
schedule: "0 5 * * 0" # Weekly on Sunday at 5 AM
storage:
type: emptyDir # Fast, auto-cleaned (or "pvc" for persistent)
size: "5Gi"
fileCount: 50 # Restore 50 random files
verifyChecksums: true # Verify SHA-256 checksums
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "6Gi"
cpu: "2000m"
This creates a CronJob ({name}-restore-test) that:
- Lists all files in the latest snapshot
- Selects a random sample of files
- Restores them to a temporary volume
- Verifies SHA-256 checksums match the originals
Troubleshooting¶
"connection refused" or timeout errors
- Verify the endpoint URL is reachable from the cluster
- Check if your S3 endpoint requires HTTPS
- For non-AWS endpoints, ensure the full URL including protocol is specified
"wrong credentials" / "access denied"
- Verify
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEYin the Secret - Check that the IAM user/role has
s3:GetObject,s3:PutObject,s3:ListBucket, ands3:DeleteObjectpermissions on the bucket - For path-style endpoints (MinIO, Ceph), the URL must include the protocol
"bucket not found"
- The bucket must exist before creating the VolumeBackup -- Restic does not create buckets
- Verify the bucket name in the repository URL matches exactly