In this post I explain in a practical way how to reliably schedule and operate Kubernetes-Persistent-Volume-Backups. The focus keyword Kubernetes-Persistent-Volume-Backups is set right at the start, because storage backups in containers have different prerequisites, risks and RESTore patterns than classic filesystem backups. The target audience are administrators, system engineers and operators: by the end they should be able to decide which tools and processes match their SLAs and how to operationalize routine, tests and fallback strategies.
Why Persistent-Volume-Backups in Kubernetes are different
PersistentVolume (PV) is the abstract storage object in Kubernetes; a PersistentVolumeClaim (PVC) is an application’s request for a PV. StorageClass describes provisioning (e.g. block-based or NFS). In classic systems you back up filesystems or block devices directly. In Kubernetes additional complexities arise:
- Volatile lifecycles: Pods/StatefulSets can be dynamically re-bound.
- Multiple access paths: NFS/SMB shares and block-based storage behave differently with snapshots.
- Application consistency: databases require quiescing or coordinated snapshots.
These differences mean: the backup tool, snapshot mechanism and RESTore pattern must be aligned.
Kubernetes-Persistent-Volume-Backups: Tool overview
There are three common approaches that complement or replace each other:
- CSI-Snapshots: storage-provider-backed point-in-time snapshots via the Container Storage Interface (CSI). Suitable for fast, consistent block-level copies; does not replace an external backup when additional protection against storage failure is required.
- Backup operators like Velero or Kasten: orchestrate snapshots, back up metadata and can copy volumes to external repositories (object storage). Velero is open source and widely used; Kasten is commercial with more integrations.
- File-/image-level backups with RESTic/Borg/rsync: mount the volume in a Job/Pod and copy the files to a repository. Good for NAS/file shares and when native CSI-Snapshots are not available.
Selection criteria are RTO (Recovery Time Objective), RPO (Recovery Point Objective), storage type (NAS vs block), encryption requirements and compliance. CSI-Snapshots offer low RTOs; external repositories increase resilience against storage failure.
CSI-Snapshots vs. real backups
A CSI-Snapshot is a metadata operation implemented inside the storage backend. It is fast and often consistent for single volumes. Why it is not always sufficient:
- Snapshots live on the same backend: hardware failure or cluster failure can corrupt both source and snapshot data.
- Snapshots are typically not versioned like object-storage backups; retention policies can be more complicated.
- For cross-application consistency (e.g. distributed databases) coordinated quiesce mechanisms are required.
Therefore many teams combine CSI-Snapshots (for fast RESTore) with regular external backups (for disaster recovery).
Backup-CronJobs in Kubernetes: Patterns and Best Practices
For simple file backups or supplementary backups operators use Kubernetes CronJobs (the Kubernetes object for scheduled Jobs). Important aspects are idempotency, locking, logging and clear exit codes.
Example: CronJob that mounts a PVC into a Backup‑Pod and runs rsync to a NAS. This pattern is suitable for NFS-PV or when CSI‑snapshots are not available.
apiVersion: batch/v1
kind: CronJob
metadata:
name: pvc-rsync-backup
spec:
schedule: "0 2 * * *" # täglich 02:00
jobTemplate:
spec:
template:
spec:
RESTartPolicy: OnFailure
volumes:
- name: data
persistentVolumeClaim:
claimName: my-app-pvc
containers:
- name: backup
image: alpine:3.18
command: ["/bin/sh", "-c"]
args:
- |
set -euo pipefail
mountpoint -q /data || (echo "PVC not mounted"; exit 2)
rsync -a --delete /data/ /backup-nfs/my-app/$(date +%F)/
volumeMounts:
- name: data
mountPath: /data
nodeSelector:
backup: "true"
Why this pattern works: A Job mounts the PVC in a standalone Pod, performs a file-based copy and writes to a separate NAS share that lives outside the Kubernetes storage. This decouples the backup retention from the PV backend.
When it fails: If files are open, data is written inconsistently (database‑WAL not flushed), or the Backup‑Pod runs on a node that has no appropriate network paths to the NAS.
Practical additions for CronJobs
- Locking with ConfigMap/Lease so that multiple jobs do not run concurrently.
- Exposed logging (e.g. stdout → Log‑Collector) and exit-code policy to avoid silent failures.
- Resource Limits and NodeSelectors for network and I/O stability.
Example: Locking with ConfigMap
Simple locking can be implemented via a ConfigMap or Lease. This pattern prevents parallel jobs:
#!/bin/bash
set -euo pipefail
LOCK_NAME=my-backup-lock
NAMESPACE=backup
# Try to create ConfigMap as lock
kubectl -n "$NAMESPACE" create configmap "$LOCK_NAME" --from-literal=owner=$(hostname) --dry-run=client -o yaml | kubectl apply -f -
# Check owner (simple approach)
OWNER=$(kubectl -n "$NAMESPACE" get configmap "$LOCK_NAME" -o jsonpath='{.data.owner}')
if [ "$OWNER" != "$(hostname)" ]; then
echo "Another backup is running (owner=$OWNER)"; exit 3
fi
# Run backup here
# On exit (trap) delete lock
RESTore‑Patterns: PVC‑RESTore, Clone and Application Recovery
RESTore has multiple levels: volume RESToration, Pod/StatefulSet reattachment, and application reconstruction (e.g. database recovery). Three common patterns:
- Volume‑RESTore via storage backend (CSI Snapshot RESTore): Snapshot → new PV → PVC binds to new PV. Advantage: fast, block‑level. Disadvantage: potentially the same storage risks.
- Object/Repository → file‑RESTore: copy backup from object storage or NAS back into a new PVC. Advantage: simple verification before production mount. Disadvantage: time-consuming.
- Application‑aware RESTore: e.g. DB point-in-time with WAL‑replay. The RESTore must reconstruct the application’s state (schema, logs, indexes).
Example: RESToring a PVC from Object‑Backup (file‑level)
Steps:
- Create a new PVC with the identical StorageClass but a temporary name.
- Start a Pod that mounts the PVC and copies the backup into the volume.
- Perform integrity checks (checksums, file counts).
- Repoint the production application and swap the PVC or adjust the Deployment.
# Example: RESTore script in the RESTore pod
set -euo pipefail
BACKUP_PATH=/backup-nfs/my-app/2026-07-27/
TARGET=/data
rsync -a --delete "$BACKUP_PATH" "$TARGET/"
# simple integrity check
find "$TARGET" -type f -exec sha256sum {} ; > /tmp/RESTore.sha256
# optional: compare with manifested checksum
Consistency for databases and NAS: Quiesce, Flush and WAL
For databases, a plain file backup is often insufficient. You need:
- Quiesce or flush: instruct the application to flush caches (e.g. MySQL FLUSH TABLES WITH READ LOCK) so files are consistent.
- WAL/transaction logs: for point-in-time recovery (PITR), transaction logs must be archived separately.
For NAS file shares (NFS/SMB), additional issues can occur: open handles, file locks and distributed UID/GID. The backup job must handle open files and ideally trigger coordinated processes at the moment of the backup.
NAS‑How‑To: Best practices, troubleshooting and checklist
NAS in Kubernetes is often provided via NFS or SMB. Such file shares have specific pitfalls that regularly cause issues in operation.
What to prioritize
- UID/GID consistency: user IDs and groups must match between the cluster and the NAS or be handled via a mapping layer; otherwise permissions will not match after RESTore.
- Check open handles: before backup you should detect open file handles and locks, because rsync/copy will otherwise use inconsistent data.
- Quotas and monitoring: NAS target volumes must be monitored, otherwise backup storage fills up and jobs fail silently.
Concrete diagnostic steps (Troubleshooting)
Example commands that help during troubleshooting:
# check open handles on a mounted NAS
lsof +D /data | head
# check which processes hold files on NFS
fuser -m /data
# check space on NAS mount
df -h /backup-nfs
# check permissions of a sample file
stat -c '%U %G %a' /data/somefile
Interpretation: lsof/fuser show processes with open handles. If important DB processes hold open logs, a flush/quiesce must be performed before backup or snapshot/provider-supported mechanisms should be used.
Rsync: chunking and performance
For very large numbers of files, splitting and parallel transfer helps, combined with a deduplicating target (e.g. deduplicating NAS or object storage with dedupe). Example for GNU Parallel with rsync:
# chunked rsync: find list of top-level dirs and sync in parallel
cd /data
find . -maxdepth 1 -mindepth 1 -type d -print0 |
xargs -0 -n1 -P4 -I{} rsync -a --delete "{}" /backup-nfs/my-app/$(date +%F)/"{}"
Caution: parallel sync can create I/O spikes; adjust the number of parallel processes to the node I/O limits.
Checklist for NAS backups
- Beforehand: check storage quotas, plan target space > 2× expected backup size.
- Before the job: detect open handles (lsof/fuser) and perform DB flush.
- During the job: measure logging, exit codes and transfer rate.
- After the job: verify checksums, file counts and retention cleanup (purge).
Velero & object repository: brief practical workflow
Velero (open source) orchestrates cluster-wide backups of resources and volumes. For PVs, Velero uses CSI snapshots (when available) or plugin-based volume backups. Typical steps are:
- Install with a provider plugin (e.g. S3/MinIO/AWS S3).
- Configure backup schedules and RESTic/CSI integration for volume data.
- Perform regular RESTore exercises.
CLI example: Backup of a namespace including volumes (Velero & RESTic):
# Start Velero backup
velero backup create myapp-backup-$(date +%F) --include-namespaces my-app-namespace --snapshot-volumes
# Check status
velero backup get
# RESTore (in test-namespace)
velero RESTore create --from-backup myapp-backup-2026-07-27 --namespace-mappings my-app-namespace:RESTore-test
Velero provides metadata management and simple RESTore orchestration; RESTic integration is useful if you want to store file-level data in object storage.
Kubernetes Persistent Volume Backups: Monitoring, Metrics and Alerts
Operationalizing means measuring metrics. Key metrics:
- Backup success rate (percentage of successful jobs).
- Backup duration (duration per job).
- RESTore duration and RESTore success rate.
- Repository free space and Growth rate.
Prometheus is suitable for collection; example AlertRule for failed backups:
groups:
- name: backup.rules
rules:
- alert: BackupFailures
expr: increase(kube_job_status_failed{job="pvc-rsync-backup"}[24h]) > 0
for: 1h
labels:
severity: page
annotations:
summary: "Backup job failed"
description: "At least one backup job has failed within the last 24h."
Important: Alerts should be linked to runbooks that check whether it’s a configuration/storage issue or a transient network outage.
RESTore Validation: Automated checks and test plan
Validation is mandatory. A RESTore test should always automate the following steps:
- Perform the RESTore into an isolation namespace.
- Mount the RESTored PVC and run file-integrity checks (checksums, file counts).
- Application smoke: health endpoint, run a minimal business process.
- DB consistency: check indexes, replication status, WAL/replication lag.
- Time tracking: document the time required (for RTO reporting).
Example smoke check as a script (see above in the article). Automate such tests in a CI/CD pipeline or as part of the backup job chain so that daily sanity checks run without manual effort.
Practical scenarios, risks and common pitfalls
Common causes for failed backups/RESTores:
- Full backup repository or NAS: jobs fail silently when there is no space.
- Network RESTrictions: backup jobs scheduled on nodes without access to the object storage or NAS will fail.
- Permissions mismatch after RESTore: UID/GID or ACLs don’t match, applications won’t start.
- Ignored exit codes: CronJobs that do not surface errors appear successful even though copy operations failed.
Checklist before production operation:
- SLA mapping: define RTO/RPO.
- Test storage provisioning (CSI snapshot & RESTore).
- Verify the network path from the backup node to the repository.
- Implement automated RESTore verification.
Security and compliance aspects
Encryption, key management and access logging are mandatory for sensitive data. Repositories should be encrypted server-side; additionally, storing keys separately is recommended, for example in an HSM or Vault (HashiCorp Vault is a secrets-management tool that securely manages keys). Audit logs and checksums support compliance evidence.
Rollback and emergency strategy
A RESTore can fail. Plan staged rollbacks:
- Fail over to a standby (if available).
- RESTore into an isolated namespace for validation.
- Switch production to the tested PVC only after successful smoke tests.
Document the rollout steps and responsibilities so that, in an incident, no time is lost to coordination.
Recommendations and conclusion
In summary, I recommend the following pragmatic roadmap:
- Define RTO/RPO and verify StorageClass/CSI snapshot functionality.
- Combine CSI snapshots (for fast RESTores) with external repository backups (for DR scenarios and compliance).
- Use CronJobs only for file-level backups when CSI is not available; implement locking and clean logging.
- Special measures for NAS: check for open handles, ensure UID/GID consistency and plan for chunked transfer.
- Automate and test RESTore paths regularly; integrate smoke tests into CI/CD pipelines.
With this structure you reduce operational risks and create repeatable RESTore processes that make the daily work of administrators and operations teams manageable.
Further reading and internal linking options
This post is conceived as a technical guide and can be extended with existing articles on backup maintenance, network architecture for backup windows and RESTore validation. Internal links to checklists and RESTore playbooks can be usefully inserted here.
FAQ
The most important questions and answers for quick orientation are in the following section.
Do I need both CSI snapshots and external backups?
In most production environments, yes. CSI snapshots are fast and suitable for low RTOs, but they often reside on the same storage backend. External backups (object storage or NAS) protect against backend failure, offer better long-term retention and compliance features.
When is a CronJob backup sensible compared to Velero?
CronJob backups make sense when no CSI snapshot is available (e.g. with NFS-PV), or when you need file-based, application-close copies. Velero, by contrast, offers metadata management, snapshot orchestration and repository integration and is often more robust for cluster-wide policies.
How do I test whether a RESTore really works?
Automate RESTore exercises in an isolated test environment: create a new namespace/PVC, perform the RESTore, and run defined smoke tests (file checks, application health checks, DB integrity checks). Document the time required and deviations from the SLA.
What NAS problems commonly occur during backup?
Common problems are open handles, UID/GID inconsistencies, ACL errors and full backup storage. Check lsof/fuser outputs, synchronize user IDs or use mapping/application accounts, and apply quotas and monitoring for the backup target.