OpenShift virtualization, powered by the KubeVirt project, extends Kubernetes’ capabilities by enabling seamless management of virtual machines (VMs) alongside containerized applications within a single platform. This empowers users to leverage the benefits of both containerization and virtualization in a cohesive environment.
One key advantage is streamlined storage management for VMs. By utilizing Kubernetes’ native storage concepts like persistent volumes (PVs) and persistent volume claims (PVCs), OpenShift simplifies provisioning and managing storage for virtual machines, making them easier to integrate and operate within a Kubernetes ecosystem.
You can get started with OpenShift virtualization by following this guide.
Summary of key concepts: VM storage in OpenShift with KubeVirt
The following table provides an overview of the key concepts covered in this article.
Key concept | Purpose |
KubeVirt-enabled storage as a native OpenShift object | Provision and manage persistent storage volumes directly from the OpenShift console, just like you would with containers. |
Performing Day 2 operations on VM storage | Dynamically add or resize disks for your virtual machines without downtime, ensuring that they adapt to changing storage needs. |
Cloning virtual machines with KubeVirt | Create instant copies of your VMs for backup, testing, or rapid deployment, accelerating your development and recovery processes. |
Using snapshots to restore VMs | Leverage snapshots to easily revert VMs to previous states, safeguarding against data loss and configuration errors. |
Leveraging the storage capabilities of KubeVirt for OpenShift virtualization
KubeVirt operates at the heart of OpenShift virtualization, acting as a Kubernetes custom resource definition (CRD) controller that introduces the concept of a virtual machine instance (VMI) to the Kubernetes API. This VMI is a first-class citizen within the Kubernetes ecosystem that allows VMs to be managed and orchestrated much like pods with containers and other native Kubernetes objects.
Under the hood, KubeVirt leverages the libvirt virtualization API to interface with hypervisors like KVM, which are responsible for the actual execution of virtual machines. Essentially, each VMI is a pod running a specialized container that acts as a hypervisor. Within this pod, virtual machines are launched and managed through resources allocated by Kubernetes.
OpenShift virtualization’s storage integration via KubeVirt
KubeVirt acts as the bridge between the world of virtual machines and the Kubernetes orchestration layer, providing a unified platform for managing both containers and VMs. The integration ultimately extends to storage management, where VMs can utilize the same storage abstractions and benefits as containers, simplifying provisioning, enhancing portability, and offering advanced features within a familiar Kubernetes environment.
KubeVirt leverages the Kubernetes persistent volume (PV) and persistent volume claim (PVC) mechanisms to handle storage provisioning for virtual machines through the following steps:
- Once a VMI is created, it can request storage resources through a PVC, which triggers the dynamic provisioning of a PV based on the defined storage class. The abstraction of the underlying storage implementation details allows VMs to request and consume storage seamlessly.
- KubeVirt ensures that the dynamically provisioned PV is attached to the VMI’s pod, making it accessible to the virtual machine as a virtual disk. The process is managed entirely by Kubernetes and does not depend on manual configuration.
- KubeVirt also integrates with storage providers to offer advanced capabilities like snapshots, clones, and thin provisioning. Snapshots enable quick point-in-time backups of VM disks, while clones facilitate rapid provisioning of new VMs from existing templates. Thin provisioning allows for the efficient allocation of storage resources by only utilizing the actual space consumed by the VM.
Managing storage as a native OpenShift object
Abstraction layers are the alpha and omega of any good system’s design. OpenShift’s storage management follows this principle and abstracts the underlying complexity by treating virtual machine storage as native OpenShift objects. This allows for the management of storage resources using well-known OpenShift constructs such as PVs and PVCs.
The following are the major components involved when dealing with storage in OpenShift:
- Persistent volume claims: The workloads in OpenShift clusters express their storage requirements through PVCs. A PVC specifies the storage size and access mode needed and optionally requests a specific storage class.
- Persistent volumes: These represent the physical storage resources available in the cluster. PVs can utilize different storage solutions, such as NFS, iSCSI, or specific storage systems offered by storage array vendors and cloud providers.
- Storage classes: These act as templates that group PVs with similar characteristics, such as performance tier, availability zone, or underlying storage provider. When creating a PVC, workloads can specify a desired storage class based on requirements.
- Container Storage Interface (CSI): OpenShift can also use the Container Storage Interface to consume storage from storage backends that implement the CSI interface as persistent storage. CSI acts as a plugin between OpenShift and the underlying storage provider. It translates storage requests (PVs and PVCs) into specific calls for the storage array that the driver manages. OpenShift virtualization can use any supported CSI provisioner.
- Storage provisioner: Each storage class uses a defined provisioner to create persistent volumes. The provisioner determines the volume plugin for provisioning these volumes and converts PVC requests into CSI calls to create and manage PVs.
Visualizing the PV, PVC, storage class, and CSI driver workflow in OpenShift
You can consult the official documentation here to learn more about persistent storage implementation in OpenShift.
Automated Kubernetes Data Protection & Intelligent Recovery
Perform secure application-centric backups of containers, VMs, helm & operators
Use pre-staged snapshots to instantly test, transform, and restore during recovery
Scale with fully automated policy-driven backup-and-restore workflows
Performing Day 2 operations on virtual machine storage
Storage is one of the most critical parts of a virtualization infrastructure due to the need to provide enough capacity for all workloads. In a traditional virtualization environment, everyday storage operations typically performed after initial VM deployment can be time-consuming and require close coordination between system and storage administrators. This might involve provisioning new volumes from the storage array and presenting them to the specific VMs through the hypervisor configuration.
The KubeVirt API in OpenShift supports hot plugging into running virtual machines and removal of volumes from them. The following sections cover two basic storage operations in OpenShift Virtualization: adding new disks and expanding existing ones. This article assumes that you’ve set up all the prerequisites for OpenShift Virtualization and have virtual machines running in your cluster. If you haven’t already, follow this guide to start with virtual machines in OpenShift.
Adding/removing disks
Before adding the disks, let’s examine the virtual machine’s existing storage. In the left-side menu in the OpenShift console, go to Storage → PersistentVolumeClaims. Make sure you select the project where you have virtual machines running.
Click the root PVC to see more information.
Notice that the volume’s access mode is ReadWriteMany (RWX). OpenShift virtualization can utilize any supported CSI provisioner that your environment supports. It imposes no restrictions on the storage protocol (e.g., NFS, iSCSI, or FC) specifically for OpenShift virtualization—the only requirement is presenting volumes to virtual machines in RWX mode. This necessity arises because virtual machines cannot live-migrate RWO volumes. These volumes are mounted read-write on a single node and would not be accessible on the destination node during migration.
Lets create a PVC so that we can hot-plug a disk to our running VM
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: my-fedora-1-pvc spec: accessModes: - ReadWriteMany storageClassName: ocs-storagecluster-ceph-rbd volumeMode: Block resources: requests: storage: 1Gi
You’ll need to change the details based on your environment. Here’s a breakdown of the PVC details mentioned above:
- The access mode of the PVC is ReadWriteMany (RWX).
- The PVC is requesting storage from the ocs-storagecluster-ceph-rbd storage class.
- The volume mode of the PVC is Block.
- The PVC has a requested capacity and size of 30 GiB.
Create the PVC from this definition:
$ oc create -f my-fedora-1-pvc.yaml persistentvolumeclaim/my-fedora-1-pvc created
Now, verify that the PVC has been created:
$ oc get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE my-fedora-1-pvc Bound pvc-eabc2702-1a73-4e6e-9597-7872dc995735 1Gi RWX ocs-storagecluster-ceph-rbd 2s [.....]
Let’s hot-plug this new volume into our virtual machine as follows. The following command will attach my-fedora-1-pvc to the my-fedora-1 VM. The –serial flag is optional and is used to identify the newly added disk by assigning the label disk-1G to this volume.
$ oc get vm NAME AGE STATUS READY my-fedora-1 58m Running True $ virtctl addvolume my-fedora-1 --volume-name=my-fedora-1-pvc --serial=disk-1G Successfully submitted add volume request to VM my-fedora-1 for volume my-fedora-1-pvc
Depending on your preferred method, access the virtual machine console and list the available block devices. You should be able to see the newly added disk in the list. In the following output, the newly added disk is shown as sda.
$ virtctl ssh fedora@my-fedora-1 -i .ssh/id_rsa Last login: Sun Jul 14 17:36:08 2024 from 10.128.0.13 [fedora@my-fedora-1 ~]$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 1G 0 disk zram0 251:0 0 3.8G 0 disk [SWAP] vda 252:0 0 30G 0 disk ├─vda1 252:1 0 2M 0 part [......]
Similarly, we can hot-unplug the disk after specifying the PVC and VM names.
$ virtctl removevolume my-fedora-1 --volume-name=my-fedora-1-pvc Successfully submitted remove volume request to VM my-fedora-1 for volume my-fedora-1-pvc
As you can see below, the device sda is no longer listed in the list of block device
[fedora@my-fedora-1 ~]$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS zram0 251:0 0 3.8G 0 disk [SWAP] vda 252:0 0 30G 0 disk ├─vda1 252:1 0 2M 0 part [......]
Watch this 1-min video to see how easily you can recover K8s, VMs, and containers
Online disk expansion
Like expanding volumes on the fly for containerized workloads, you can also increase the virtual machine disk size by extending the PVC size. However, the underlying storage class must support volume expansion for this to work. You can use the following command to check if your configured storage class supports online volume expansion. If the AllowVolumeExpansion field is set to True, the KubeVirt API can leverage this capability to dynamically increase the storage capacity of virtual machines using these storage classes.
$ oc describe sc ocs-storagecluster-ceph-rbd |grep AllowVolumeExpansion AllowVolumeExpansion: True
As the last section explained, you can create a PVC and attach it to your virtual machine. After verifying the connection of the new disk to the virtual machine, modify the PVC configuration and request a new size by changing the value of the storage field based on your requirements.
$ oc edit persistentvolumeclaim/my-fedora-1-pvc # Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: v1 kind: PersistentVolumeClaim metadata: annotations: [.....] spec: accessModes: - ReadWriteMany resources: requests: storage: 2Gi [.....]
Once changes have been made, save and close the editor. If you list the PVCs, you’ll see that the size has been updated.
$ oc get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE my-fedora-1-pvc Bound pvc-eabc2702-1a73-4e6e-9597-7872dc995735 2Gi RWX ocs-storagecluster-ceph-rbd 2s
The same can also be validated from inside the virtual machine.
$ virtctl ssh fedora@my-fedora-1 -i .ssh/id_rsa Last login: Sun Jul 14 20:16:52 2024 from 10.128.0.13 [fedora@my-fedora-1 ~]$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 2G 0 disk [.....]
Cloning virtual machines in OpenShift
Cloning involves creating an identical replica of your original virtual machine. This newly created virtual machine comes with the same virtual hardware, preinstalled software, and other settings of the original VM.
Types of cloning
When cloning data volumes, the Containerized Data Importer (CDI) in OpenShift virtualization can use a different cloning technique depending on the most efficient method available:
- CSI volume cloning: This method leverages features of the underlying storage class exposed through CSI drivers to create a direct copy of the source data volume.
- Smart cloning: This method utilizes snapshots, if available, through a CSI plugin. CDI creates a new PVC from a snapshot of the source volume, enabling efficient cloning of additional volumes based on that snapshot.
- Host-assisted cloning: CDI resorts to this method when neither CSI nor smart cloning is applicable. This approach involves creating a source pod and a target pod to copy data directly from the source to the target volume. While slower than the other two methods, it has fewer prerequisites.
OpenShift uses storage profiles to define recommended storage configurations for individual storage classes. You can check if your storage class will use CSI, smart, or host-assisted cloning as follows:
$ oc get StorageProfile NAME AGE ocs-storagecluster-ceph-rbd 48d [.....] $ oc get StorageProfile ocs-storagecluster-ceph-rbd -o yaml |grep cloneStrategy cloneStrategy: csi-clone [.....]
For smart cloning, the cloneStrategy field will be set to snapshot, and for host-assisted cloning, it will have the value copy. You can also change the cloning strategy for your storage profile:
$ oc get StorageProfile NAME AGE ocs-storagecluster-ceph-rbd 48d [.....] $ oc edit StorageProfile ocs-storagecluster-ceph-rbd apiVersion: cdi.kubevirt.io/v1beta1 kind: StorageProfile metadata: [........] spec: cloneStrategy: copy [........]
Creating virtual machine clones
Before proceeding, make sure to install the QEMU guest agent on the virtual machine you want to clone. This agent is required to pass the necessary information about the VM to the host.
Let’s create a clone of our virtual machine’s PVC. First, shut down the virtual machine whose volume you want to clone:
$ oc get vm NAME AGE STATUS READY my-fedora-1 2h Running True $ virtctl stop my-fedora-1 $ oc get vm NAME AGE STATUS READY my-fedora-1 40h Stopped False
Find the PVC you want to clone:
$ oc get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE root Bound pvc-624dd4fe-d0ce-4f75-b244-6f1f1e8df190 30Gi RWX ocs-storagecluster-ceph-rbd 2h
Create a manifest file as follows. The cdi.kubevirt.io API defines resources for cloning KubeVirt objects. Make sure to mention the name of the project hosting the source PVC.
apiVersion: cdi.kubevirt.io/v1beta1 kind: DataVolume metadata: name: root-clone spec: source: pvc: namespace: "vm-pool" name: "root"
$ oc create -f clone.yaml
By default, users cannot clone volumes to a different project. If you want non-admin users to be able to clone the VM to a different project, follow the instructions here to create a cluster role that allows the necessary permissions.
If you take a look at your PVCs or data volumes, you should be able to see the newly created clone:
$ oc get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE root Bound pvc-624dd4fe-d0ce-4f75-b244-6f1f1e8df190 30Gi RWX ocs-storagecluster-ceph-rbd 2h root-clone Bound pvc-6c690753-a4d2-4940-8a83-3b17e1de5eff 30Gi RWX ocs-storagecluster-ceph-rbd 2h $ oc describe pvc root-clone Name: root-clone Namespace: vm-pool StorageClass: ocs-storagecluster-ceph-rbd Status: Bound [...........] Annotations: cdi.kubevirt.io/clonePhase: Succeeded cdi.kubevirt.io/cloneType: csi-clone cdi.kubevirt.io/storage.condition.running: false cdi.kubevirt.io/storage.condition.running.message: Clone Complete cdi.kubevirt.io/storage.condition.running.reason: Completed [...........]
Learn about the features that power Trilio’s intelligent backup and restore
Creating virtual machine snapshots in OpenShift
In a virtualization environment, snapshots play a crucial role by capturing the state of a VM’s disks at a specific time. This offers numerous benefits, such as rolling back to a known good state and restoring VMs in case of an issue. Furthermore, unlike cloning, one can take snapshots of a running VM.
Requirements
The following are required for VM snapshots in OpenShift virtualization:
- A supported storage provider: Any storage provider with a CSI driver that supports the Kubernetes volume snapshot API can be used to snapshot virtual machine disks in OpenShift virtualization.
- QEMU guest agent: While not strictly mandatory, installing the QEMU guest agent within the VM’s operating system is highly recommended for online snapshots. The guest agent facilitates communication with the storage driver, ensuring data consistency during the snapshot process. Snapshots might not capture the most recent data state without the agent, potentially leading to inconsistencies.
Creating snapshots
To check if your storage class provisioner supports taking snapshots, you can explore the documentation for the specific CSI driver. You can list the CSI driver for your cluster and then find the available snapshot classes:
$ oc get csidrivers NAME ATTACHREQUIRED PODINFOONMOUNT STORAGECAPACITY TOKENREQUESTS REQUIRESREPUBLISH MODES AGE openshift-storage.rbd.csi.ceph.com true false false false Persistent 115d $ oc get volumesnapshotclasses NAME DRIVER DELETIONPOLICY AGE ocs-storagecluster-rbdplugin-snapclass openshift-storage.rbd.csi.ceph.com Retain 115d
To create an online snapshot for your virtual machine, create an offline snapshot for our VM:
$ virtctl stop my-fedora-1 VM my-fedora-1 was scheduled to stop $ oc get vm NAME AGE STATUS READY my-fedora-1 5m7s Stopped False
Define a VirtualMachineSnapshot object in your manifest file. The snapshot.kubevirt.io API group defines the necessary resources for snapshotting and restoring virtual machines. Specify the snapshot name and the source virtual machine:
apiVersion: snapshot.kubevirt.io/v1alpha1 kind: VirtualMachineSnapshot metadata: name: my-fedora-1-snap spec: source: apiGroup: kubevirt.io kind: VirtualMachine name: my-fedora-1
Create the snapshot from the manifest file, and verify that it has been completed and then make sure to check the status field in the output. In case of successful completion, the status will be shown as successful:
$ oc create -f snap.yaml virtualmachinesnapshot.snapshot.kubevirt.io/my-fedora-1-snap created $ oc get vmsnapshot NAME SOURCEKIND SOURCENAME PHASE READYTOUSE CREATIONTIME ERROR my-fedora-1-snap VirtualMachine my-fedora-1 Succeeded true 3s
To restore the VM from a snapshot, define a VirtualMachineRestore object in your manifest file. Specify the snapshot name and the source virtual machine:
apiVersion: snapshot.kubevirt.io/v1alpha1 kind: VirtualMachineRestore metadata: name: my-fedora-1-restore spec: target: apiGroup: kubevirt.io kind: VirtualMachine name: my-fedora-1 virtualMachineSnapshotName: my-fedora-1-snap
The restore operation can only be performed on a powered-down VM, so make sure the VM is powered down:
$ oc get vm NAME AGE STATUS READY my-fedora-1 6m4s Stopped False
Create the restore object and verify that the VM has been restored:
$ oc create -f restore.yaml virtualmachinerestore.snapshot.kubevirt.io/my-fedora-1-restore created $ oc get vmrestore NAME TARGETKIND TARGETNAME COMPLETE RESTORETIME ERROR my-fedora-1-restore VirtualMachine my-fedora-1 true 3s
Once the snapshot has been restored, the VM can be powered up again:
$ virtctl start my-fedora-1 VM my-fedora-1 was scheduled to start
Creating and restoring virtual machine backups in OpenShift
In addition to snapshots and clones, complete backups of virtual machines can be created in OpenShift. Unlike snapshots—which capture a point-in-time image—or clones—which generate a copy of a running VM—backups provide complete, restorable, independent copies of virtual machines for long-term retention.
Specialized tools can be used for backing up virtual machines. Trilio is one of the most popular solutions for creating backups in OpenShift and can protect both application containers and virtual machines. In the following demo, we’ll see how Trilio can be used to back up and restore virtual machines in OpenShift.
You can refer to this link to install and configure the Trilio operator in OpenShift. Once the Trilio operator has been installed, the Trilio Backups tab will become available in the OpenShift console.
Creating virtual machine backups using Trilio
To create virtual machine backups using Trilio, follow these steps:
- Define a backup target: Specify the storage location for your backups.
- Create a backup plan: Determine backup frequency, retention policy, and other relevant settings for your backup.
- Execute backups: Initiate the backup process for your virtual machines based on the defined plan.
To create a backup target, go to Trilio Backups -> Target in the OpenShift console and define the storage location for your backups. The target storage can either be an NFS or an S3 object store. Here, we will use an NFS server to store our virtual machine backups. Make sure that you do the following:
- Select the desired namespace for the backup target.
- Assign the necessary write permissions on the NFS/S3 target to store the backups.
- Assign the necessary storage space to the backup targets so that they don’t run out of space when backing up virtual machine data.
Creating backup targets using Trilio
Once Trilio has validated your defined backup target, its status should change to Available.
Successful backup target creation
Now that we’ve created our backup target, we can store backups. At this point, we will switch to using the Trilio dashboard for the remaining steps. We can continue using the OpenShift console to complete the remainder of the tasks, but using the dedicated Trilio dashboard to manage backups is recommended. The Trilio dashboard is specifically designed for backup and recovery operations, offering a more comprehensive range of features, granular control, and advanced options than the OpenShift console.
You can launch the Trilio dashboard as follows:
Launching the Trilio dashboard
Once you’re in the Trilio console, create a backup plan as follows. Select the “Backup & Recovery” tab and click Create Backup and select “Application”.:
Creating virtual machine backups
Creating a backup plan
Select the virtual machine tab, select the virtual machines you want to backup and click “Next”.
Selecting virtual machine for backups
If there is no existing backup plan, create a new one by clicking “Create new”.
Creating a new backup plan
And then enter the configuration parameters as shown below. Select the target that was previously created for this backup plan.
Defining backup plan parameters
There are no additional components or applications to add so you can proceed to click next on the Component Details tab. We are not creating a Continuous Restore policy for this backup, so we can proceed to click on “Skip and Create”.
Successful creation of the backup plan
Once the backup plan has been completed successfully, click finish and you will return to the “Select Backup Plan” window.
Ensure that the newly created plan is selected and click “Next”.
Selecting the newly created backup plan
Enter a name for the backup and click “Create Backup” to start the backup process.
The backup will take some time, depending on the size of your virtual machine. The dialog box will continue to show you the different stages of the backup until it is complete.
Once the backup plan is created, a success screen appears with a status log as shown below:
Successful backup creation
Restoring virtual machine backups using Trilio
The backup virtual machine can be restored in the same project or a different one. To restore a virtual machine from backup, select the View Backup & Restore Summary option from the Create Backup drop-down menu:
Restoring virtual machines from backup
Click the Restore option at the bottom:
Restoring from available restore points
Select the desired project where you want to restore the backup and set a name for the restore resource. You can skip the Advanced section and click Create. Once done, you would get a status log with a confirmation of the restore:
Successful restore operation
Once the restored operation completes, the restored virtual machine will run in the selected project.
Limitations of snapshots and clones in OpenShift Virtualization
Consider the following limitations when using snapshots and clones in OpenShift Virtualization:
- Not all storage classes in OpenShift Virtualization natively support snapshots or cloning. The underlying storage provider must support the OpenShift Volume Snapshot API.
- The QEMU guest agent must be installed in the operating system to create snapshots of live VMs.
- Although you can create snapshots for running VMs, you must power off the VM to restore a snapshot.
Optimizing Day 2 storage management in OpenShift
The following are some of the best practices for managing virtual machine storage in OpenShift virtualization:
- When creating PVCs for VMs, request only the necessary storage capacity to avoid wasting space.
- Estimate the disk usage of your VMs and factor in snapshot sizes to ensure sufficient storage capacity for both active VMs and snapshots.
- Choose an appropriate storage provider that supports snapshots and clones.
- Regularly review and delete old snapshots that are no longer needed. Retaining unnecessary snapshots can consume valuable storage space.
- Schedule snapshots during periods of low VM write activity to minimize the risk of data inconsistencies.
- Use a comprehensive backup and disaster recovery solution for your virtual machines to ensure data protection and quick recovery in case of an incident. Consider using solutions such as Trilio for this purpose.
Learn about a lead telecom firm solved K8s backup and recovery with Trilio
Conclusion
KubeVirt, the foundation of OpenShift Virtualization, seamlessly integrates with OpenShift’s storage concepts, simplifying virtual machine storage management. This familiarity makes it easier for users accustomed to the OpenShift working method to handle storage management tasks. Users can quickly perform daily operations such as hot-plugging or expanding existing disks. OpenShift Virtualization also supports advanced features like snapshots and cloning, which assist in data protection and recovery scenarios. For virtual machine backups, specialized solutions such as Trilio can offer comprehensive backup and restore options for virtual machines.
- Summary of key concepts: VM storage in OpenShift with KubeVirt
- Leveraging the storage capabilities of KubeVirt for OpenShift virtualization
- Performing Day 2 operations on virtual machine storage
- Cloning virtual machines in OpenShift
- Creating virtual machine snapshots in OpenShift
- Creating and restoring virtual machine backups in OpenShift
- Limitations of snapshots and clones in OpenShift Virtualization
- Optimizing Day 2 storage management in OpenShift
- Conclusion
Like This Article?
Subscribe to our LinkedIn Newsletter to receive more educational content