Bookmark this page

Chapter 5.  Configuring Kubernetes Storage for Virtual Machines

Abstract

Goal

Manage storage and disks for VMs in Red Hat OpenShift.

Objectives
  • Configure appropriate services for persistent VM storage.

  • Attach disks to a VM.

  • Connect a VM to external storage by using Multus.

Sections
  • Attaching Persistent Storage to Virtual Machines (and Guided Exercise)

  • Attaching and Accessing Disks on Virtual Machines (and Guided Exercise)

  • Connecting Virtual Machines to External Storage (and Guided Exercise)

Lab
  • Configuring Storage for Virtual Machines

Attaching Persistent Storage to Virtual Machines

Objectives

  • Configure appropriate services for persistent VM storage.

Container Storage Concepts

Kubernetes implements various resources to abstract the details of the underlying storage architecture. Developers can request persistent storage for applications without applying specific settings for LUNs, NFS, or other storage back ends.

Kubernetes pods are composed of one or more containers. Each container is stateless by default because the provided storage is ephemeral. You can configure the containers in a pod to request persistent storage to preserve the state when the application is restarted.

Container Storage

Containers have ephemeral storage by default. When Kubernetes destroys a pod, it deletes all the files and data that are associated with that pod. You need a mechanism to preserve the application data, because Kubernetes destroys and re-creates pods when you scale down your application, deploy a new version, or when a node is drained for maintenance.

Ephemeral storage

Pods and containers can require temporary or transient local storage for their operation. This ephemeral storage does not extend beyond the lifetime of the individual pod, and this ephemeral storage cannot be shared across pods.

Persistent storage

Pods and containers can require permanent storage for their operation. OpenShift uses the Kubernetes Persistent Volume (PV) framework so cluster administrators can provision persistent storage for a cluster. Developers can use a Persistent Volume Claim (PVC) to request PV resources without knowing the underlying storage infrastructure.

Connection to the Back-end Storage

The administrator configures a connection between the Kubernetes cluster and the back-end storage by using Container Storage Interface (CSI) plug-ins, and then creates storage classes to represent the available storage types in the back-end storage controller.

CSI plugins

The CSI standard enables the use of backing storage to containers. The Kubernetes cluster plug-ins enable the cluster to interface with the specific storage back-end and to provide persistent storage to containers.

Storage Classes

The storage class resources in Kubernetes describe the storage characteristics, such as quality of service, throughput, or technology that the backing data services provide. Kubernetes defines storage classes to provide various cluster storage types to address different application requirements. Applications consume these storage classes as PVs that PVCs define. Storage classes are cluster-wide resources.

Each storage class uses a storage provisioner that determines the volume plug-in for provisioning the PVs. Each storage class also contains the fields for such needs as to configure the reclaim policy (to retain, recycle, or delete the released volumes), or to enable volume expansion. Other storage technologies, such as Ceph File System or Amazon Elastic Block Storage, use different volume provisioners.

Persistent Volumes and Persistent Volume Claims

Kubernetes uses persistent volumes to preserve data across container executions. Inside the container, you mount a persistent volume in a directory where the application stores its data. For example, MariaDB Server stores its database data under the /var/lib/mysql/data directory. By mounting a volume in that directory, you preserve the database data across container executions.

Persistent Volumes

Persistent volumes are Kubernetes resources that abstract the users from how the storage is provisioned. Depending on the underlying backing data service, the administrator can create the persistent volumes in advance, or the storage provisioner can create them dynamically.

The persistent volume specifications contain the access mode, the storage capacity, and the storage class name that provides the backing data service. Persistent volumes are cluster-wide resources.

Persistent Volume Claims

PVCs are Kubernetes objects to request storage PVs. A PVC can include specific details such as the size and the access mode. PVCs are namespaced resources.

Volume Provisioning

Kubernetes supports two ways of provisioning storage: static and dynamic.

Static provisioning

Requires the cluster administrators to prepare volumes manually. For example, administrators can create PVs that are mapped to NFS shares or to logical units from a Storage Area Network (SAN) system. Developers can use PVC resources to access these volumes.

Dynamic provisioning

When a developer creates a PVC to get a volume of a specific storage class, Kubernetes uses the provisioner that is associated with the class to allocate the volume dynamically on demand. A provisioner is a plug-in that communicates with the back-end storage to manage volumes.

Volume Modes

Applications can request a persistent storage file system to mount a directory, or a raw block device for the fastest possible low-level operations. The application developer specifies the intended volume mode in the persistent volume claim (PVC).

Filesystem

When set to the Filesystem default, the returned volume has a file system that you can directly mount inside your container.

This volume mode is the default if the parameter is not specified.

Block

When set to Block, you access the volume in the container as a block device, such as /dev/xvda. You use this mode with applications that require a raw device.

Note

Not all back-end storage supports both modes.

Volume Access Modes

Each storage back-end has different characteristics, and the provided volumes can be mounted by one or more containers in read-only or read/write mode. The application developer specifies the intended access mode in the PVC.

ReadWriteOnce

You can mount the volume read/write on one container at a time. This mode is often used for block devices. The OpenShift web console and the oc get pvc command report this mode as RWO.

ReadOnlyMany

You can mount the volume read/write on several containers simultaneously. The OpenShift web console and the oc get pvc command report this mode as ROX. Not all back-end storage supports this mode.

ReadWriteMany

You can simultaneously mount the volume read-only on several containers. The OpenShift web console and the oc get pvc command report this mode as RWX. Not all back-end storage supports this mode.

Warning

VM live migration requires disks of the ReadWriteMany (RWX) type.

Selecting a Storage Class

As a developer, you request a volume for your application by creating a Kubernetes PVC resource. The main parameters of a PVC are the size and the access mode. Kubernetes processes your PVC, prepares a PV, and then binds it to the PVC.

[user@host ~]$ oc get pvc
NAME  STATUS   VOLUME  CAPACITY  MODE  STORAGECLASS
vm1   Bound    pvc-…   10Gi      RWX   ocs-external-storagecluster-ceph-rbd	1
vm2   Pending  ​        ​          ​      ocs-external-storagecluster-ceph-rbd-​vi…	2

1

The vm1 PVC is bound and its associated persistent volume is being used in a virtual machine.

2

The vm2 PVC has the Pending status because it is waiting for Kubernetes to prepare and assign a PV.

As a developer, you do not know the exact details of the storage infrastructure. The cluster administrators manage that infrastructure, which might be composed of several technologies, such as iSCSI, Fibre Channel (FC), Network File System (NFS), Amazon Elastic Block Store (EBS), or Red Hat Ceph Storage services.

The cluster administrators expose these storage solutions through storage classes. Developers select the storage class in their PVCs. For example, the cluster administrators might create a storage class named gold that is using your company's fast Red Hat Ceph Storage infrastructure. The administrators can also create a silver storage class based on slower NFS shares.

When you deploy Red Hat OpenShift Container Platform (RHOCP) on a cloud provider infrastructure, the installation process automatically creates a default storage class. For example, the default storage class on Amazon Web Services (AWS) is named gp2 and uses EBS volumes of the General Purpose 2 (gp2) type. On Microsoft Azure, managed-premium is the default storage class name.

You can list the available storage classes on your cluster by using the oc get storageclasses command.

[user@host ~]$ oc get storageclasses
NAME                                                 PROVISIONER
nfs-storage (default)                                k8s-sigs.io/nfs-subdir-…	1
ocs-external-storagecluster-ceph-rbd                 openshift-storage.rbd.csi…
ocs-external-storagecluster-ceph-rbd-​virtualization  openshift-storage.rbd…	2
ocs-external-storagecluster-ceph-rgw                 openshift-storage.ceph.rook…
ocs-external-storagecluster-cephfs                   openshift-storage.cephfs.csi…
openshift-storage.noobaa.io                          openshift-storage.noobaa.io…

1

The default storage class has an indicator to help identify it.

2

The ODF storage class for virtualization.

You can also use the OpenShift web console. Navigate to StorageStorageClasses to list the storage classes.

1

The default storage class has an indicator to help identify it.

2

The ODF storage class for virtualization.

The preceding screen capture shows the available storage classes. In this example, the cluster administrators created the nfs-storage class. The other classes are from a Red Hat OpenShift Data Foundation installation. OpenShift Data Foundation is an additional product that is based on Ceph technologies. It can aggregate the available disk space on your cluster nodes as a resilient storage service.

Storage Class Annotations

The persistent volume claims may contain a field to specify the storage class that is requested from the cluster. The default storage class is used for the new PVCs that do not specify a storage class requirement.

The OpenShift storage classes might contain annotations to identify the default storage class in the cluster, or to indicate that the storage class is specialized for use with virtual machine disks.

storageclass.kubernetes.io​/is-default-class=​true

This annotation indicates that this storage class is used for all the new PVCs if no storage class is specified. This annotation is applied to the default storage class with a value of true. You can verify whether the storage class has this annotation by using the following command:

[user@host ~]$ oc describe storageclass nfs-storage | grep is-default-class
Annotations:           storageclass.kubernetes.io/is-default-class=true
storageclass.kubevirt.io​/is-default-virt-class=​true

This annotation indicates that the storage class has customized settings for virtual machine disks. OpenShift Data Foundation creates this storage class when it detects that OpenShift Virtualization is installed on the cluster. You can verify whether the storage class has this annotation by using the following command:

[user@host ~]$ oc describe storageclass \
  ocs-external-storagecluster-ceph-rbd-​virtualization | grep is-default-virt-class
Annotations:           description=Provides RWO and RWX Block volumes suitable for Virtual Machine disks,storageclass.kubevirt.io/is-default-virt-class=true

Note

ODF creates the ocs-external-storagecluster-ceph-rbd-​virtualization storage class only if it was installed in internal mode. You can create the storage class with the mapOptions: "krbd:rxbounce" parameter if ODF is installed on your cluster in external mode.

Requesting a Persistent Volume

As a developer, you request a PV through a PVC. You can prepare a PVC by using a YAML resource manifest. PVCs are namespaced resources, whereas PVs are cluster-wide resources.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: dbdata	1
spec:
  storageClassName: ocs-external-storagecluster-ceph-rbd-​virtualization	2
  accessModes:
    - ReadWriteOnce	3
  resources:
    requests:
      storage: 10Gi	4
  volumeMode: Filesystem	5

1

The name of the PVC resource.

2

The storageClassName parameter specifies the storage class to use.

3

The accessModes parameter indicates how containers can access the volume.

4

The storage parameter specifies the requested volume size.

5

The volumeMode parameter gives the volume type.

Note

Most applications consume volumes in the Filesystem mode, because containers store their data as files and directories.

However, for optimal performance, Red Hat recommends using volumes in Block mode for VM disks.

You can also use the OpenShift web console to create PVCs. Navigate to StoragePersistentVolumeClaims, click Create PersistentVolumeClaimWith Form, and then complete the form.

Figure 5.1: Create a Persistent Volume Claim

Configuring Persistent Storage for Virtual Machines

Red Hat OpenShift Virtualization provides several mechanisms to manage the VM disks. Most of these mechanisms rely on PVCs. A VM disk uses a PV that contains a disk image. For example, the root disk of a VM uses a PV that stores the operating system disk image.

  • With PVCs in Block mode, OpenShift Virtualization transfers the disk image into the volume. The VM disk uses the volume as its back-end device.

  • With PVCs in Filesystem mode, OpenShift Virtualization creates a disk.img file at the root of the PV file system and then copies the disk image into the file. The VM disk uses the disk.img file as its back-end device.

OpenShift Virtualization introduces new resource types to help creating the PVC with optimal parameters for VM disks and copying the disk image into the resulting PV:

Storage profile

For each storage class, a storage profile resource gives default values that are optimized for VM disks. Storage profiles are cluster-wide resources.

[user@host ~]$ oc get storageprofiles
NAME                                                  AGE
nfs-storage                                           1h
ocs-external-storagecluster-ceph-rbd                  1h
ocs-external-storagecluster-ceph-rbd-​virtualization   1h
ocs-external-storagecluster-ceph-rgw                  1h
ocs-external-storagecluster-cephfs                    1h
openshift-storage.noobaa.io                           1h
Data volume

A data volume resource describes a VM disk. It groups the PVC definition and the details of the disk image to inject into the PV. Data volumes are namespaced resources.

[user@host ~]$ oc get datavolumes -n storage-intro
NAME   PHASE       PROGRESS   RESTARTS   AGE
vm1    Succeeded   100.0%     1          5m
vm2    Succeeded   100.0%     1          1m

Listing the Available Storage Profiles

For each storage class, OpenShift Virtualization creates a storage profile. Storage profiles have the same name as their associated storage classes. A storage profile defines the PVC default values that are best suited for VM disks.

The following example shows that the ocs-external-storagecluster-ceph-rbd-​virtualization storage profile provides default values for the PVCs that are created through the storage class with the same name:

[user@host ~]$ oc get storageclass \
  ocs-external-storagecluster-ceph-rbd-​virtualization
NAME                                                  PROVISIONER
ocs-external-storagecluster-ceph-rbd-​virtualization   openshift-storage.rbd.csi…

[user@host ~]$ oc describe storageprofile \
  ocs-external-storagecluster-ceph-rbd-​virtualization
Name:         ocs-external-storagecluster-ceph-rbd-​virtualization	1
Namespace:    ​	2
Labels:       ...output omitted...
...output omitted...
Annotations:  <none>
API Version:  cdi.kubevirt.io/v1beta1
Kind:         StorageProfile
...output omitted...
Spec:
Status:
  Claim Property Sets:
    Access Modes:
      ReadWriteMany	3
    Volume Mode:  Block	4
    Access Modes:
      ReadWriteOnce	5
    Volume Mode:  Block
    Access Modes:
      ReadWriteOnce
    Volume Mode:  Filesystem	6
...output omitted...
  Provisioner:           openshift-storage.rbd.csi.ceph.com
  Storage Class:         ocs-external-storagecluster-ceph-rbd-​virtualization	7
Events:                  <none>
...output omitted...

1

The name of the storage profile resource.

2

No namespace is listed, because storage profiles are cluster-wide resources.

3 5

This storage profile supports the ReadWriteMany and ReadWriteOnce access modes.

4 6

This storage profile supports the Block and Filesystem volume modes.

7

The associated storage class of this storage volume is ocs-​external-​storagecluster-​ceph-​rbd-​virtualization.

The default settings for a storage profile are determined by the order in which the access mode and volume modes are declared. The preceding storage profile declares the ReadWriteMany access mode as the default, which enables VM live migrations, and declares the Block volume mode as the default, which provides better performance for VM disks than the Filesystem mode.

As a developer, when you use a storage profile to prepare a VM disk, the only parameter that you must provide is the disk size. The storage profile ensures that all the other parameters have an optimal value for VM disk usage.

Creating a Virtual Machine Disk by Using a Data Volume

The data volume resources define properties for the associated PVC, and the location of the source image to initialize the volume.

apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
  name: vm1	1
  namespace: storage-intro	2
  ...output omitted...
spec:
  pvc:
    accessModes:
    - ReadWriteMany	3
    resources:
      requests:
        storage: 10Gi	4
    storageClassName: ocs-external-storagecluster-ceph-rbd-​virtualization	5
    volumeMode: Block	6
  source:
    http:
      url: http://images.example.com/openshift4/images/mariadb-server.qcow2	7

1

The name of the data volume resource.

2

The namespace that contains this data volume resource.

3

The associated PVC requests a volume with the ReadWriteMany access mode.

4

The requested volume size for the persistent volume claim.

5

The requested storage class for the persistent volume claim.

6

The associated PVC requests a block volume.

7

Use the disk image from this URL to initialize the persistent volume. OpenShift Virtualization can import the image from this location or by cloning another PVC.

Note

The following example of a source section instructs the data volume to create an empty disk:

apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
...output omitted...
spec:
...output omitted...
  source:
    blank: {}	1

1

The curly braces represent an empty map in YAML syntax.

When the PVC to create is in Filesystem mode, the data volume automatically instructs Kubernetes to create the PVC 5.5% larger than requested to account for file system overhead. By doing so, Kubernetes ensures that it can create the disk image file, disk.img, with the requested size.

Warning

If your cluster administrator set storage resource quotas for your project, then these quotas apply to the PVCs that you create through data volumes.

Note

Deleting a data volume resource triggers the deletion of the associated PVC and PV. However, if the volume is attached to a VM, then the deletion occurs only after you have detached the volume.

Attaching a Data Volume to a Virtual Machine

Use the OpenShift web console to create a data volume and attach it to a VM as an additional disk.

  1. Navigate to VirtualizationVirtualMachines.

  2. Click the VM name to open its details page.

  3. Click ConfigurationDisks to display the VM disks.

  4. Click Add disk and complete the form.

Figure 5.2: Add a disk to a virtual machine

Note

You can attach disks to running VMs. However, you might find that some options are unavailable. For example, when the VM is running, the only option available in the Interface field is scsi, which might not provide the best performance compared to the virtio interface.

Using Local Node Disk Space for Virtual Machine Disks

Some virtualization features, such as live migration or VM snapshots, rely on your back-end storage. For example, using Red Hat Ceph Storage RBD volumes enables live migration, snapshots, and disk cloning.

For single-node clusters or clusters without a dedicated storage solution, the administrator can configure the cluster to use the local disk space of each node as persistent storage by using any of the following solutions:

  • Kubernetes hostPath volume

  • Local Storage Operator

  • LVM Storage Operator

Warning

You cannot use advanced features such as live migration when allocating your VM disks on the node disk space.

Revision: do316-4.14-d8a6b80