8. Scheduled backups¶
Goal: schedule automatic base backups and confirm that WAL archiving to R2 is actually working. Without WAL archiving you have no point-in-time recovery.
Two things must both work¶
flowchart LR
cl["Cluster (plugin: barman-cloud)"] -->|continuous| wal["WAL archive → R2"]
sb["ScheduledBackup (cron)"] -->|periodic| base["Base backup → R2"]
wal & base --> store[("R2 bucket")]
store --> pitr["PITR = base + replayed WAL"]
- WAL archiving is continuous and was enabled the moment the Cluster
referenced the plugin with
isWALArchiver: true. It is the film. - Base backups are periodic full snapshots. They are the photos. You
schedule them with a
ScheduledBackup.
You need both.
Step 8.1 — Create a ScheduledBackup¶
apiVersion: postgresql.cnpg.io/v1
kind: ScheduledBackup
metadata:
name: pg-daily
namespace: production
spec:
schedule: "0 0 2 * * *" # (1)!
backupOwnerReference: self
cluster:
name: pg
method: plugin # (2)!
pluginConfiguration:
name: barman-cloud.cloudnative-pg.io
target: prefer-standby # (3)!
- CNPG cron has 6 fields (the leading one is seconds).
0 0 2 * * *= 02:00 every day. Don't drop the seconds field. - Plugin method, not the deprecated in-tree
barmanObjectStore. The plugin already knows the destination from the Cluster'sbarmanObjectName. - Back up from a standby when possible, to avoid loading the primary.
(Older guides say
target: primary—prefer-standbyis the kinder default.)
Step 8.2 — Trigger a backup now (don't wait for 2 AM)¶
kubectl cnpg backup pg -n production # on-demand backup
kubectl get backup -n production -w # watch it reach 'completed'
Step 8.3 — Verify WAL archiving is healthy¶
This is the check people skip and regret.
You want to see continuous archiving reporting OK / working and a recent "Last Archived WAL" timestamp. Also confirm objects are actually landing in R2:
aws s3 ls --endpoint-url https://<account-id>.r2.cloudflarestorage.com \
s3://<your-bucket>/pg-cluster/ --recursive | tail
You should see base/ and wals/ prefixes growing.
If WAL archiving shows a failure
Common cause on R2: the checksum env vars are missing or the bucket/endpoint is wrong. Re-check the ObjectStore. A failing WAL archive means no PITR — fix it before putting real data in.
A note on retention¶
Retention (30d in our ObjectStore) is enforced by the plugin: WAL and base
backups older than the window are pruned. For extra safety against accidental
deletes, you can also configure an R2 lifecycle/versioning policy so deleted
objects are recoverable for a few days beyond Barman's retention.
What could go wrong¶
method: barmanObjectStorein the ScheduledBackup → that's the deprecated path; usemethod: plugin.- 5-field cron → CNPG expects 6 fields (seconds first); a 5-field schedule is rejected or misread.
- Backup completes but WAL archive fails → you have base photos but no film; PITR to arbitrary times won't work. Treat WAL archive OK as the real success signal.
Where to go deeper¶
Next: Security.