Kubernetes Backup & Restore
A comprehensive guide to backing up and restoring Kubernetes clusters covering Velero, etcd backup, application backup, disaster recovery strategies, and practical implementation for production environments.
Kubernetes clusters are critical infrastructure for modern applications. A disaster (cluster failure, etcd corruption, accidental deletion, security breach) can cause significant downtime and data loss. A robust backup and restore strategy is essential for:
- Disaster Recovery: Recover from cluster failures, hardware issues, or cloud provider outages
- Data Protection: Prevent data loss from accidental deletions or application bugs
- Compliance: Meet regulatory requirements for data retention and audit
- Migration: Move applications between clusters or cloud providers
- Testing: Create copies of production environments for testing
- RPO (Recovery Point Objective): Maximum acceptable data loss (e.g., 1 hour)
- RTO (Recovery Time Objective): Maximum acceptable downtime (e.g., 4 hours)
- 3-2-1 Rule: 3 copies, 2 different media, 1 offsite
- Regular Testing: Restore backups regularly to verify integrity
- Automation: Automate backup creation and retention
Velero
etcd Backup
PV/CSI Snapshots
Database Backups
Velero is the industry-standard tool for backing up and restoring Kubernetes clusters. It provides a comprehensive solution for disaster recovery, cluster migration, and application backup.
# Install Velero (AWS example)
velero install \
--provider aws \
--bucket my-backup-bucket \
--backup-location-config region=us-east-1 \
--snapshot-location-config region=us-east-1 \
--plugins velero/velero-plugin-for-aws:v1.7.0 \
--secret-file ./credentials-velero
# Install Velero (Azure example)
velero install \
--provider azure \
--bucket my-backup-container \
--secret-file ./credentials-azure \
--backup-location-config resourceGroup=velero-rg,storageAccount=velerosa \
--snapshot-location-config apiTimeout=5m
# Install Velero (GCP example)
velero install \
--provider gcp \
--bucket my-backup-bucket \
--secret-file ./credentials-gcp \
--backup-location-config region=us-central1
# Create a backup
velero backup create full-backup --include-namespaces default,production
# Create a backup with specific resources
velero backup create app-backup \
--include-namespaces default \
--include-resources deployments,services,configmaps,secrets
# Exclude resources from backup
velero backup create partial-backup \
--include-namespaces default \
--exclude-resources events,events.events.k8s.io
# Schedule daily backups
velero schedule create daily-backup \
--schedule="0 2 * * *" \
--include-namespaces default,production \
--ttl=168h # Keep for 7 days
# View backups
velero backup get
# Describe backup details
velero backup describe full-backup
# Restore from backup
velero restore create --from-backup full-backup
# Restore specific namespace
velero restore create --from-backup full-backup --include-namespaces production
# Restore with mapping (for cluster migration)
velero restore create \
--from-backup full-backup \
--namespace-mappings default:new-default,production:new-production
- Store backups in a different region from your cluster
- Use scheduled backups for regular backups (daily, weekly)
- Set TTL to automatically expire old backups
- Test restores regularly in a staging environment
- Enable volume snapshots for persistent data backup
- Monitor backup status and alert on failures
etcd stores all cluster state and is the single source of truth for Kubernetes. Backing up etcd is essential for recovering from control plane failures or cluster corruption.
# etcd backup (using etcdctl)
ETCDCTL_API=3 etcdctl snapshot save /backups/etcd-$(date +%Y%m%d-%H%M%S).db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
# Verify snapshot integrity
ETCDCTL_API=3 etcdctl snapshot status /backups/etcd-20250115-020000.db
# etcd backup script (automated)
#!/bin/bash
BACKUP_DIR="/backups/etcd"
DATE=$(date +%Y%m%d-%H%M%S)
ETCDCTL_API=3 etcdctl snapshot save $BACKUP_DIR/etcd-$DATE.db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
# Keep only last 30 days of backups
find $BACKUP_DIR -name "etcd-*.db" -mtime +30 -delete
# Restore etcd from snapshot
ETCDCTL_API=3 etcdctl snapshot restore /backups/etcd-20250115-020000.db \
--data-dir /var/lib/etcd-restore
# For HA etcd cluster, restore on all nodes
# Stop etcd, replace data directory, restart etcd
# Check etcd health
etcdctl endpoint health --cluster
# Monitor etcd metrics
curl http://localhost:2382/metrics
CSI drivers support volume snapshots, enabling point-in-time backups of persistent volumes. This is essential for stateful applications and databases.
# VolumeSnapshotClass
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
name: ebs-snapshot-class
driver: ebs.csi.aws.com
deletionPolicy: Delete
parameters:
force-create: "true"
# Create VolumeSnapshot
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: pvc-snapshot
namespace: default
spec:
volumeSnapshotClassName: ebs-snapshot-class
source:
persistentVolumeClaimName: data-postgres-0
# Check snapshot status
kubectl get volumesnapshot
kubectl describe volumesnapshot pvc-snapshot
# Restore from snapshot (create new PVC)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-restored
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
dataSource:
name: pvc-snapshot
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
# Using Velero with volume snapshots
velero backup create app-with-snapshots \
--include-namespaces default \
--snapshot-volumes
# Restore with volume snapshots
velero restore create --from-backup app-with-snapshots
- Use CSI drivers that support snapshots (EBS CSI, GCE PD CSI, etc.)
- Snapshots are more efficient than copying data
- Combine with Velero for application-level backup
- Test snapshot restore procedures regularly
- Implement snapshot retention policies
# PostgreSQL backup (pg_dump)
apiVersion: batch/v1
kind: CronJob
metadata:
name: postgres-backup
spec:
schedule: "0 2 * * *" # Daily at 2 AM
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: postgres:15
command:
- /bin/sh
- -c
- |
export PGPASSWORD=$POSTGRES_PASSWORD
pg_dump -h postgres-0.postgres -U postgres mydb > /backups/mydb-$(date +%Y%m%d).sql
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: password
volumeMounts:
- name: backup
mountPath: /backups
restartPolicy: Never
volumes:
- name: backup
persistentVolumeClaim:
claimName: backup-pvc
# MySQL backup (mysqldump)
apiVersion: batch/v1
kind: CronJob
metadata:
name: mysql-backup
spec:
schedule: "0 3 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: mysql:8.0
command:
- /bin/sh
- -c
- |
mysqldump -h mysql-0.mysql -u root -p$MYSQL_ROOT_PASSWORD --all-databases > /backups/all-dbs-$(date +%Y%m%d).sql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: root-password
volumeMounts:
- name: backup
mountPath: /backups
restartPolicy: Never
# MongoDB backup (mongodump)
apiVersion: batch/v1
kind: CronJob
metadata:
name: mongodb-backup
spec:
schedule: "0 4 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: mongo:6.0
command:
- /bin/sh
- -c
- |
mongodump --host mongodb-0.mongodb --out /backups/mongo-$(date +%Y%m%d)
volumeMounts:
- name: backup
mountPath: /backups
restartPolicy: Never
- Use database-specific tools for logical backups
- Schedule backups during low-traffic periods
- Compress backups to save storage space
- Store backups in a separate location (object storage)
- Implement backup verification and alerting
- Test database restore procedures regularly
A comprehensive disaster recovery strategy combines multiple backup approaches to ensure data protection and cluster recovery.
Full Cluster Backup
Multi-Region DR
Point-in-Time Recovery
Cross-Cluster Migration
# Disaster Recovery Procedure
# 1. etcd restore (for control plane failure)
# Stop etcd on all nodes
systemctl stop etcd
# Restore from snapshot on each node
ETCDCTL_API=3 etcdctl snapshot restore /backups/etcd-20250115-020000.db \
--data-dir /var/lib/etcd-restore
# Start etcd with new data directory
systemctl start etcd
# 2. Velero restore (for application failure)
# Check available backups
velero backup get
# Restore full cluster
velero restore create --from-backup full-backup
# 3. Database restore (for data corruption)
# Restore from database backup
pg_restore -h postgres-0.postgres -U postgres -d mydb /backups/mydb-20250115.sql
# 4. Verify cluster health
kubectl get nodes
kubectl get pods --all-namespaces
kubectl get pv,pvc --all-namespaces
# 5. Post-recovery validation
# Check application functionality
# Verify data integrity
# Monitor for any issues
Define and document your Recovery Time Objective (RTO) and Recovery Point Objective (RPO) to guide your backup strategy.
| Objective | Definition | Example Target | Strategy |
|---|---|---|---|
| RTO | Maximum acceptable downtime | 4 hours | Automated restore, documented procedures |
| RPO | Maximum acceptable data loss | 1 hour | Hourly backups, WAL archiving |
| Backup Frequency | How often backups are taken | Daily (full), Hourly (incremental) | Velero schedules, database backups |
| Retention Period | How long backups are kept | 30 days | TTL settings, lifecycle policies |
| Restore Testing | How often restores are tested | Monthly | Automated restore tests |
# Velero backup monitoring
# Check backup status
velero backup get
velero backup describe full-backup
# Monitor backup metrics (Prometheus)
# Velero exposes metrics on port 8085
curl http://localhost:8085/metrics | grep velero
# Key metrics to monitor:
# - velero_backups_total (total backups)
# - velero_backup_success_total (successful backups)
# - velero_backup_failure_total (failed backups)
# - velero_backup_duration_seconds (backup duration)
# - velero_restore_success_total (successful restores)
# Alerting rules (Prometheus)
- alert: VeleroBackupFailed
expr: increase(velero_backup_failure_total[5m]) > 0
annotations:
summary: "Velero backup failed"
description: "A Velero backup has failed. Check the logs for details."
# Check backup logs
kubectl logs -n velero deployment/velero
# Velero backup validation hook
apiVersion: velero.io/v1
kind: Backup
metadata:
name: validated-backup
spec:
hooks:
resources:
- name: post-backup-validation
includedNamespaces:
- default
post:
- exec:
container: app
command:
- /bin/sh
- -c
- /scripts/validate-backup.sh
onError: Fail
- Monitor backup success/failure rates
- Alert on backup failures immediately
- Track backup storage usage and costs
- Monitor backup completion time against SLOs
- Implement automated backup health checks
A robust backup and restore strategy is essential for production Kubernetes clusters. Implement regular backups, test your restores, and document your disaster recovery procedures to ensure business continuity.