Backup β on-demand and scheduled VM disk backups
corral backup ships VM disk backups to any S3/R2-compatible bucket via
rclone β export a stopped VM's disk, upload it, and
restore it later via CDI's image-upload. Scheduled backups run entirely
in-cluster via Kubernetes CronJobs, so nothing depends on your
workstation being online.
Installβ
corral plugin install backup
rclone config # set up your S3/R2 remote once, locally
On-demandβ
corral backup create web --dest r2:backups/corral
# exporting web disk β /tmp/.../web-20260702-120000.img.gz ...
# uploading β r2:backups/corral/web-20260702-120000.img.gz ...
# backed up web β r2:backups/corral/web-20260702-120000.img.gz
corral backup list --dest r2:backups/corral
corral backup restore web-restored --src r2:backups/corral/web-20260702-120000.img.gz --size 20Gi
# downloading r2:backups/corral/web-...img.gz β /tmp/...
# uploading into PVC web-restored (20Gi) via CDI ...
# restored β DataVolume corral-vms/web-restored
# attach it to a VM with: corral create <name> --pvc web-restored
The VM must be stopped to export (the disk needs to be quiescent).
Scheduled (in-cluster CronJobs)β
corral backup schedule web --every 24h --keep 7 --to r2:backups/corral
corral backup schedules
corral backup unschedule web
--every accepts 30m / 1h / 6h / 12h / 24h, or a raw 5-field cron
expression. The CronJob pod fetches virtctl (matched to the cluster's
actual installed KubeVirt version, not a hardcoded pin) and rclone at
runtime β no bespoke image required. Your local rclone config (the
remote's credentials) gets mirrored into a namespaced Secret the CronJob
mounts read-only, since the pod has no other way to reach your remote.
Retention prunes this VM's own backups on the remote beyond --keep β
mirrors the same prune pattern the snapsched plugin uses for
snapshots.
Requirementsβ
rclone, configured for your remote (rclone config) β local machine for on-demand backups, mirrored into a Secret for scheduled onesvirtctl