Cloning a virtual machine disk into a new block storage data volume

You can clone the persistent volume claim (PVC) of a virtual machine disk into a new block data volume by referencing the source PVC in your data volume configuration file.

Cloning operations between different volume modes are supported, such as cloning from a persistent volume (PV) with volumeMode: Block to a PV with volumeMode: Filesystem.

However, you can only clone between different volume modes if they are of the contentType: kubevirt.

When you enable preallocation globally, or for a single data volume, the Containerized Data Importer (CDI) preallocates disk space during cloning. Preallocation enhances write performance. For more information, see Using preallocation for data volumes.

Prerequisites

About data volumes

DataVolume objects are custom resources that are provided by the Containerized Data Importer (CDI) project. Data volumes orchestrate import, clone, and upload operations that are associated with an underlying persistent volume claim (PVC). Data volumes are integrated with OKD Virtualization, and they prevent a virtual machine from being started before the PVC has been prepared.

About block persistent volumes

A block persistent volume (PV) is a PV that is backed by a raw block device. These volumes do not have a file system and can provide performance benefits for virtual machines by reducing overhead.

Raw block volumes are provisioned by specifying volumeMode: Block in the PV and persistent volume claim (PVC) specification.

Creating a local block persistent volume

Create a local block persistent volume (PV) on a node by populating a file and mounting it as a loop device. You can then reference this loop device in a PV manifest as a Block volume and use it as a block device for a virtual machine image.

Procedure

  1. Log in as root to the node on which to create the local PV. This procedure uses node01 for its examples.

  2. Create a file and populate it with null characters so that it can be used as a block device. The following example creates a file loop10 with a size of 2Gb (20 100Mb blocks):

    1. $ dd if=/dev/zero of=<loop10> bs=100M count=20
  3. Mount the loop10 file as a loop device.

    1. $ losetup </dev/loop10>d3 <loop10> (1) (2)
    1File path where the loop device is mounted.
    2The file created in the previous step to be mounted as the loop device.
  4. Create a PersistentVolume manifest that references the mounted loop device.

    1. kind: PersistentVolume
    2. apiVersion: v1
    3. metadata:
    4. name: <local-block-pv10>
    5. annotations:
    6. spec:
    7. local:
    8. path: </dev/loop10> (1)
    9. capacity:
    10. storage: <2Gi>
    11. volumeMode: Block (2)
    12. storageClassName: local (3)
    13. accessModes:
    14. - ReadWriteOnce
    15. persistentVolumeReclaimPolicy: Delete
    16. nodeAffinity:
    17. required:
    18. nodeSelectorTerms:
    19. - matchExpressions:
    20. - key: kubernetes.io/hostname
    21. operator: In
    22. values:
    23. - <node01> (4)
    1The path of the loop device on the node.
    2Specifies it is a block PV.
    3Optional: Set a storage class for the PV. If you omit it, the cluster default is used.
    4The node on which the block device was mounted.
  5. Create the block PV.

    1. # oc create -f <local-block-pv10.yaml>(1)
    1The file name of the persistent volume created in the previous step.

Cloning the persistent volume claim of a virtual machine disk into a new data volume

You can clone a persistent volume claim (PVC) of an existing virtual machine disk into a new data volume. The new data volume can then be used for a new virtual machine.

When a data volume is created independently of a virtual machine, the lifecycle of the data volume is independent of the virtual machine. If the virtual machine is deleted, neither the data volume nor its associated PVC is deleted.

Prerequisites

  • Determine the PVC of an existing virtual machine disk to use. You must power down the virtual machine that is associated with the PVC before you can clone it.

  • Install the OpenShift CLI (oc).

  • At least one available block persistent volume (PV) that is the same size as or larger than the source PVC.

Procedure

  1. Examine the virtual machine disk you want to clone to identify the name and namespace of the associated PVC.

  2. Create a YAML file for a data volume that specifies the name of the new data volume, the name and namespace of the source PVC, volumeMode: Block so that an available block PV is used, and the size of the new data volume.

    For example:

    1. apiVersion: cdi.kubevirt.io/v1beta1
    2. kind: DataVolume
    3. metadata:
    4. name: <cloner-datavolume> (1)
    5. spec:
    6. source:
    7. pvc:
    8. namespace: "<source-namespace>" (2)
    9. name: "<my-favorite-vm-disk>" (3)
    10. pvc:
    11. accessModes:
    12. - ReadWriteOnce
    13. resources:
    14. requests:
    15. storage: <2Gi> (4)
    16. volumeMode: Block (5)
    1The name of the new data volume.
    2The namespace where the source PVC exists.
    3The name of the source PVC.
    4The size of the new data volume. You must allocate enough space, or the cloning operation fails. The size must be the same as or larger than the source PVC.
    5Specifies that the destination is a block PV
  3. Start cloning the PVC by creating the data volume:

    1. $ oc create -f <cloner-datavolume>.yaml

    Data volumes prevent a virtual machine from starting before the PVC is prepared, so you can create a virtual machine that references the new data volume while the PVC clones.

CDI supported operations matrix

This matrix shows the supported CDI operations for content types against endpoints, and which of these operations requires scratch space.

Content typesHTTPHTTPSHTTP basic authRegistryUpload

KubeVirt (QCOW2)

✓ QCOW2
✓ GZ
✓ XZ

✓ QCOW2*
✓ GZ

✓ XZ

✓ QCOW2
✓ GZ
✓ XZ

✓ QCOW2
□ GZ
□ XZ

✓ QCOW2
✓ GZ

✓ XZ

KubeVirt (RAW)

✓ RAW
✓ GZ
✓ XZ

✓ RAW
✓ GZ
✓ XZ

✓ RAW
✓ GZ
✓ XZ

✓ RAW
□ GZ
□ XZ

✓ RAW
✓ GZ

✓ XZ*

✓ Supported operation

□ Unsupported operation

* Requires scratch space

** Requires scratch space if a custom certificate authority is required