Automating etcd Backup and Restore in Gardener Shoot Clusters
Learn how Gardener’s etcd backup sidecar automates snapshots and restores for Shoot clusters, with configuration tips, a worked example, and cost/downtime trade‑offs.
24 Mar 2026, 02:48 UTC

Problem: protecting etcd without manual snapshots
When a Shoot cluster’s etcd database becomes corrupted or lost, the API server stops responding and workloads cannot be scheduled. Manual etcd snapshots are easy to forget, and ad‑hoc scripts often miss the correct retention settings, leaving operators exposed to data loss or unexpected storage charges.
Thesis: Gardener’s built‑in etcd backup sidecar automates snapshot creation and restore, letting you define schedules and retention in the Shoot spec.
How Gardener’s etcd backup sidecar works
When Gardener creates a Shoot, it injects a sidecar container into the etcd StatefulSet. The sidecar watches a Backup custom resource (CR) that you define in the Shoot spec. On the schedule you provide (cron expression), the sidecar runs etcdctl snapshot save, streams the snapshot to the object‑storage bucket you configured, and tags it with a timestamp.
Configuring backup and retention
Backup behavior is controlled under .spec.backup in the Shoot manifest:
spec:
backup:
schedule: "0 2 * * *" # every day at 02:00 UTC
retention:
maxBackups: 30
garbageCollection:
enabled: true
destinations:
- bucket: "my-gardener-backups"
region: "eu-central-1"
provider: "s3"
The schedule field accepts standard cron syntax. maxBackups limits how many snapshots are kept; older ones are removed when garbage collection is enabled. You can add multiple destination entries for cross‑region replication.
Worked example: creating a backup and restoring from it
- Create the Shoot with backup config – apply a Shoot manifest that includes the
.spec.backupblock above. Ensure you havecluster-adminrights on the Garden cluster. - Verify the sidecar is running –
kubectl -n garden‑<shoot-name> get pods -l etcd-sidecar=trueshould show a pod ready. - Wait for the first snapshot – either let the cron trigger or manually create a Backup CR:
- Simulate an etcd failure – delete the etcd pod for member 0:
- Trigger a restore – create a Restore CR pointing to the latest snapshot:
- Validate recovery – after the Restore CR reaches
Readystate, run:kubectl get --raw='/readyz?timeout=5s'If the response is
ok, the API server is healthy. Then check that workloads are rescheduled:kubectl get pods -A | grep -v Completed | grep -v RunningAny
Pendingpods should transition toRunningas the controller manager reschedules them.
kubectl -n garden-<shoot-name> create -f - <
Check the object storage (e.g., AWS CLI):
aws s3 ls s3://my-gardener-backups/<shoot-uid>/ --recursive
You should see a file like etcd-snapshot-2026-09-15T02-00-00Z.db.
kubectl -n garden-<shoot-name> delete pod etcd-0
The API server will become unavailable for a short period.
kubectl -n garden-<shoot-name> create -f - <
Gardener launches a temporary etcd pod, loads the snapshot, and replaces the failed member. During this time the API server is down; plan the restore inside a maintenance window.
Trade‑offs and limitations
- Storage cost – retaining many snapshots can inflate object‑storage bills. Monitor bucket size with cloud‑provider metrics and adjust
maxBackupsor lifecycle rules accordingly. - Restore downtime – replacing an etcd member requires a brief API‑server outage. For workloads that cannot tolerate any interruption, consider deploying a standby control plane (Gardener’s
highAvailabilityfeature) or performing restores during a scheduled maintenance slot. - Network bandwidth – snapshots are streamed to the bucket; large etcd datasets may saturate limited links, especially when using cross‑region replication. Test backup duration in a non‑production Shoot before committing to a tight schedule.
Actionable next steps
- Add a
.spec.backupblock to your existing Shoot manifests, starting with a conservative schedule (e.g., weekly) and a lowmaxBackupsvalue. - Enable object‑storage lifecycle rules to expire snapshots older than your retention period, providing a safety net against runaway costs.
- Document a restore run‑book that includes the steps above, the expected downtime window, and a verification command (
kubectl get --raw='/readyz'). - Schedule a quarterly drill: manually trigger a Backup CR, then a Restore CR in a test Shoot, and confirm that applications return to normal.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.