Tech ONTAP Blogs
Tech ONTAP Blogs
NetApp Backup and Recovery for Kubernetes is now generally available, building on last year’s preview and delivering enterprise-grade data protection for both containerized applications and virtual machines on Kubernetes, including Red Hat OpenShift and OpenShift Virtualization.
One notable feature that was added during the preview phase of NetApp Backup and Recovery for Kubernetes is the support onboard existing Trident protect clusters into NetApp Backup and Recovery. During onboarding, the service discovers existing application definitions and recovery points created with Restic- or Kopia-based workflows. After discovery, you re-protect applications by assigning a protection policy going forward. Existing recovery points remain available for restore using Kubernetes CR based workflows or through the NetApp Console.
In this blog post, I’ll walk you through a sample scenario adding a Kubernetes cluster with applications already protected by Trident protect to NetApp Backup and Recovery. Let's dive in and take your Kubernetes backups to a next level!
The K8s cluster sks5037 we want to Backup and Recovery has NetApp Trident and Trident protect version 25.10 already installed:
$ helm list -n trident-protect
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
trident-protect trident-protect 1 2026-01-26 18:25:32.891389 +0100 CET deployed trident-protect-100.2510.0 25.10.0
Persistent storage is provisioned by Trident’s CSI provisioner via the storage class ontap-vsim-nas, backed by ONTAP storage:
$ k get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
ontap-vsim2-nas (default) csi.trident.netapp.io Delete Immediate false 19h
$ tridentctl get backends
+-----------------+----------------+--------------------------------------+--------+------------+---------+
| NAME | STORAGE DRIVER | UUID | STATE | USER-STATE | VOLUMES |
+-----------------+----------------+--------------------------------------+--------+------------+---------+
| ontap-nas-vsim2 | ontap-nas | ed3ae3e5-8ee1-49fb-a21a-d5a53b17f73d | online | normal | 4 |
+-----------------+----------------+--------------------------------------+--------+------------+---------+
For storing the application data and metadata backups with Trident protect, we have two Azure Storage containers container1 and container2 available in the Azure Storage account pubrtest:
The Azure Storage containers are represented by two corresponding AppVault objects container1 and container2 in Trident protect:
$ tridentctl-protect get appvault
+------------+----------+-----------+-------+---------+-----+
| NAME | PROVIDER | STATE | ERROR | MESSAGE | AGE |
+------------+----------+-----------+-------+---------+-----+
| container1 | Azure | Available | | | 22s |
| container2 | Azure | Available | | | 8s |
+------------+----------+-----------+-------+---------+-----+
As data-rich sample applications, we installed two simple NGINX deployments with one persistent volume in the namespaces web1 and web2, respectively. Each application is represented by a corresponding application custom resource (CR) in Trident protect:
$ kubectl get all, pvv -n web1
NAME READY STATUS RESTARTS AGE
pod/web-7994c6f99b-6m825 1/1 Running 0 5d2h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/web 1/1 1 1 5d2h
NAME DESIRED CURRENT READY AGE
replicaset.apps/web-7994c6f99b 1 1 1 5d2h
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
persistentvolumeclaim/nginxdata Bound pvc-1c78b34a-ac70-4037-be41-426bb44fb6b9 2Gi RWO ontap-vsim2-nas <unset> 5d2h
$ kubectl get all, pvv -n web2
NAME READY STATUS RESTARTS AGE
pod/web-7994c6f99b-j4n8t 1/1 Running 0 5d2h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/web 1/1 1 1 5d2h
NAME DESIRED CURRENT READY AGE
replicaset.apps/web-7994c6f99b 1 1 1 5d2h
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
persistentvolumeclaim/nginxdata Bound pvc-ed7ca8be-f9f2-4828-b93b-4f9bae50c133 2Gi RWO ontap-vsim2-nas <unset> 5d2h
$ tridentctl-protect get app -A
+-----------+------+------------+-------+-----+
| NAMESPACE | NAME | NAMESPACES | STATE | AGE |
+-----------+------+------------+-------+-----+
| web1 | web1 | web1 | Ready | 4s |
| web2 | web2 | web2 | Ready | 13s |
+-----------+------+------------+-------+-----+
To regularly protect these applications, we assigned a Trident protect protection schedule for running daily backups and snapshots to each application.
$ tridentctl-protect get schedule -A
+-----------+------------+------+----------------------+---------+-------+-------+-----+
| NAMESPACE | NAME | APP | SCHEDULE | ENABLED | STATE | ERROR | AGE |
+-----------+------------+------+----------------------+---------+-------+-------+-----+
| web1 | web1-sched | web1 | Daily:hour=17,min=55 | true | | | 8s |
| web2 | web2-sched | web2 | Daily:hour=17,min=50 | true | | | 34s |
+-----------+------------+------+----------------------+---------+-------+-------+-----+
$ k -n web1 get schedule web1-sched -o yaml | yq '.spec'
appVaultRef: container1
applicationRef: web1
backupReclaimPolicy: Retain
backupRetention: "3"
dataMover: Kopia
dayOfMonth: ""
dayOfWeek: ""
enabled: false
granularity: Daily
hour: "17"
minute: "55"
recurrenceRule: ""
replicateSnapshotReclaimPolicy: Retain
replicationRetention: "0"
runImmediately: false
snapshotReclaimPolicy: Delete
snapshotRetention: "3"
$ k -n web2 get schedule web2-sched -o yaml | yq '.spec'
appVaultRef: container2
applicationRef: web2
backupReclaimPolicy: Retain
backupRetention: "3"
dataMover: Kopia
dayOfMonth: ""
dayOfWeek: ""
enabled: false
granularity: Daily
hour: "17"
minute: "50"
recurrenceRule: ""
replicateSnapshotReclaimPolicy: Retain
replicationRetention: "0"
runImmediately: false
snapshotReclaimPolicy: Delete
snapshotRetention: "3"
Backups of application web1 are stored in container1, and those of application web2 are stored in container2.
Now let’s add the cluster to NetApp Backup and Recovery to benefit from an intuitive graphical user interface and advanced data protection capabilities like 3-2-1 backups.
In the NetApp Console, we navigate to the Clusters tab of the Backup and Recovery for Kubernetes Inventory and click the Discover button.
After selecting Kubernetes as workload type from the dropdown list, entering the name of the cluster we’re going to discover (sks5037) and selecting the Console Agent connecting your environment with NetApp Console (if you haven’t installed a Console Agent yet, follow the steps in the documentation to deploy one), the Consoles generate a set of commands we need to execute on the cluster, which will update Trident protect to the latest version and connect the cluster to Backup and Recovery.
As Trident protect is already installed, we don’t need to create the trident-protect namespace and run the remaining commands:
$ kubectl create secret generic occmauthcreds \
--namespace=trident-protect \
--from-literal=client_id=2dngDUL4CqJbWzan3CobI90tfUd6eV5l \
--from-literal=client_secret=l_yVj6y-9mni3MiBCSGWuiNnjkyOUPvd10Pd2HAIDHNachE2enldhnoeYnI93_uP
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 upgrade --install trident-protect \
netapp-trident-protect/trident-protect-bxp-preview \
--version 100.2511.0-bxp-preview \
--namespace trident-protect \
--set clusterName=sks5037 \
--set trident-protect.cbs.accountID=7f2955ab-d109-4597-8d32-3363cf95ca9e \
--set trident-protect.cbs.agentID=Glt9qs4Rjdi5G2JomvRnCOIRHfjlRYoeclients \
--set trident-protect.cbs.proxySecretName=occmauthcreds \
--set trident-protect.cbs.proxyHostIP=http://10.192.18.66
After clicking Discover in the Console, the cluster is discovered and shows up as Connected in the Inventory’s list of clusters. Our two sample applications that we configured already in Trident protect are also listed.
With the Trident protect CLI, we check that the backups and snapshots that were created by the protection schedule are still available for bath applications:
$ tridentctl-protect get backups -n web1
+----------------------------+------+----------------+-----------+-------+--------+
| NAME | APP | RECLAIM POLICY | STATE | ERROR | AGE |
+----------------------------+------+----------------+-----------+-------+--------+
| daily-a8826-20260126175500 | web1 | Retain | Completed | | 1d23h |
| daily-a8826-20260127175500 | web1 | Retain | Completed | | 23h43m |
+----------------------------+------+----------------+-----------+-------+--------+
$ tridentctl-protect get snapshots -n web1
+----------------------------+------+----------------+-----------+-------+--------+
| NAME | APP | RECLAIM POLICY | STATE | ERROR | AGE |
+----------------------------+------+----------------+-----------+-------+--------+
| daily-a8826-20260126175500 | web1 | Delete | Completed | | 1d23h |
| daily-a8826-20260127175500 | web1 | Delete | Completed | | 23h44m |
+----------------------------+------+----------------+-----------+-------+--------+
$ tridentctl-protect get backups -n web2
+----------------------------+------+----------------+-----------+-------+--------+
| NAME | APP | RECLAIM POLICY | STATE | ERROR | AGE |
+----------------------------+------+----------------+-----------+-------+--------+
| daily-bddef-20260126175000 | web2 | Retain | Completed | | 1d23h |
| daily-bddef-20260127175000 | web2 | Retain | Completed | | 23h49m |
+----------------------------+------+----------------+-----------+-------+--------+
$ tridentctl-protect get snapshots -n web2
+----------------------------+------+----------------+-----------+-------+--------+
| NAME | APP | RECLAIM POLICY | STATE | ERROR | AGE |
+----------------------------+------+----------------+-----------+-------+--------+
| daily-bddef-20260126175000 | web2 | Delete | Completed | | 1d23h |
| daily-bddef-20260127175000 | web2 | Delete | Completed | | 23h49m |
+----------------------------+------+----------------+-----------+-------+--------+
Note that NetApp Backup and Recovery disabled the existing protection schedules when the cluster was added to the Console, as going forward, we’ll protect the applications with Backup and Recovery’s advanced protection policies.
$ tridentctl-protect get schedules -A
+-----------+------------+------+----------------------+---------+-------+-------+-----+
| NAMESPACE | NAME | APP | SCHEDULE | ENABLED | STATE | ERROR | AGE |
+-----------+------------+------+----------------------+---------+-------+-------+-----+
| web1 | web1-sched | web1 | Daily:hour=17,min=55 | false | | | 2d |
| web2 | web2-sched | web2 | Daily:hour=17,min=50 | false | | | 2d |
+-----------+------------+------+----------------------+---------+-------+-------+-----+
You might have noted already that the applications on cluster sks5037 don’t have a protection status in the Backup and Recovery Inventory.
But don’t worry, all the snapshots and backups that were taken before adding the cluster to Backup and Recovery are still available and can be accessed both from the CLI and now also from the Console for restores.
Select one of our applications in the Applications tab of the Inventory, select the associated Actions menu and select View and restore, and you’ll see the available restore points (snapshots and backups):
You can now select the restore point from which you want to restore your application from and restore in the usual way, while the snapshots and backups are also still available for restores with the Trident protect CLI:
$ tridentctl-protect get backups -n web1
+----------------------------+------+----------------+-----------+-------+--------+
| NAME | APP | RECLAIM POLICY | STATE | ERROR | AGE |
+----------------------------+------+----------------+-----------+-------+--------+
| daily-a8826-20260126175500 | web1 | Retain | Completed | | 1d23h |
| daily-a8826-20260127175500 | web1 | Retain | Completed | | 23h43m |
+----------------------------+------+----------------+-----------+-------+--------+
$ tridentctl-protect get snapshots -n web1
+----------------------------+------+----------------+-----------+-------+--------+
| NAME | APP | RECLAIM POLICY | STATE | ERROR | AGE |
+----------------------------+------+----------------+-----------+-------+--------+
| daily-a8826-20260126175500 | web1 | Delete | Completed | | 1d23h |
| daily-a8826-20260127175500 | web1 | Delete | Completed | | 23h44m |
+----------------------------+------+----------------+-----------+-------+--------+
So restores using the Trident protect CLI- or CR-based workflows are also still possible.
Now let’s protect the applications on the cluster we just imported to Backup and Recovery with its advanced protection policies.
If we want to use our existing Azure Storage account as backup target with Backup and Recovery, too, we need to add it as an offsite backup target first. To add the Microsoft Azure credentials to the NetApp Console Agent, we click Discover backup target in the Managed offsite backup targets tab of the Inventory and follow the steps in the UI.
Now we can add the Azure Storage account from the Inventory. After specifying the account name and region, Backup and Recovery will create a BLOB container with the same name as the Azure Storage account:
Before we can use advanced protection policies like replication to object storage, we need to add our ONTAP system to the NetApp Console, if this wasn’t done already.
In the Console, go to Management -> Storage, select the right Console Agent, and select +Add
After selecting the correct system type and clicking Discover, we can enter the ONTAP system details. After selecting Discover again, our ONTAP system is added to the available storage systems.
Now we’re all set to apply one of Backup and Recovery’s advanced protection policies to our applications. Let’s use the web2 application to walk you through the steps. In the Applications tab of the Inventory, select the web2 associated Actions menu and select Protect. In the next screen’s Policy section, we select Create new policy, select Kubernetes as workload type and name the policy pu-web2-321.
We want to protect web2 with a 3-2-1 fan-out protection policy, so we select this as data flow for the protection policy.
In the next set of screens, we enter the schedule settings and select the Azure storage container as backup target, as outlined in the documentation.
After clicking Create, the policy pu-web2-321 will be created and we can start the application protection by selecting Done in the next screen. Backup and Recovery will immediately start protecting the application with a baseline backup, which will finish in a couple of minutes.
At the CLI level, we can now see that we have two enabled protection schedules reflecting the applied protection policy, as well as the Backup and Recovery baseline backup and snapshot completed, while still having access to the original backup and snapshots:
$ tridentctl-protect get schedule -n web2
+-----------------------------------------+------+--------------------------------------+---------+-------+-------+-------+
| NAME | APP | SCHEDULE | ENABLED | STATE | ERROR | AGE |
+-----------------------------------------+------+--------------------------------------+---------+-------+-------+-------+
| web2-sched | web2 | Daily:hour=17,min=50 | false | | | 3d |
| web2-schedule-20260203172620-5wqd090q6c | web2 | DTSTART:20260203T172620Z | true | | | 9m17s |
| | | RRULE:FREQ=DAILY;BYHOUR=0;BYMINUTE=0 | | | | |
| web2-schedule-20260203172620-yuozpypmty | web2 | DTSTART:20260203T172620Z | true | | | 9m17s |
| | | RRULE:FREQ=HOURLY;BYMINUTE=0 | | | | |
+-----------------------------------------+------+--------------------------------------+---------+-------+-------+-------+
~$ tridentctl-protect get backup -n web2
+-----------------------------+------+----------------+-----------+-------+-------+
| NAME | APP | RECLAIM POLICY | STATE | ERROR | AGE |
+-----------------------------+------+----------------+-----------+-------+-------+
| custom-1857d-20260203172621 | web2 | Retain | Completed | | 9m24s |
| daily-bddef-20260126175000 | web2 | Retain | Completed | | 2d23h |
| daily-bddef-20260127175000 | web2 | Retain | Completed | | 1d23h |
+-----------------------------+------+----------------+-----------+-------+-------+
~$ tridentctl-protect get snapshot -n web2
+---------------------------------------------+------+----------------+-----------+-------+-------+
| NAME | APP | RECLAIM POLICY | STATE | ERROR | AGE |
+---------------------------------------------+------+----------------+-----------+-------+-------+
| backup-cefc29bb-af05-4a4f-81a6-00f883c2f6a0 | web2 | Delete | Completed | | 9m32s |
| daily-bddef-20260126175000 | web2 | Delete | Completed | | 2d23h |
| daily-bddef-20260127175000 | web2 | Delete | Completed | | 1d23h |
+---------------------------------------------+------+----------------+-----------+-------+-------+
We also confirm that the original two appVault CRs do still exist, and Backup and Recovery created an additional appVault CR for the backup target we created above:
$ tridentctl-protect get appvault
+------------------------------------+----------+-----------+-------+---------+-------+
| NAME | PROVIDER | STATE | ERROR | MESSAGE | AGE |
+------------------------------------+----------+-----------+-------+---------+-------+
| bucket-azure-r1zexovs6t-unmehsrv3k | Azure | Available | | | 6d2h |
| container1 | Azure | Available | | | 9d23h |
| container2 | Azure | Available | | | 9d23h |
+------------------------------------+----------+-----------+-------+---------+-------+
$ k -n trident-protect get appvault bucket-azure-r1zexovs6t-unmehsrv3k -o yaml | yq '.spec'
providerConfig:
azure:
accountName: pubrtest
bucketName: pubrtest
endpoint: core.windows.net
gcp:
bucketName: ""
projectID: ""
s3:
bucketName: ""
endpoint: ""
providerCredentials:
accountKey:
valueFromSecret:
key: accountKey
name: azure-bucket-azure-r1zexovs6t-secret
providerType: Azure
In this blog post, we walked through the process of integrating a Kubernetes cluster with existing Trident protect configurations into NetApp Backup and Recovery. By following these steps, you can leverage NetApp's advanced data protection capabilities to enhance the resilience and manageability of your containerized applications and virtual machines.
To summarize, we covered the following key points:
Login to NetApp Console, navigate to Protection --> Backup and Recovery and sign up for a free trial to add your cluster protected by Trident protect and bring their protection to the next level!