Operations 11 min read

Essential Velero Guide for Kubernetes Disaster Recovery

This article walks through using Velero to back up, restore, and migrate Kubernetes clusters, covering MinIO installation, Velero client and server setup, storage volume creation, backup location configuration, and execution of backup, restore, and scheduled backup commands.

DevOps Operations Practice
DevOps Operations Practice
DevOps Operations Practice
Essential Velero Guide for Kubernetes Disaster Recovery

What is Velero

Velero (formerly Heptio Ark) is an open‑source backup and restore tool for Kubernetes that can back up an entire cluster or selected resources and migrate them between clusters. It is a CNCF project.

Install MinIO as S3‑compatible object storage

Create a namespace for Velero: $ kubectl create ns velero Create a PersistentVolume and PersistentVolumeClaim for MinIO storage (adjust the NFS server and path as needed):

# storage.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: velero-pv
spec:
  capacity:
    storage: 100Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: 192.168.1.10
    path: /velero-backups/k8s-dev
    readOnly: false
  persistentVolumeReclaimPolicy: Retain
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: velero-pvc
  namespace: velero
spec:
  storageClassName: ""
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 100Gi
  volumeName: velero-pv
$ kubectl create -f storage.yaml

Deploy MinIO (replace the image tag if a newer version is required):

# minio.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: velero
  name: minio
  labels:
    component: minio
spec:
  strategy:
    type: Recreate
  selector:
    matchLabels:
      component: minio
  template:
    metadata:
      labels:
        component: minio
    spec:
      volumes:
      - name: storage
        persistentVolumeClaim:
          claimName: velero-pvc
      - name: config
        emptyDir: {}
      containers:
      - name: minio
        image: minio/minio:RELEASE.2023-03-20T20-16-18Z
        imagePullPolicy: IfNotPresent
        args:
        - server
        - /data
        - --config-dir=/config
        - --console-address=:9001
        env:
        - name: MINIO_ROOT_USER
          value: "admin"
        - name: MINIO_ROOT_PASSWORD
          value: "minio123"
        ports:
        - containerPort: 9000
        - containerPort: 9001
        volumeMounts:
        - name: storage
          mountPath: /data
        - name: config
          mountPath: "/config"
        resources:
          limits:
            cpu: "2"
            memory: 4Gi
          requests:
            cpu: "0.5"
            memory: 0.5Gi
---
apiVersion: v1
kind: Service
metadata:
  namespace: velero
  name: minio
  labels:
    component: minio
spec:
  type: LoadBalancer
  ports:
  - name: port-9000
    port: 9000
    protocol: TCP
    targetPort: 9000
  - name: console
    port: 9001
    protocol: TCP
    targetPort: 9001
  selector:
    component: minio
$ kubectl create -f minio.yaml

Log in to the MinIO console (default credentials: admin / minio123) and create a bucket named velero.

Deploy Velero server

Choose a Velero version compatible with the Kubernetes version (see the compatibility table in the source). Install the Velero client binary:

$ tar xvf velero-v1.12.4-linux-amd64.tar.gz
$ mv velero-v1.12.4-linux-amd64/velero /usr/bin/
$ chmod +x /usr/bin/velero
$ velero version
Client:
    Version: v1.12.4
    Git commit: 7d8417b2c58792422ed6dd4b4c0cf3848b0beb56

Create a credentials file for MinIO access:

# credentials-velero
[default]
aws_access_key_id = admin
aws_secret_access_key = minio123

Install the Velero server with the appropriate flags (adjust the plugin version to match the Velero version):

velero install \
    --provider aws \
    --plugins velero/velero-plugin-for-aws:v1.8.2 \
    --image velero/velero:v1.12.4 \
    --namespace velero \
    --bucket velero \
    --default-volumes-to-fs-backup \
    --use-volume-snapshots=false \
    --secret-file ./credentials-velero \
    --use-node-agent \
    --backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://minio:9000

Verify that the Velero pods are running:

$ kubectl get pod -n velero
NAME                     READY   STATUS    RESTARTS   AGE
minio-...                1/1     Running   0          6h32m
node-agent-...           1/1     Running   0          6h11m
velero-...               1/1     Running   0          6h11m

Backup operations

Backup the entire cluster (no namespace or resource filter): $ velero backup create k8s-dev-backup Backup a specific namespace (example: default):

$ velero backup create default-backup --include-namespaces default

Backup specific resources (example: deployment):

$ velero backup create deployment-backup --include-resources deployment

Backup PVC data – install the node‑agent and annotate the pod:

$ kubectl annotate pod <pod_name> backup.velero.io/backup-volumes=<volume_name>

Restore operations

Cluster‑wide restore:

$ velero restore create --from-backup k8s-dev-backup

Namespace‑specific restore:

$ velero restore create --from-backup k8s-dev-backup --include-namespaces default

Restore specific resource types (e.g., PVCs and PVs):

$ velero restore create --from-backup k8s-dev-backup --include-namespaces default --include-resources persistentvolumeclaims,persistentvolumes

Scheduled backups

Create a daily backup at 01:00 that excludes pods and retains backups for 240 hours:

$ velero schedule create k8s-dev --schedule="0 1 * * *" --exclude-resources pods --ttl 240h

Key points

Velero stores backups in an S3‑compatible bucket; MinIO serves as the storage backend.

Select a Velero version that matches the Kubernetes version (compatibility table provided in the source).

Disabling volume snapshots ( --use-volume-snapshots=false) forces Velero to back up volumes as files.

The node‑agent is required for PVC data backup.

Backup and restore commands can target the whole cluster, specific namespaces, or individual resources.

Velero overview diagram
Velero overview diagram
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Cloud NativeOperationsKubernetesDisaster RecoveryMinIOBackupVelero
DevOps Operations Practice
Written by

DevOps Operations Practice

We share professional insights on cloud-native, DevOps & operations, Kubernetes, observability & monitoring, and Linux systems.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.