Storage Backends
Configure where Retour stores backups.
Types
| Type | Description |
|---|---|
| s3 | Any S3-compatible endpoint: AWS S3, MinIO, Ceph RGW, Cloudflare R2, Backblaze B2, Wasabi, DigitalOcean Spaces, Hetzner, Scaleway, IBM COS, Oracle, Alibaba OSS, and the rest |
| azureblob | Azure Blob Storage (shared key, SAS URL, or workload identity) |
| gcs | Google Cloud Storage (service-account JSON or Application Default Credentials) |
| crypt | Client-side encrypted wrapper around an s3 backend |
type: local is refused at validation. A local path is a path inside the
carrier pod, which the worker deletes when the job finishes, so the backup went
with it while the CR still reported Completed.
Two settings cut across the types:
engineselects the data plane:rclone(default) orkopia(deduplicated, incremental-forever snapshots). Kopia works ons3,azureblob, andgcs.transferbounds every transfer through the backend:bandwidthLimitin rclone--bwlimitsyntax (a timetable such as08:00,512k 19:00,10M 23:00,offis how a backup window is expressed), plustransfersandcheckers.
S3 Backend
apiVersion: retour.thebackup.company/v1
kind: StorageBackend
metadata:
name: s3-production
namespace: retour
spec:
type: s3
s3:
bucket: retour-backups
region: us-east-1
useSSL: true
secretRef:
name: s3-credentials
keys:
accessKeyID: access-key-id
secretAccessKey: secret-access-key
MinIO, Ceph RGW, and other S3-compatible providers
Point endpoint at the provider. Everything else is the same, which is why the
S3-compatible services (R2, B2's S3 API, Wasabi, Spaces, Hetzner, Scaleway,
IBM COS, Oracle, Alibaba OSS) need no type of their own.
spec:
type: s3
s3:
endpoint: http://minio.retour.svc.cluster.local:9000
bucket: retour-backups
region: us-east-1
useSSL: false
secretRef:
name: minio-credentials
keys:
accessKeyID: access-key-id
secretAccessKey: secret-access-key
AWS S3 with IRSA (no secrets)
On EKS, use IAM Roles for Service Accounts:
The carrier pods must use a ServiceAccount annotated with
eks.amazonaws.com/role-arn.
Server-side encryption and Object Lock
Both are S3-only, and both compose with crypt and with each other:
spec:
type: s3
s3:
bucket: retour-backups
region: us-east-1
serverSideEncryption: "aws:kms" # or AES256 for SSE-S3
kmsKeyID: arn:aws:kms:us-east-1:111122223333:key/abcd-1234
immutability:
mode: COMPLIANCE # or GOVERNANCE
retainDays: 30
secretRef:
name: s3-credentials
keys:
accessKeyID: access-key-id
secretAccessKey: secret-access-key
immutability needs a bucket created with Object Lock enabled. Retention is
applied to every uploaded object after upload, and a lock that cannot be
applied fails the backup rather than reporting an immutability nothing
enforces. Backend data is not deleted until status.retainedUntil passes.
Azure Blob Backend
spec:
type: azureblob
azureblob:
account: retourstorage
container: retour-backups
secretRef:
name: azure-credentials
keys:
accountKey: account-key # or sasToken: sas-url
sasToken takes the full SAS URL for the container or account, not the bare
token. For Azure Workload Identity or a managed identity, drop secretRef and
set envAuth: true. endpoint overrides the blob service endpoint for Azurite
or a sovereign cloud, and is rclone-only: kopia's Azure provider has no
endpoint override, so the combination is refused rather than silently writing
to the real service.
Google Cloud Storage Backend
spec:
type: gcs
gcs:
bucket: retour-backups
secretRef:
name: gcs-credentials
keys:
serviceAccountKey: service-account-json
The secret value is the service-account JSON document itself, not a path to
one. Under GKE Workload Identity, drop secretRef and set envAuth: true so
Application Default Credentials are used. As with Azure, a custom endpoint
(fake-gcs-server, private access endpoints) is rclone-only.
Encrypted Backend (Crypt)
Wrap an S3 backend with rclone crypt. File contents and file names are encrypted client-side, before upload:
apiVersion: v1
kind: Secret
metadata:
name: crypt-credentials
namespace: retour
type: Opaque
stringData:
password: "your-encryption-password"
access-key-id: "minio"
secret-access-key: "minio123"
---
apiVersion: retour.thebackup.company/v1
kind: StorageBackend
metadata:
name: s3-encrypted
namespace: retour
spec:
type: crypt
crypt:
backend: s3
s3:
endpoint: http://minio.retour.svc.cluster.local:9000
bucket: retour-backups
region: us-east-1
useSSL: false
secretRef:
name: crypt-credentials
keys:
password: password
accessKeyID: access-key-id
secretAccessKey: secret-access-key
A crypt backend is also what the encrypted Secrets stream requires, with a
second passphrase under keys.secretsPassword that must differ from this one.
Incremental backups (kopia engine)
spec:
type: s3
engine: kopia
s3:
bucket: retour-backups
region: us-east-1
secretRef:
name: s3-credentials
keys:
accessKeyID: access-key-id
secretAccessKey: secret-access-key
kopiaPassword: kopia-password
kopiaPassword is required on s3, azureblob, and gcs, including under
envAuth: workload identity covers the cloud credentials, not the repository
password. Losing it makes every kopia backup in that repository unrestorable.
Kopia cannot be combined with crypt or with immutability, and both
combinations are refused with a message saying so.
Bandwidth and transfer tuning
spec:
type: s3
transfer:
bandwidthLimit: "08:00,512k 19:00,10M 23:00,off"
transfers: 4
checkers: 8
s3:
bucket: retour-backups
region: us-east-1
A single rate (10M), an upload:download pair (10M:100k), and the timetable
above are all valid. Backup.spec.bandwidthLimit overrides the rate for one
run. On the kopia engine only a simple single rate maps, to the repository
upload throttle.
Connection Test
The operator tests StorageBackend connectivity when the CR is created or changed. Check status:
Phases: Pending → Ready (or Failed with error message)