How to Back Up K3s with Velero, Kopia, and S3-Compatible Storage

Updated on Sep 8, 2026
Kimberly N
7 MINS READ
Table of Contents
Back Up K3s with Velero and Kopia

Losing a Kubernetes cluster with no backup is one of the worst things that can happen to a self-hosted setup. This guide shows you how to back up K3s with Velero, using the built-in Kopia file-system backup and your own S3-compatible storage. So your namespaces and persistent volumes are safe even if a whole server goes down.

What Are Velero and Kopia

Velero is a free and open-source tool that backs up Kubernetes objects and the data inside your persistent volumes. Kopia is the backup engine Velero uses to read files from your volumes, compress them, and upload them to storage.

Together, they let you back up K3s with Velero without needing expensive commercial backup software.

What You Need for This Setup

  • A working K3s cluster, single-node or multi-node, with kubectl access.
  • An S3-compatible bucket. This can be AWS S3, MinIO, Backblaze B2, or another provider that supports the S3 API.
  • Access key ID and secret access key for that bucket.

Step 1: Create Your S3-Compatible Bucket and Access Keys

Before installing anything, you must prepare the storage side. Log in to your S3-compatible provider and create a new bucket just for Velero backups, for example, k3s-velero-backups.

Generate an access key ID and secret access key for this bucket. Keep these two values ready; you will use them in the next step.

If you are using MinIO on your own server, you can create the bucket from the command line with the MinIO client:

Bash
mc alias set myminio https://minio.example.com ACCESS_KEY SECRET_KEYmc mb myminio/k3s-velero-backups

If you already back up Docker volumes to S3 or MinIO, you can use the same setup here; just create a separate bucket for Kubernetes. Check our guide to backing up Docker volumes to S3 or MinIO.

Step 2: Install the Velero CLI

Download the current stable Velero CLI release and install it on your management machine. This can be your K3s master node or your laptop, as long as it has kubectl access to the cluster:

Bash
curl -LO https://github.com/vmware-tanzu/velero/releases/download/v1.18.2/velero-v1.18.2-linux-amd64.tar.gztar -xvf velero-v1.18.2-linux-amd64.tar.gzsudo mv velero-v1.18.2-linux-amd64/velero /usr/local/bin/

Check that it is installed correctly with the following command:

Bash
velero version --client-only

Step 3: Create the Credentials File for Your Bucket

Velero needs your S3 access keys in a simple text file. Create this file with your real values:

Bash
cat <<EOF > credentials-velero[default]aws_access_key_id=your-access-key-idaws_secret_access_key=your-secret-access-keyEOF

This file is sensitive, since anyone with it can read or delete your backups. Give it the proper permissions:

Bash
chmod 600 credentials-velero
Never put this file in Git or share it in chat. Velero copies it into a Kubernetes Secret during install, so you only need the plain file for that one step. After install, delete the local file or move it to a password manager. The Secret inside the cluster is all Velero needs going forward.

Step 4: Back Up K3s with Velero Using the Install Command

Now install Velero into your cluster. This single command sets up the Velero server, connects it to your S3 bucket, and installs the Node Agent for Kopia file-system backups. Replace the bucket name, region, and S3 URL with your own values. For AWS S3, you can drop the s3Url part:

Bash
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml velero install \  --provider aws \  --plugins velero/velero-plugin-for-aws:v1.14.1 \  --bucket k3s-velero-backups \  --backup-location-config region=us-east-1,s3ForcePathStyle="true",s3Url=https://minio.example.com \  --secret-file ./credentials-velero \  --use-node-agent \  --uploader-type kopia \  --default-volumes-to-fs-backup
  • --plugins velero/velero-plugin-for-aws:v1.14.1 adds the plugin that lets Velero talk to S3-compatible storage.
  • --use-node-agent installs the Node Agent DaemonSet, which is required for file-system backups.
  • --uploader-type kopia tells Velero to use Kopia instead of the older Restic tool.
  • --default-volumes-to-fs-backup tells Velero to back up every volume's files by default, so you do not need to add annotations to every pod.

This is the core command to back up K3s with Velero on any self-hosted cluster, and it works the same whether your nodes are bare metal or virtual machines.

Step 5: Verify Velero and the Node Agent Are Running

Check that everything started correctly in the velero namespace:

Bash
kubectl get pods -n velero

You should see one velero deployment pod and one node-agent pod per cluster node, all showing Running. Also, check that Velero can see your backup location:

Bash
velero backup-location get

The AVAILABLE column should say Available. If it says Unavailable, double-check your bucket name, region, and S3 URL.

Step 6: Create First Backup with Kopia File-System Backup

With Velero installed, you can manually back up a namespace to confirm everything works correctly. Replace my-app with a real namespace in your cluster:

Bash
velero backup create my-app-backup-01 \  --include-namespaces my-app \  --wait

Because we installed Velero with --default-volumes-to-fs-backup, this backup automatically uses Kopia to copy the actual files inside your persistent volumes. Check the backup status:

Bash
velero backup describe my-app-backup-01 --details

Look for Phase: Completed. If you see PartiallyFailed or Failed, run velero backup logs my-app-backup-01 to see the exact error.

Step 7: Schedule Automatic Backups with Retention

Manual backups are good for testing, but production clusters need a schedule. Create a daily schedule that keeps each backup for 7 days:

Bash
velero schedule create daily-backup \  --schedule="0 2 * * *" \  --include-namespaces my-app \  --ttl 168h0m0s

--ttl 168h0m0s keeps each backup for 168 hours (7 days), then Velero deletes it automatically, including the copy in your S3 bucket.

Check your schedules anytime with:

Bash
velero schedule get

For longer retention, create a second schedule for weekly or monthly backups with a longer --ttl value, such as 720h0m0s for 30 days. Running more than one schedule with different retention periods is a normal way to back up K3s with Velero for both short-term and long-term recovery needs.

Step 8: Restore a Backup into a Clean Namespace

The real test of any backup is a restore. Create an empty namespace and restore your backup into it, instead of overwriting the original namespace. This is the safest way to prove your backups work without risking your live data.

Bash
velero restore create my-app-restore-01 \  --from-backup my-app-backup-01 \  --namespace-mappings my-app:my-app-restore \  --wait

--namespace-mappings my-app:my-app-restore tells Velero to recreate everything from the my-app namespace inside a new namespace called my-app-restore. It leaves your original namespace untouched.

Step 9: Verify the Restore Worked

Check that the new namespace has your pods, services, and data back:

Bash
kubectl get all -n my-app-restorekubectl get pvc -n my-app-restore

Check the restore's own status and logs:

Bash
velero restore describe my-app-restore-01 --detailsvelero restore logs my-app-restore-01

If your app saves files to disk, go into the pod and check the files. This proves the Kopia backup restored real data, not just empty volumes:

Bash
kubectl exec -n my-app-restore <pod-name> -- ls /data

Once you are done with the test, delete the test namespace to free up resources:

Bash
kubectl delete namespace my-app-restore

Best Practices for Production Backups

Following a setup guide gets your backups running, but keeping them reliable long-term takes a bit more care. Here are best practices that help your backups stay safe and actually work when you need them:

  • Keep your backup bucket on separate hardware or a separate provider from your K3s cluster, so one failure cannot take out both.
  • Run more than one schedule so you have both short-term and long-term recovery points.
  • Test a full restore every few months, not just once during setup. An untested backup is not a real backup.
  • Store the credentials file and any exported secrets in an encrypted password manager, never in plain Git repositories.
  • Watch velero backup get regularly, or connect it to your monitoring, so a failed backup doesn't go unnoticed for weeks.

Conclusion

At this point, you have learned to back up K3s with Velero using Kopia file-system backup and your own S3-compatible storage. This setup protects your data from node failures, bad deployments, and accidental deletes, without locking you into one cloud provider's snapshot system.

For real resilience, keep your K3s cluster and your backup storage on separate machines. PerLod dedicated server hosting works well for both, giving your Velero backups a safe, isolated location outside the cluster. So you can still recover if your main cluster ever goes down.

We hope you enjoy this guide. For more detailed information, you can check the Official Velero Documentation.

No. Kopia file-system backup reads files directly from the pod's volume, so it works even without snapshot support in your storage driver.

Yes. Kopia is faster, uses less memory, and is the default and recommended uploader, while Restic is being phased out.

Yes. Install Velero on the new cluster pointing at the same S3 bucket, then run velero restore create from there.