Backup and Restore in a Kubernetes Cluster with Velero
This section walks you through setting up and using Velero for backup and restore operations in a Kubernetes cluster, with MinIO as the S3-compatible object storage backend.
Prerequisites
Before you begin, ensure your environment meets the following requirements:
A running Kubernetes cluster where workloads are deployed.
Installed and configured, used to deploy the MinIO chart.
Command-line access to interact with the cluster.
Required to pull Helm charts and container images.
Every pod whose volumes you want backed up must include the following annotation in
spec.template.metadata.annotations:annotations: backup.velero.io/backup-volumes: "*"
Install MinIO (Object Storage)
MinIO is a high-performance, S3-compatible object storage system that serves as the backend where Velero stores all backup data. Installing MinIO within your cluster gives you a self-hosted, lightweight storage target.
Add Helm repo and update
In this step, you configure your local Helm client to trust and pull charts from the official MinIO Helm chart repository. Run the following command to add the MinIO Helm repository and refresh chart indices.
helm repo add minio https://charts.min.io/ helm repo update
helm repo add registers the MinIO chart repository URL with your local Helm configuration, and helm repo update refreshes Helm’s local chart index so it can discover the latest available chart versions before you install or upgrade MinIO.
Create MinIO values file
The values file lets you customize the MinIO deployment in a repeatable, version-controlled way. Here, it is used to set MinIO to standalone mode, enable persistent storage for backups, specify resource requests, configure service exposure, and control optional components like the MinIO console.
Create a file named minio-values.yaml with the following configuration:
mode: standalone
persistence:
enabled: true
size: 50Gi
resources:
requests:
memory: 512Mi
cpu: 250m
rootUser: "minioadmin"
rootPassword: "minioadmin"
service:
type: ClusterIP
replicas: 1
console:
enabled: falseThe following table provides the details of each field of the above configuration file:
Field | Description | Default value |
|---|---|---|
| MinIO deployment mode. standalone runs a single instance. |
|
| Ensures data is stored on a PersistentVolume and survives pod restarts. |
|
| Requested PV capacity for object data. |
|
| Minimum guaranteed resources for stable performance. | |
| Bootstrap admin credentials for MinIO. | |
| Exposure method inside the cluster. ClusterIP limits access to in-cluster clients. |
|
| Number of MinIO pods. 1 for standalone. |
|
| Enables/disables MinIO Web Console. Disabled here for simplicity and minimal attack surface. |
|
Install MinIO
Run the following command to install MinIO in its own namespace using the values file.
helm upgrade --install minio minio/minio \ -n minio --create-namespace \ -f minio-values.yaml \ --version 5.4.0
Configure Buckets with MinIO client (mc)
This step prepares MinIO so that Velero has a known bucket to store backups and a dedicated set of credentials with the right permissions. Open a terminal inside the MinIO container, configure an mc (MinIO Client) alias to point to the MinIO service endpoint. After establishing the connection, create the required bucket, provision a user, and assign the appropriate access permissions.
kubectl exec -it deploy/minio -n minio -- bash # Inside pod: mc alias set localminio http://minio:9000 minioadmin minioadmin mc mb localminio/velero mc admin user add localminio velero-user vP@assWoRd mc admin policy attach localminio readwrite --user velero-user mc ls localminio
Configure cloud credentials for Velero
Configuring cloud credentials enables Velero to authenticate to the MinIO object storage in order to write backups and read them back during restores. Create a Kubernetes Secret named cloud-credentials.yaml containing the access key and secret key in the AWS credential format that Velero expects.
apiVersion: v1
kind: Secret
metadata:
name: cloud-credentials
namespace: velero
stringData:
cloud: |
[default]
aws_access_key_id = velero-user
aws_secret_access_key = vP@assWoRdThe following table defines each field of the above configuration:
Field | Description | Default value |
|---|---|---|
| Secret name referenced by OADP/Velero. |
|
| Must match the OADP operator namespace. |
|
| AWS-style credentials file. Values are injected into Velero for S3-compatible access to MinIO. Replace with your secure credentials. |
Run the command to apply the cloud-credentials.yaml so that Velero can use these credentials to access the MinIO S3 bucket for backups and restores.
kubectl apply -f cloud-credentials.yaml
Deploy Velero client pod
This step creates a pod that runs the Velero CLI, which you use to execute backup and restore commands. The pod mounts the cloud credentials secret so Velero can authenticate with MinIO.
Create the velero-client.yaml configuration file:
apiVersion: v1
kind: Pod
metadata:
name: velero-client
namespace: velero
spec:
containers:
- name: velero
image: velero/velero:v1.12.0
command: ["/bin/sh"]
args: ["-c", "sleep infinity"]
volumeMounts:
- name: cloud-credentials
mountPath: /credentials
readOnly: true
volumes:
- name: cloud-credentials
secret:
secretName: cloud-credentialsThe following table defines each field of the above configuration:
Field | Description | Default value |
|---|---|---|
| Namespace to access the credentials secret and Velero CRDs. |
|
| The Velero container image and version. |
|
| Runs a shell that sleeps indefinitely, keeping the pod alive so you can | |
| Path inside the container where the credentials file is mounted. |
|
| Prevents the container from modifying the credentials. |
|
| References the cloud-credentials secret created before. |
|
Run the command to apply the manifest to deploy the Velero client pod, which will mount the cloud credentials and remain running for you to execute backup and restore commands.
kubectl apply -f velero-client.yaml
Create a tuned Backup Storage Location (BSL) (optional)
The Velero configuration uses the information to know where backups are stored and how to connect to that storage. The BSL points Velero to the MinIO S3-compatible service and the velero bucket, so backups and restore artifacts are consistently written to the correct location.
Create a tuned BSL for faster uploads, backup-storage-location.yaml.
apiVersion: velero.io/v1
kind: BackupStorageLocation
metadata:
name: default
namespace: velero
spec:
provider: aws
objectStorage:
bucket: velero
prefix: backups
config:
region: minio
s3ForcePathStyle: 'true'
s3Url: 'http://minio.minio.svc.cluster.local:9000'
maxParallel: "10"
maxRetries: "5"
maxRetriesBackoff: "2s"
partSize: "104857600"
credential:
name: cloud-credentials
key: cloud
default: trueThe following table defines each field of the above configuration:
Field | Description | Default value |
|---|---|---|
| The namespace where Velero is running. |
|
| The storage provider type. |
|
| Components where backup objects are written within MinIO. | |
| The endpoint URL of the S3-compatible object store, pointing to the in-cluster MinIO service. |
|
| The maximum number of parallel upload/download operations Velero performs against this storage location. |
|
| The maximum number of times Velero retries a failed S3 operation before marking it as failed. |
|
| The wait duration between retries, using an exponential backoff strategy. |
|
| The size of each part in a multipart upload to S3. |
|
| The name of the Kubernetes Secret that contains the S3 access key and secret key. | |
| When |
|
Run the command to apply the manifest, registering MinIO as Velero's default backup storage location with the configured connection and performance settings.
kubectl apply -f backup-storage-location.yaml
Create a backup
Creating a backup is the step where you define what data and Kubernetes resources Velero should capture and how the backup should be executed and retained.
Create a backup:
velero backup create virtana-io-backup-16sep-01 \ --include-namespaces virtana-io \ --ttl 72h
Adjust parameters as required. See Velero Backup Reference for more details.
Run the command to check the backup status:
velero backup get velero backup describe virtana-io-backup-16sep-01
Restore from Backup
When you need to recover workloads, Velero can restore all resources from a previously created backup. This recreates the Kubernetes objects and restores persistent volume data.
Run the command to restore from backup:
velero restore create virtana-io-restore-16sep-01 \ --from-backup virtana-io-backup-16sep-01
Adjust parameters as required. See Velero Restore Reference for more details.
Run the command to check the restore status:
velero restore get velero restore describe virtana-io-restore-16sep-01
Validation
After a backup or restore operation, verify that it completed successfully by checking the status of both the Velero operations and the restored workloads.
Run the command to check the backup and restore status:
velero backup get -and- velero restore get
Verify workloads
As a final step, confirm that all pods, persistent volume claims, and services in the restored namespace are running as expected.
Run the following command to verify the workload:
kubectl get pods -n virtana-io kubectl get pvc -n virtana-io kubectl get svc -n virtana-io