Tech ONTAP Blogs

Crash-Consistent Backup and Restore Operations for OpenShift Virtualization VMs using Trident 25.02

banusundhar
NetApp
142 Views

In a previous blog, I introduced Backup and Restore feature of the Trident 25.02 release that enhances the comprehensive data protection capabilities for VMs on KubeVirt-based platforms. In this blog, I will provide a detailed guide on how to create a backup of a VM and restore it. Additionally, I will demonstrate techniques for creating VM backups using labels on VM resources, which is particularly useful when managing multiple VMs within a single namespace. I will show how to restore a specific VM from a backup using label selectors to ensure only the intended VM is restored.

 

Prerequisites

Hardware Requirements

Ensure you have bare metal servers available for worker node creation in your OpenShift cluster.

 

OpenShift Cluster Setup

Install the OpenShift cluster that includes bare metal servers.

 

OpenShift Virtualization Installation

Install and configure the OpenShift Virtualization operator from the Operator Hub. Once installed, you will see the Virtualization option available in the console, allowing you to create VMs from the UI.

 

Storage Requirements

Ensure ONTAP storage is available and reachable from the worker nodes of the cluster for provisioning storage using Trident.

 

Trident Installation and Configuration

Install Trident version 25.02 or later on the OpenShift cluster. Create backend objects and storage classes using Trident to provision storage resources.

 

Trident Protect Installation

Install Trident Protect 25.02 on the cluster to enable backup and restore functionalities for OpenShift Virtualization VMs.

 

By following these prerequisites and setup instructions, you will be equipped to leverage the powerful backup and restore features provided by Trident 25.02, ensuring crash-consistent data protection for your VMs in an OpenShift Virtualization environment.

Below, you can see the resources that are already setup as mentioned in the prerequisites.

Screenshot 2025-03-12 at 3.44.06 PM.png

Screenshot 2025-03-12 at 3.44.15 PM.png

Screenshot 2025-03-12 at 3.44.24 PM.png

Screenshot 2025-03-12 at 3.44.32 PM.png

 

Create a VM in the namespace “demo” with a root disk and a data disk

The following screen shots show the creation of the VM from the console using the template. The root disk chooses the default storage class automatically, so, verify that the default storage class is set appropriately. In my setup, the default storage class is sc-zonea-san.  Ensure that when you create the additional disk, you choose the storage class sc-zonea-san and check the “Apply optimized storage settings” checkbox.  This will set the Access modes to RWX and Volume Mode to Block.

 

Note: Trident supports RWX access mode in Block Volume mode for SAN (iSCSI, NVMe/TCP and FC). (It is the default access mode for NAS). RWX Access mode is required if you need to do Live migration of the VMs at a later point.

 

Screenshot 2025-03-12 at 3.47.15 PM.png

Screenshot 2025-03-12 at 3.47.32 PM.png

Screenshot 2025-03-12 at 3.47.44 PM.png

Screenshot 2025-03-12 at 3.48.03 PM.png

Screenshot 2025-03-12 at 3.48.20 PM.png

 

List the vm, pods, pvc

Screenshot 2025-03-12 at 3.50.19 PM.png

 

Create a secret with appvault credentials and create appvault for trident-protect

 

# cat appvault-secret.yaml
apiVersion: v1
stringData:
  accessKeyID: "<access key of S3>"
  secretAccessKey: "<secret access key of S3>"
# you can also provide base 64 encoded values instead of string values
#data:
# base 64 encoded values
#  accessKeyID: < base 64 encoded access key> 
#  secretAccessKey: <base 64 encoded secretAccess key>
kind: Secret
metadata:
  name: appvault-secret
  namespace: trident-protect
type: Opaque

# cat appvault.yaml
apiVersion: protect.trident.netapp.io/v1
kind: AppVault
metadata:
  name: ontap-s3-appvault
  namespace: trident-protect
spec:
  providerConfig:
    azure:
      accountName: ""
      bucketName: ""
      endpoint: ""
    gcp:
      bucketName: ""
      projectID: ""
    s3:
      bucketName: trident-protect
      endpoint: <lif for S3 access>
      secure: "false"
      skipCertValidation: "true"
  providerCredentials:
    accessKeyID:
      valueFromSecret:
        key: accessKeyID
        name: appvault-secret
    secretAccessKey:
      valueFromSecret:
        key: secretAccessKey
        name: appvault-secret
  providerType: OntapS3

# oc create -f appvault-secret.yaml -n trident-protect
# oc create -f appvault.yaml -n trident-protect

 

Screenshot 2025-03-12 at 3.51.45 PM.png

 

Create an app that includes all resources in the “demo” namespace

The namespace demo has only one VM and so the trident protect app created represents that VM. Later, we will see how to selectively create an app if there is more than one VM  in the namespace.

 

# tp create app demo-vm --namespaces demo -n demo --dry-run > app.yaml
yaml
[root@localhost VM-DataProtection]# cat app.yaml
apiVersion: protect.trident.netapp.io/v1
kind: Application
metadata:
  creationTimestamp: null
  name: demo-vm
  namespace: demo
spec:
  includedNamespaces:
  - namespace: demo
# oc create -f app.yaml -n demo

 

Screenshot 2025-03-12 at 3.53.09 PM.png

 

Create backups

Create an On-demand backup

 

# tp create schedule backup-schedule1 --app demo-vm --appvault ontap-s3-appvault --granularity Hourly --minute 45 --backup-retention 1 -n demo --dry-run>backup-schedule-demo-vm.yaml 
schedule.protect.trident.netapp.io/backup-schedule1 created

#cat backup-schedule-demo-vm.yaml
apiVersion: protect.trident.netapp.io/v1
kind: Schedule
metadata:
  creationTimestamp: null
  name: backup-schedule1
  namespace: demo
spec:
  appVaultRef: ontap-s3-appvault
  applicationRef: demo-vm
  backupRetention: "1"
  dayOfMonth: ""
  dayOfWeek: ""
  enabled: true
  granularity: Hourly
  hour: ""
  minute: "45"
  recurrenceRule: ""
  snapshotRetention: "0"
status: {}
# oc create -f backup-schedule-demo-vm.yaml -n demo
# tp create backup demo-vm-backup-on-demand --app demo-vm --appvault ontap-s3-appvault -n demo
Backup "demo-vm-backup-on-demand" created.

 

Screenshot 2025-03-12 at 3.56.25 PM.png

Create a Schedule for backups

 

# tp create schedule backup-schedule1 --app demo-vm --appvault ontap-s3-appvault --granularity Hourly --minute 45 --backup-retention 1 -n demo --dry-run>backup-schedule-demo-vm.yaml 
schedule.protect.trident.netapp.io/backup-schedule1 created

#cat backup-schedule-demo-vm.yaml
apiVersion: protect.trident.netapp.io/v1
kind: Schedule
metadata:
  creationTimestamp: null
  name: backup-schedule1
  namespace: demo
spec:
  appVaultRef: ontap-s3-appvault
  applicationRef: demo-vm
  backupRetention: "1"
  dayOfMonth: ""
  dayOfWeek: ""
  enabled: true
  granularity: Hourly
  hour: ""
  minute: "45"
  recurrenceRule: ""
  snapshotRetention: "0"
status: {}
# oc create -f backup-schedule-demo-vm.yaml -n demo

 

Screenshot 2025-03-12 at 3.57.47 PM.png

Screenshot 2025-03-12 at 3.57.56 PM.png

 

Restore from backup

You can restore the VM to the same namespace or to a different namespace from any of the backups you have created. I am showing you an example for each restore operation.

Screenshot 2025-03-12 at 9.03.19 PM.png

Now, restore the VM from the backup to the demo namespace.

 

# tp create bir demo-fedora-restore --backup demo/demo-vm-backup-on-demand -n demo --dry-run>vm-demo-bir.yaml

# cat vm-demo-bir.yaml
apiVersion: protect.trident.netapp.io/v1
kind: BackupInplaceRestore
metadata:
  annotations:
    protect.trident.netapp.io/max-parallel-restore-jobs: "25"
  creationTimestamp: null
  name: demo-fedora-restore
  namespace: demo
spec:
  appArchivePath: demo-vm_cc8adc7a-0c28-460b-a32f-0a7b3d353e13/backups/demo-vm-backup-on-demand_f6af3513-9739-480e-88c7-4cca45808a80
  appVaultRef: ontap-s3-appvault
  resourceFilter: {}
status:
  postRestoreExecHooksRunResults: null
  state: ""

# oc create -f vm-demo-bir.yaml -n demo
backupinplacerestore.protect.trident.netapp.io/demo-fedora-restore created

 

 

Screenshot 2025-03-12 at 9.04.15 PM.png

Verify that the VM, pods and PVC are created in the same demo namespace.

Screenshot 2025-03-12 at 9.04.49 PM.png

 

Restore to different namespace

 

# tp create br demo2-fedora-restore --backup demo/hourly-4c094-20250312154500 --namespace-mapping demo:demo2 -n demo2 --dry-run>vm-demo2-br.yaml

# cat vm-demo2-br.yaml
apiVersion: protect.trident.netapp.io/v1
kind: BackupRestore
metadata:
  annotations:
    protect.trident.netapp.io/max-parallel-restore-jobs: "25"
  creationTimestamp: null
  name: demo2-fedora-restore
  namespace: demo2
spec:
  appArchivePath: demo-vm_cc8adc7a-0c28-460b-a32f-0a7b3d353e13/backups/hourly-4c094-20250312154500_aaa14543-a3fa-41f1-a04c-44b1664d0f81
  appVaultRef: ontap-s3-appvault
  namespaceMapping:
  - destination: demo2
    source: demo
  resourceFilter: {}
status:
  conditions: null
  postRestoreExecHooksRunResults: null
  state: ""
# oc create -f vm-demo2-br.yaml -n demo2

 

Screenshot 2025-03-12 at 9.05.26 PM.png

Screenshot 2025-03-12 at 9.05.44 PM.png

 

In our previous example, we demonstrated backing up a single VM within a namespace. By including the entire namespace in the backup, all resources associated with that VM were captured. But what happens when you have multiple VMs within the same namespace? How can you selectively back up a specific VM and its resources, and then restore it from the correct backup?

Let me show you how.

 

Create another VM (demo-centos) in the same namespace (demo)

Screenshot 2025-03-12 at 9.06.57 PM.png

Now label the VM and the related resources for the demo-centos VM.

Screenshot 2025-03-12 at 9.07.29 PM.png

You can verify that only the demo-centos VM and its PVCs  got the labels.

Screenshot 2025-03-12 at 9.08.00 PM.png

 

Create an app for only a specific VM (use the label selector)

 

# tp create app demo-centos-app --namespaces 'demo(category=protect-demo-centos)' -n demo --dry-run>demo-centos-app.yaml



# cat demo-centos-app.yaml

apiVersion: protect.trident.netapp.io/v1

kind: Application

metadata:

  creationTimestamp: null

  name: demo-centos-app

  namespace: demo

spec:

  includedNamespaces:

  - labelSelector:

      matchLabels:

        category: protect-demo-centos

    namespace: demo

status:

  conditions: null



# oc create -f demo-centos-app.yaml -n demo

application.protect.trident.netapp.io/demo-centos-app created

 

 

Screenshot 2025-03-12 at 9.09.14 PM.png

 

Create a backup of only a specific VM by using the app (demo-centos-app)

 

# tp create backup demo-centos-backup-on-demand --app demo-centos-app --appvault ontap-s3-appvault -n demo
Backup "demo-centos-backup-on-demand" created.

 

 

Screenshot 2025-03-12 at 9.10.00 PM.png

Restore from this backup (only demo-centos is restored)

 

Now, delete the demo-centos VM and restore it from the backup you just created.

Screenshot 2025-03-12 at 9.10.42 PM.png

 

[root@localhost VM-DataProtection]# tp create bir demo-centos-restore --backup demo/demo-centos-backup-on-demand -n demo --dry-run>demo-centos-bir.yaml
[root@localhost VM-DataProtection]# cat demo-centos-bir.yaml
apiVersion: protect.trident.netapp.io/v1
kind: BackupInplaceRestore
metadata:
  annotations:
    protect.trident.netapp.io/max-parallel-restore-jobs: "25"
  creationTimestamp: null
  name: demo-centos-restore
  namespace: demo
spec:
  appArchivePath: demo-centos-app_a7f2c791-f450-4245-871e-aa33cb4ffbf5/backups/demo-centos-backup-on-demand_e8ff8965-0c37-46ac-966f-97ed378c73f8
  appVaultRef: ontap-s3-appvault
  resourceFilter: {}
status:
  postRestoreExecHooksRunResults: null
  state: ""

[root@localhost VM-DataProtection]# oc create -f demo-centos-bir.yaml -n demo
backupinplacerestore.protect.trident.netapp.io/demo-centos-restore created

 

Verify that the demo-centos VM and its pvcs have been restored.

Screenshot 2025-03-12 at 9.11.27 PM.png

 

Conclusion

In this blog, we've explored how to protect VMs in OpenShift Virtualization using the robust backup and restore capabilities of Trident Protect. You have learned how to create backups and restore VMs, as well as how to use label selectors to selectively backup and restore specific VMs within a namespace. For more detailed information, please refer to the Trident Protect documentation. Additionally, for guidance on Failover and Failback scenarios for OpenShift Virtualization VMs, consult the Solutions documentation.

 

Public