Tech ONTAP Blogs

NetApp Backup & Recovery enters public preview support for Kubernetes workloads

PatricU
NetApp
110 Views

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:

  • Unified Protection: Manage and protect Kubernetes applications and resources from a single console.
  • Enhanced Data Protection: Leverages NetApp SnapMirror® for faster backups and restores, building on the robust Trident™ software.
  • Streamlined Operations: Efficiently moves backup data to object storage using SnapMirror technology.
  • Structured incremental backups with protection policies.
  • 3-2-1 fan-out protection policy for superior data protection.
  • Change block tracking for optimized performance.

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!

Test environment

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.

Screenshot 2025-09-19 at 11.32.27.png

Discover the Kubernetes cluster

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.

Screenshot 2025-09-19 at 13.29.15.png

Screenshot 2025-09-19 at 13.42.50 copy.png

In the next screen, select the Kubernetes workload type.

Screenshot 2025-09-19 at 13.52.18.png

Enter the cluster name to add to Backup and Recovery and choose a Backup and Recovery agent to use with the K8s cluster:

Screenshot 2025-09-19 at 13.52.33.png

Now Backup and Recovery creates command line instructions to add the K8s cluster to Backup and Recovery.

Screenshot 2025-10-08 at 18.18.18.png

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.

Screenshot 2025-09-19 at 14.11.34.png

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:

Screenshot 2025-09-19 at 14.13.24.png

Create application

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.

Screenshot 2025-09-19 at 14.23.54.png

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.

Screenshot 2025-09-19 at 14.25.20.png

Screenshot 2025-09-19 at 14.26.17.png

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.

Screenshot 2025-09-19 at 14.29.48.png

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”.

Screenshot 2025-09-19 at 14.31.08.png

Create protection policy

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.

Screenshot 2025-10-08 at 16.24.25.png

From there, we can create a new protection policy (or could add an existing one).

Screenshot 2025-10-08 at 16.24.45.png

In the first step, we select Kubernetes as the workload type and set the policy name as pu-minio-11.

Screenshot 2025-10-08 at 16.33.58.png

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.

Screenshot 2025-10-08 at 16.35.37.png

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.

Screenshot 2025-09-23 at 18.13.40.png

Next, we select the object storage location to store the Kubernetes application resources during each snapshot cycle, selecting an already configured Azure backup target.

Screenshot 2025-09-23 at 18.13.40.png

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.

Screenshot 2025-09-23 at 18.14.30.png

Protect application

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.

Screenshot 2025-09-24 at 14.26.52.png

Now we search for the newly created protection policy pu-minio-11 in the list of existing policies and select it.

Screenshot 2025-09-24 at 18.31.35.png

As we don’t want to add any pre- or postscripts, we select Done and the policy is attached to the application.

Screenshot 2025-09-24 at 18.31.39.png

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.

Screenshot 2025-09-24 at 18.31.48.png

This leads us to the Monitoring tab, where we see the details of the protection job, which succeeds after a short while.

Screenshot 2025-09-24 at 18.37.45.png

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 |
+---------------------------------------------+--------------------------+----------------+-----------+-------+-------+

On-demand backup

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.

Screenshot 2025-09-25 at 09.19.05.png

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.

Screenshot 2025-09-25 at 09.19.05 copy.png

We see multiple restore points, as meanwhile the schedule kicked in an created the first scheduled backups.

Screenshot 2025-09-25 at 09.25.03.png

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  |
+-------------------------------------+--------------------------+----------------+-----------+-------+--------+

Restore application

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.

Screenshot 2025-10-08 at 17.47.01.png

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.

PatricU_33-1754662320050.png

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.

PatricU_34-1754662341571.png

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.

PatricU_35-1754662394169.png

We choose minio-dr as destination namespace on the destination cluster and select Next.

PatricU_36-1754662418721.png

As we want to restore the complete application, we select Restore all resources and then Next.

PatricU_37-1754662436894.png

Finally, we select to restore to the default storage class on the destination cluster and start the restore by selecting Restore.

PatricU_38-1754662457885.png

We track the progress of the restore job, which finishes after some minutes.

PatricU_39-1754662508955.png

PatricU_40-1754662522966.png

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

View protection health on the Backup and Recovery Dashboard

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:

Screenshot 2025-10-09 at 15.56.57.png

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. 

Conclusion and call to action

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!

Public