Tech ONTAP Blogs
Tech ONTAP Blogs
On October 6th, NetApp published an updated preview of its new Backup and Recovery solution for Kubernetes-based containers and virtual machines, offering seamless, unified protection for applications on NetApp storage. This integration is a game-changer for those managing modern applications in their organizations.
Key Highlights:
For a complete list of features supported in the preview release, see the release notes.
Stay tuned for more features being added throughout the preview period!
In this blog post, we’ll guide you through setting up protection policies and protecting and restoring your K8s applications with NetApp Backup & Recovery.
Ready to elevate your data protection game? Let’s dive in!
For our further demonstrations, we use an RKE2 cluster patric-sks4177 with the latest version of the NetApp Trident CSI provisioner installed, and the NetApp ONTAP 9 simulator to provide backend storage.
After installing the RKE2 snapshot controller and configuring the Trident backend including the corresponding storage and volume snapshot class, we have this storage configuration on our cluster:
$ tridentctl -n trident get backends
+-----------------+----------------+--------------------------------------+--------+------------+---------+
| NAME | STORAGE DRIVER | UUID | STATE | USER-STATE | VOLUMES |
+-----------------+----------------+--------------------------------------+--------+------------+---------+
| ontap-nas-vsim1 | ontap-nas | 1654b6a5-b588-4d53-859d-20303c6d2f60 | online | normal | 0 |
+-----------------+----------------+--------------------------------------+--------+------------+---------+
$ kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
ontap-vsim1-nas (default) csi.trident.netapp.io Delete Immediate false 18s
$ kubectl get volumesnapshotclass
NAME DRIVER DELETIONPOLICY AGE
trident-snapshotclass csi.trident.netapp.io Delete 57s
For the backup and restore tests, we installed a simple Minio® application:
$ kubectl get all,pvc -n minio
NAME READY STATUS RESTARTS AGE
pod/minio-b6b84f46c-sr2qm 1/1 Running 0 114s
pod/minio-console-cb99559c-zgq76 1/1 Running 0 114s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/minio ClusterIP 10.98.237.51 <none> 9000/TCP 115s
service/minio-console ClusterIP 10.104.0.87 <none> 9090/TCP 115s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/minio 1/1 1 1 115s
deployment.apps/minio-console 1/1 1 1 115s
NAME DESIRED CURRENT READY AGE
replicaset.apps/minio-b6b84f46c 1 1 1 115s
replicaset.apps/minio-console-cb99559c 1 1 1 115s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
persistentvolumeclaim/minio Bound pvc-b0fed8f1-c5ed-4000-b938-ba29393864f0 8Gi RWO ontap-vsim1-nas <unset> 116s
Our Backup and Recovery account and environment are prepared already as per the Backup and Recovery requirements: My user has the required SuperAdmin permissions and a Backup and Recovery agent is already installed and configured in our on-premises test environment, and the working environment was created and associated with an Azure Storage account.
The typical workflow to protect your K8s applications obviously starts by adding your K8s cluster to Backup and Recovery, enabling you to then add applications to the cluster and protect the resources hosted by the cluster.
If you are discovering Kubernetes workloads for the first time, in Backup and Recovery, select Discover and Manage under the Kubernetes workload type. If you have already discovered Kubernetes workloads, in Backup and Recovery, select Inventory > Workloads and then select Discover resources.
In the next screen, select the Kubernetes workload type.
Enter the cluster name to add to Backup and Recovery and choose a Backup and Recovery agent to use with the K8s cluster:
Now Backup and Recovery creates command line instructions to add the K8s cluster to Backup and Recovery.
Follow the command line instructions on your K8s cluster:
$ kubectl create namespace trident-protect
namespace/trident-protect created
$ kubectl create secret generic occmauthcreds --namespace=trident-protect --from-literal=client_id=aSXCqUIWxYoGVR6hhXHBPNoP8uwDUj7G --from-literal=client_secret=SCDfvf8BoN-eG0dJ_SDnGtz-wIL3PJSbrbMQle91IWqObbln1pnZ1yR3y6Z_pZUB
secret/occmauthcreds created
$ helm repo add --force-update netapp-trident-protect https://netapp.github.io/trident-protect-helm-chart
"netapp-trident-protect" has been added to your repositories
$ helm install trident-protect netapp-trident-protect/trident-protect-bxp-preview --version 100.2510.0-bxp-preview --namespace trident-protect --set clusterName=patric-sks4177 --set trident-protect.cbs.accountID=7f2955ab-d109-4597-8d32-3363cf95ca9e --set trident-protect.cbs.agentID=Bk99JO3PiLIJODBCQWXbiHv4f0v4DSsWclients --set trident-protect.cbs.proxySecretName=occmauthcreds --set trident-protect.cbs.proxyHostIP=http://10.192.8.118
NAME: trident-protect
LAST DEPLOYED: Fri Sep 19 13:53:51 2025
NAMESPACE: trident-protect
STATUS: deployed
REVISION: 1
TEST SUITE: None
These steps install Trident protect and the Trident protect connector on the K8s cluster in the trident-protect namespace, ensuring that Backup and Recovery can interact with the K8s cluster.
$ kubectl get all -n trident-protect
NAME READY STATUS RESTARTS AGE
pod/trident-protect-connector-78d6798b5c-j4nr4 1/1 Running 0 12m
pod/trident-protect-controller-manager-57c59d8857-ff94s 2/2 Running 0 12m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/tp-webhook-service ClusterIP 10.111.7.135 <none> 443/TCP 12m
service/trident-protect-controller-manager-metrics-service ClusterIP 10.103.21.64 <none> 8443/TCP 12m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/trident-protect-connector 1/1 1 1 12m
deployment.apps/trident-protect-controller-manager 1/1 1 1 12m
NAME DESIRED CURRENT READY AGE
replicaset.apps/trident-protect-connector-78d6798b5c 1 1 1 12m
replicaset.apps/trident-protect-controller-manager-57c59d8857 1 1 1 12m
After you completing the steps, select Discover. The cluster is added to the inventory.
Select View in the associated Kubernetes workload to see the list of applications, clusters, and namespaces for that workload. We see our newly added cluster patric-sks4177 as Connected in the list of managed clusters:
With our test cluster patric-sks4177 added to Backup and Recovery, we can now add our sample Minio application to Backup and Recovery, making Backup and Recovery aware of the running application on the Kubernetes cluster. In Backup and Recovery, select Inventory, then select the Applications tab and click on Create application.
Now add your name for the application, select the K8s cluster it’s running on, and the namespaces that contain the app’s resources. Optionally you can also include resources based on label and GroupVersionKind (GVK) filters and add cluster scoped resources to the Backup and Recovery application definition. In our case, we simply add the minio namespace to the application definition.
In the next window, we could add pre- and postscripts (execution hooks the run before and after snapshots/backups) and assign a protection policy to the application. As we don’t need pre- and postscripts and want to create a protection policy separately, we skip both steps and directly create the application.
The minio application is created and appears in the list of applications in the Applications tab of the Kubernetes inventory with the protection status “Unprotected” and application status “Ready”.
Next, let’s create a new protection policy. We start from the list of applications in the Backup & recovery Inventory, find our still unprotected minio application in the list of applications and select Protect from the associated Actions menu.
From there, we can create a new protection policy (or could add an existing one).
In the first step, we select Kubernetes as the workload type and set the policy name as pu-minio-11.
Then we select the backup architecture. As we want to protect our application also against, for example, the failure of the K8s cluster, the underlying ONTAP storage, or the whole data center, we select “Disk to object storage” as data flow model, which protects the application data by local snapshots and copies of the data in an offsite object storage. The 3-2-1 fan-out protection policy would offer an even higher level of protection and will be covered in a separate blog.
Now we define the protection schedules, sticking with the default schedules of hourly snapshots and one daily snapshot, keeping the last three snapshots of each cycle.
Next, we select the object storage location to store the Kubernetes application resources during each snapshot cycle, selecting an already configured Azure backup target.
Then we select the object storage location to store the actual application backup data, in our case we use the same target as for the application resources. We can also adjust the schedule for the backup schedules if needed and click Create to create the protection schedule.
To protect our sample application, we go back to the list of applications in the Backup & recovery Inventory, select our minio application and select Protect from the associated Actions menu.
Now we search for the newly created protection policy pu-minio-11 in the list of existing policies and select it.
As we don’t want to add any pre- or postscripts, we select Done and the policy is attached to the application.
Backup and Recovery now immediately starts a baseline backup, a full backup of the application. Any future incremental backups are created based on the schedule that you define in the protection policy associated with the application. We can track the progress of the backup by selecting Track progress.
This leads us to the Monitoring tab, where we see the details of the protection job, which succeeds after a short while.
Checking on the K8s cluster with the Trident protect CLI, we see the baseline backup and snapshot.
$ tridentctl-protect get backup -n minio
+-------------------------------------+--------------------------+----------------+---------+-------+-------+
| NAME | APP | RECLAIM POLICY | STATE | ERROR | AGE |
+-------------------------------------+--------------------------+----------------+---------+-------+-------+
| baseline-transfer-backup-gghvyc3qmo | patricu-minio-9vvnkvosql | Retain | Running | | 3m31s |
+-------------------------------------+--------------------------+----------------+---------+-------+-------+
~$ tridentctl-protect get snapshot -n minio
+---------------------------------------------+--------------------------+----------------+-----------+-------+-------+
| NAME | APP | RECLAIM POLICY | STATE | ERROR | AGE |
+---------------------------------------------+--------------------------+----------------+-----------+-------+-------+
| backup-df8460c6-07f2-4016-9e1c-33afc259c7d5 | patricu-minio-9vvnkvosql | Delete | Completed | | 3m52s |
+---------------------------------------------+--------------------------+----------------+-----------+-------+-------+
If needed, we can also manually create a backup of the sample application if needed, for example to make sure the most recent data is protected. Again, from the list of application in the Inventory, select the minio application and select Backup now from the Actions menu.
From View and restore in the Actions menu of our application, we can check the details of the application protection, and the list of available restore points and their locations.
We see multiple restore points, as meanwhile the schedule kicked in an created the first scheduled backups.
This can also be seen with the CLI, showing the available backups and snapshots.
$ tridentctl-protect get snapshot -n minio
+---------------------------------------------+--------------------------+----------------+-----------+-------+--------+
| NAME | APP | RECLAIM POLICY | STATE | ERROR | AGE |
+---------------------------------------------+--------------------------+----------------+-----------+-------+--------+
| backup-df8460c6-07f2-4016-9e1c-33afc259c7d5 | patricu-minio-9vvnkvosql | Delete | Completed | | 14h42m |
| custom-8525a-20250925050048 | patricu-minio-9vvnkvosql | Delete | Completed | | 2h13m |
| custom-8525a-20250925060048 | patricu-minio-9vvnkvosql | Delete | Completed | | 1h13m |
| custom-8525a-20250925070048 | patricu-minio-9vvnkvosql | Delete | Completed | | 13m12s |
| custom-e5bfd-20250925000048 | patricu-minio-9vvnkvosql | Delete | Completed | | 7h13m |
+---------------------------------------------+--------------------------+----------------+-----------+-------+--------+
~$ tridentctl-protect get backup -n minio
+-------------------------------------+--------------------------+----------------+-----------+-------+--------+
| NAME | APP | RECLAIM POLICY | STATE | ERROR | AGE |
+-------------------------------------+--------------------------+----------------+-----------+-------+--------+
| baseline-transfer-backup-gghvyc3qmo | patricu-minio-9vvnkvosql | Retain | Completed | | 14h42m |
| custom-8525a-20250925030048 | patricu-minio-9vvnkvosql | Retain | Completed | | 4h13m |
| custom-8525a-20250925040048 | patricu-minio-9vvnkvosql | Retain | Completed | | 3h13m |
| custom-8525a-20250925050048 | patricu-minio-9vvnkvosql | Retain | Completed | | 2h13m |
| custom-8525a-20250925060048 | patricu-minio-9vvnkvosql | Retain | Completed | | 1h13m |
| custom-8525a-20250925070048 | patricu-minio-9vvnkvosql | Retain | Completed | | 13m16s |
| custom-e5bfd-20250925000048 | patricu-minio-9vvnkvosql | Retain | Completed | | 7h13m |
+-------------------------------------+--------------------------+----------------+-----------+-------+--------+
Now we’re all set to test a restore of the minio sample application. Out of the many possible restore (and failure) scenarios, let’s see in more detail how we can recover our application to another cluster in case of a failure of the original cluster hosting the application.
For a realistic test scenario, let’s first simulate a cluster failure by stopping the Trident protect connector on the cluster. We scale down the trident-protect-connector deployment to zero and wait for the associated pod to stop.
$ kubectl -n trident-protect scale deployment.apps/trident-protect-connector --replicas=0
deployment.apps/trident-protect-connector scaled
This leads to Backup and Recovery losing the communication to the K8s cluster. After some minutes, our cluster goes into the "Failed" state in Backup and Recovery.
Luckily our application is protected already, and we can easily initiate a restore to another cluster. We select again View and restore from the Actions menu of the minio application in the list of applications.
From the list of available restore points, we select the restore point from which we want to restore form and select Restore from its associated Actions menu.
As the local snapshots are not available anymore due to the cluster failure, we select to restore from object store and choose the destination cluster from the list of managed clusters.
We choose minio-dr as destination namespace on the destination cluster and select Next.
As we want to restore the complete application, we select Restore all resources and then Next.
Finally, we select to restore to the default storage class on the destination cluster and start the restore by selecting Restore.
We track the progress of the restore job, which finishes after some minutes.
Finally, we confirm that the minio application is up and running on the destination cluster in the minio-dr namespace.
$ kubectl get all,pvc -n minio-dr --context sks3794-admin@sks3794
NAME READY STATUS RESTARTS AGE
pod/minio-b6b84f46c-v7cxw 1/1 Running 0 4h42m
pod/minio-console-cb99559c-td8f4 1/1 Running 0 4h42m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/minio ClusterIP 10.103.102.117 <none> 9000/TCP 4h42m
service/minio-console ClusterIP 10.108.79.13 <none> 9090/TCP 4h42m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/minio 1/1 1 1 4h42m
deployment.apps/minio-console 1/1 1 1 4h42m
NAME DESIRED CURRENT READY AGE
replicaset.apps/minio-b6b84f46c 1 1 0 4h42m
replicaset.apps/minio-console-cb99559c 1 1 1 4h42m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
persistentvolumeclaim/minio Bound pvc-d2bbdd4f-9fe1-4fa3-a89d-8c65264b400e 8Gi RWO ontap-vsim4-nas <unset> 4h42m
We can view the status of the backups and restores on the NetApp Backup and Recovery Dashboard to get a quick overview. From the Backup and Recovery menu, select Dashboard, and select Kubernetes workload from the drop-down menu:
The Dashboard gives you a quick overview of the number of protected systems, clusters, applications, as well as the number of backup and metadata buckets, configured protection policies, and the total protected capacity.
In the job summary, you can review the completed, running or failed backup and restore jobs in the selected time period of the last 24 hours, 7, or 30 days.
In the data protection status, you can view your applications based on their protection status and protection health, and target repositories shows you the storage capacity used in the local, secondary, and object store repositories.
NetApp has introduced a preview of its Backup and Recovery solution for Kubernetes workloads, enhancing the protection of Kubernetes-based containers. This new solution offers a unified management console, leveraging SnapMirror for efficient backups and restores, and integrates seamlessly with Trident software for streamlined operations. Key features include centralized management, structured incremental backups, and the ability to restore applications across different clusters and namespaces.
This blog post provides a detailed guide on setting up protection policies, protecting, and restoring Kubernetes applications using Backup and Recovery. It includes step-by-step instructions for configuring the test environment, discovering Kubernetes clusters, creating applications, and implementing protection policies. Additionally, it covers manual and on-demand backups, as well as restoring applications to different clusters in case of failures.
Ready to elevate your data protection strategy? Dive into the comprehensive guide and start leveraging Backup and Recovery for your Kubernetes workloads today! Ensure your applications are protected against any failures with seamless, efficient, and unified backup solutions. Get started now and experience the future of data protection with Backup and Recovery!
Log in to the NetApp Console today to get started!