Tus datos de Kubernetes están a un mal comando de desaparecer: una guía práctica de respaldo con Velero para PYMEs

Your Kubernetes Data Is One Bad Command Away from Gone: A Practical Velero Backup Guide for SMBs

It starts with one command. kubectl delete ns production — a fat-fingered flag, a wrong context, a script with a bug. Or it starts with ransomware encrypting your persistent volumes. Either way, the question is the same: can you get your cluster back? For most SMBs, the honest answer is no.

Cloud snapshots are not enough. An EBS or managed-disk snapshot protects the volume data, but it captures nothing about your cluster state — the Deployments, Services, ConfigMaps, Ingresses, and Secrets that define your application. Rebuilding those by hand after an outage takes days, not hours. And if the cluster itself is gone, your snapshots are orphaned objects in a deleted account. Kubernetes backups are different from VM backups, and treating them the same way is how SMBs lose everything.

The Problem: Kubernetes Backups Are Not VM Backups

A complete Kubernetes backup has three layers, and you need all of them:

  • Cluster state: the API objects — Deployments, Services, ConfigMaps, Secrets, Ingresses, CRDs, and namespaces. This is the “recipe” for your applications.
  • Persistent data: the contents of PersistentVolumes (databases, object stores, upload directories).
  • Restorability: the ability to rebuild in a different cluster, because in a real disaster your old cluster may not exist anymore.

Before you install anything, write down two numbers: RPO (how much data you can afford to lose) and RTO (how fast you must be back). A sensible SMB starting point is RPO of 24 hours and RTO of 4 hours for non-critical workloads, and RPO of 1 hour / RTO of 1 hour for customer-facing or financial systems. Every decision below follows from those numbers. If you have not defined them yet, our guide on building DR that actually works is the place to start.

Meet Velero: Backup, Restore, and Migration in One Tool

Velero is the open-source standard for Kubernetes backup. A small in-cluster controller backs up API objects to object storage (S3, S3-compatible, or Azure Blob), and a node agent performs file-level backups of PersistentVolumes using restic or kopia. It is the same tool for backup, restore, and cluster migration — one skill to learn, one pipeline to maintain.

Installing it against AWS S3 takes minutes:

velero install \
  --provider aws \
  --bucket smb-velero-backups \
  --secret-file ./credentials-velero \
  --backup-location-config region=eu-west-1 \
  --use-volume-snapshots=false \
  --use-node-agent \
  --uploader-type restic \
  --plugins velero/velero-plugin-for-aws:v1.9.0

Two flags deserve attention. --use-volume-snapshots=false disables cloud-native volume snapshots and forces restic file-level backups — simpler, provider-independent, and it works on-premises too. --use-node-agent deploys the daemon that performs those file-level backups. For on-prem or minio users, point the bucket at any S3-compatible endpoint with --backup-location-config s3Url=https://minio.example.com.

Back Up What Matters: Schedules, Scope, and Secrets

An on-demand backup is a good smoke test, but a schedule is what saves you. Declare it as a Velero Schedule object so it lives in Git alongside your cluster config:

apiVersion: velero.io/v1
kind: Schedule
metadata:
  name: daily-app-backup
  namespace: velero
spec:
  schedule: "0 2 * * *"
  template:
    ttl: 720h
    includedNamespaces:
      - app
      - db
    excludedResources:
      - events
      - events.events.k8s.io

Apply it with kubectl apply -f schedule.yaml, and Velero runs it every night at 02:00, keeping each backup for 30 days (ttl: 720h). A few scope rules that prevent classic SMB mistakes:

  • Exclude kube-system and velero namespaces — system internals restore badly and can conflict with the new cluster’s own system components.
  • Exclude ephemeral resources like events and pods; restore the workload, not the wreckage.
  • Know that Secrets are included. Protect the backup bucket with KMS encryption and strict IAM, because your backup now contains your credentials. If that thought makes you uncomfortable, read how to secure credentials without enterprise tools.

Restore Is the Real Test: Prove Your Backups Work

A backup that has never been restored is a rumor. Restore is where Velero earns its keep — and where most SMB backup strategies collapse, because nobody has ever practiced it.

Restore into the same cluster:

velero restore create --from-backup daily-app-backup-20260731-020000
velero restore get
velero restore logs daily-app-backup-20260731-020000-20260731-100000

Restore into a new cluster (the disaster scenario): install Velero in the fresh cluster pointing at the same bucket, then restore with namespace remapping so you can validate before cutting over:

velero restore create --from-backup daily-app-backup-20260731-020000 \
  --namespace-mappings app:app-restored,db:db-restored

Verify the obvious things — kubectl get pods, database contents, ingress routes — and then verify the non-obvious ones: do your Services still resolve, do CronJobs fire, do the restored Secrets match what your app expects? This is exactly what we mean by chaos engineering for SMBs: deliberately breaking things in a controlled way so you know the recovery path works.

Automate, Monitor, and Keep Backups Honest

Backups fail silently. The schedule runs, Velero logs an error, and nobody notices for three weeks — until the restore fails. A tiny check in cron or CI closes that gap:

#!/bin/bash
# backup-health.sh — alert when the latest backup failed or is stale
LATEST=$(velero backup get --output json | jq -r '.items[0].metadata.name')
STATUS=$(velero backup get --output json | jq -r '.items[0].status.phase')

if [ "$STATUS" != "Completed" ]; then
  curl -fsS -X POST -H 'Content-type: application/json' \
    --data '{"text":"VELERO ALERT: latest backup '$LATEST' is '$STATUS'"}' \
    https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
fi

Add a staleness check (alert if no successful backup in 36 hours), monitor the backup bucket size to keep storage costs predictable, and run a quarterly restore drill against a throwaway cluster. Budget tip: keep one full backup per week plus dailies for the last 7 days — with restic-style deduplication, the incremental cost is small, and you avoid the classic trap of 90 identical full copies eating your S3 bill. For the broader cost picture, see how SMBs cut Kubernetes costs by 50%.

Your cluster is not “backed up” because a snapshot exists somewhere. It is backed up when a restore has been proven — and proven again after every major change. The 90-day maturity framework in our disaster recovery maturity guide will show you where backups fit in your overall DR journey.

Not sure your current backup setup would survive a real incident? Book a free consultation — we will audit your backup strategy and run a restore drill with you.

es_ESEspañol
Scroll al inicio