Kubernetes Backup with Velero
Velero is an open-source Kubernetes backup and restore solution that enables disaster recovery, migration, and compliance for Kubernetes clusters. This guide covers installation, backup scheduling, restore operations, volume snapshots, cluster migration, and configuring S3-compatible object storage backends for your VPS and baremetal Kubernetes infrastructure.
Table of Contents
- Velero Overview
- Installation
- Storage Backend Configuration
- Backup Operations
- Restore Operations
- Volume Snapshots
- Cluster Migration
- Advanced Configuration
- Conclusion
Velero Overview
What is Velero?
Velero is a backup and restore solution for Kubernetes that:
- Backs up cluster resources and persistent volumes
- Schedules automated backups
- Restores to original or different clusters
- Migrates resources between clusters
- Enables disaster recovery workflows
Components
Velero Server: Runs in the cluster, manages backups/restores
Velero CLI: Command-line tool for backup operations
Plugins: Integration with storage backends (S3, Azure, vSphere, AWS, etc.)
Restores: Apply backed-up resources to clusters
Installation
Prerequisites
- Kubernetes v1.16+
- kubectl configured
- Object storage (S3, MinIO, S3-compatible)
- AWS account or MinIO setup (optional)
Installing Velero CLI
On Linux:
wget https://github.com/vmware-tanzu/velero/releases/download/v1.12.1/velero-v1.12.1-linux-amd64.tar.gz
tar -xzf velero-v1.12.1-linux-amd64.tar.gz
sudo mv velero-v1.12.1-linux-amd64/velero /usr/local/bin/
velero version
On macOS:
brew install velero
velero version
Installing Velero in Kubernetes
Create credentials file for S3:
cat << EOF > credentials-velero
[default]
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
EOF
Install Velero:
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.8.1 \
--bucket velero-backups \
--secret-file ./credentials-velero \
--use-volume-snapshots=true \
--snapshot-location-config snapshotLocation=us-east-1 \
--use-mutatingleiamingestaddin=true \
--wait
Verify installation:
kubectl get pods -n velero
velero version
Storage Backend Configuration
AWS S3 Backend
Configure for AWS S3:
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.8.1 \
--bucket velero-backups \
--secret-file ./credentials-velero \
--use-volume-snapshots=true \
--snapshot-location-config snapshotLocation=us-east-1 \
--prefix production \
--wait
MinIO Backend
For on-premises S3-compatible storage:
# Create credentials file
cat << EOF > minio-credentials
[default]
aws_access_key_id=minioadmin
aws_secret_access_key=minioadmin
EOF
# Install Velero with MinIO
velero install \
--provider aws \
--plugins velero/velero-plugin-for-aws:v1.8.1 \
--bucket velero-backups \
--secret-file ./minio-credentials \
--use-volume-snapshots=false \
--backup-location-config s3Url=https://minio.example.com:9000 \
--wait
Multiple Backup Locations
Create backup locations programmatically:
apiVersion: velero.io/v1
kind: BackupStorageLocation
metadata:
name: aws-us-east-1
namespace: velero
spec:
provider: aws
objectStorage:
bucket: velero-backups-east
config:
region: us-east-1
---
apiVersion: velero.io/v1
kind: BackupStorageLocation
metadata:
name: aws-us-west-2
namespace: velero
spec:
provider: aws
objectStorage:
bucket: velero-backups-west
config:
region: us-west-2
Azure Backend
Configure Azure Blob Storage:
velero install \
--provider azure \
--plugins velero/velero-plugin-for-microsoft-azure:v1.8.0 \
--bucket velero \
--secret-file ./azure-credentials \
--use-volume-snapshots=true \
--snapshot-location-config snapshotLocation=eastus \
--wait
Backup Operations
On-Demand Backup
Create immediate backup:
velero backup create production-backup-$(date +%Y%m%d-%H%M%S)
With include/exclude filters:
velero backup create full-backup \
--include-namespaces production,monitoring \
--exclude-namespaces kube-system,velero
Backup specific resources:
velero backup create app-backup \
--include-resources deployments,services,configmaps \
--exclude-namespaces kube-system
Scheduled Backups
Create a backup schedule:
velero schedule create daily-backup \
--schedule "0 2 * * *" \
--include-namespaces production \
--ttl 720h
List schedules:
velero schedule get
velero schedule describe daily-backup
Backup Configuration
Full backup example with scheduling:
velero schedule create production-daily \
--schedule "0 2 * * *" \
--include-namespaces production,monitoring \
--exclude-namespaces kube-system,kube-public \
--ttl 2160h \
--wait
Viewing Backups
List all backups:
velero backup get
Get backup details:
velero backup describe production-backup-20240101-120000
View backup logs:
velero backup logs production-backup-20240101-120000
Restore Operations
Basic Restore
Restore latest backup:
velero restore create --from-backup production-backup-20240101-120000
Restore with filtering:
velero restore create production-restore \
--from-backup production-backup-20240101-120000 \
--include-namespaces production \
--include-resources deployments,services,configmaps
Selective Namespace Restore
Restore to different namespace:
velero restore create restore-to-staging \
--from-backup production-backup-20240101-120000 \
--namespace-mappings production:staging
Restore with Resource Modification
Restore and modify resources:
# Use restore hooks to modify resources during restore
cat << 'EOF' > restore-actions.yaml
apiVersion: velero.io/v1
kind: Restore
metadata:
name: production-restore
spec:
backupName: production-backup-20240101-120000
hooks:
resources:
- name: update-database-config
includedNamespaces:
- production
includedResources:
- configmaps
labelSelector:
matchLabels:
app: database
postHooks:
- exec:
container: config-updater
command: ["/scripts/update-db-config.sh"]
waitTimeout: 5m
EOF
kubectl apply -f restore-actions.yaml
Monitor Restore Progress
velero restore get
velero restore describe production-restore --details
velero restore logs production-restore
Volume Snapshots
EBS Volume Snapshots
Configure snapshot locations:
apiVersion: velero.io/v1
kind: VolumeSnapshotLocation
metadata:
name: aws-snapshot-location
namespace: velero
spec:
provider: aws
config:
region: us-east-1
snapshotLocation: us-east-1a
Enable for backups:
velero backup create volume-backup \
--snapshot-locations aws-snapshot-location \
--volume-snapshot-locations aws-snapshot-location
Snapshot Retention
Set retention policy:
velero backup create data-backup \
--ttl 720h \
--snapshot-move-data=false
List Snapshots
velero snapshot-location get
Cluster Migration
Pre-Migration Steps
- Backup source cluster
- Prepare target cluster
- Configure same backup location
Migration Process
On source cluster, create full backup:
velero backup create migration-backup \
--include-namespaces "*" \
--exclude-namespaces kube-system,kube-public,kube-node-lease
On target cluster:
- Install Velero with same backup location
- Wait for backup to be available
velero backup get
Restore from backup:
velero restore create migration-restore \
--from-backup migration-backup \
--wait
Migrating to Different Storage Class
Use restore transformation:
velero restore create storage-upgrade \
--from-backup migration-backup \
--skip-api-validation-crds
Or use patch during restore:
apiVersion: velero.io/v1
kind: Restore
metadata:
name: storage-class-migrate
spec:
backupName: migration-backup
hooks:
resources:
- name: change-storage-class
includedResources:
- persistentvolumeclaims
postHooks:
- exec:
container: kubectl
command: ["/bin/sh", "-c"]
args:
- "kubectl patch pvc --all -p '{\"spec\":{\"storageClassName\":\"fast-ssd\"}}'"
Advanced Configuration
Custom Velero Configuration
Create custom Velero deployment:
apiVersion: v1
kind: ConfigMap
metadata:
name: velero-config
namespace: velero
data:
enable-restic: "true"
restic-timeout: "24h"
restore-only: "false"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: velero
namespace: velero
spec:
template:
spec:
containers:
- name: velero
args:
- server
- --features=EnableCSI
env:
- name: VELERO_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: AWS_SHARED_CREDENTIALS_FILE
value: /credentials/cloud
Backup Retention Policies
Implement automatic cleanup:
# Set TTL (time to live) for backups
velero schedule create daily-backups \
--schedule "0 2 * * *" \
--ttl 720h \
--include-namespaces production
Restic for PV Backup
Enable Restic for volume backups:
velero install \
--use-restic \
--restic-timeout 24h
Specify which volumes to backup:
apiVersion: v1
kind: Pod
metadata:
name: app-with-volume
annotations:
backup.velero.io/backup-volumes: data,logs
spec:
volumes:
- name: data
persistentVolumeClaim:
claimName: data-pvc
- name: logs
persistentVolumeClaim:
claimName: logs-pvc
Practical Examples
Example: Production Backup and Restore Strategy
# Daily incremental backups
velero schedule create production-daily \
--schedule "0 2 * * *" \
--include-namespaces production \
--exclude-namespaces kube-system \
--ttl 2160h \
--wait
# Weekly full backups with longer retention
velero schedule create production-weekly \
--schedule "0 3 * * 0" \
--include-namespaces "*" \
--exclude-namespaces kube-system,kube-public \
--ttl 4320h \
--wait
# View schedules
velero schedule get
# Test restore process monthly
velero backup create monthly-test-backup
velero restore create monthly-test-restore --from-backup monthly-test-backup --wait
Example: Disaster Recovery Workflow
# Production cluster backup
velero backup create dr-backup-$(date +%Y%m%d) \
--include-namespaces production,monitoring,ingress-nginx \
--snapshot-volumes \
--wait
# Verify backup completion
velero backup describe dr-backup-20240101
# If disaster occurs, restore to new cluster
# 1. Install Velero on new cluster with same storage location
# 2. Restore backup
velero restore create disaster-recovery \
--from-backup dr-backup-20240101 \
--wait
# Monitor restore
velero restore describe disaster-recovery --details
Conclusion
Velero is essential for Kubernetes disaster recovery, migration, and compliance on VPS and baremetal infrastructure. By implementing automated backup schedules, regularly testing restore procedures, and leveraging volume snapshots, you create a robust backup and recovery strategy. Start with simple daily backups of production namespaces, progressively add scheduled snapshots for faster recovery, and regularly test restore procedures to ensure backup integrity. Maintain clear documentation of your backup strategy and recovery procedures for your operations team.


