Importing virtual machine images into block storage with data volumes

You can import an existing virtual machine image into your OKD cluster. OKD Virtualization uses data volumes to automate the import of data and the creation of an underlying persistent volume claim (PVC).

When you import a disk image into a PVC, the disk image is expanded to use the full storage capacity that is requested in the PVC. To use this space, the disk partitions and file system(s) in the virtual machine might need to be expanded.

The resizing procedure varies based on the operating system that is installed on the virtual machine. See the operating system documentation for details.

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.

Importing a virtual machine image into block storage by using a data volume

You can import a virtual machine image into block storage by using a data volume. You reference the data volume in a VirtualMachine manifest before you create a virtual machine.

Prerequisites

  • A virtual machine disk image in RAW, ISO, or QCOW2 format, optionally compressed by using xz or gz.

  • An HTTP or HTTPS endpoint where the image is hosted, along with any authentication credentials needed to access the data source.

Procedure

  1. If your data source requires authentication, create a Secret manifest, specifying the data source credentials, and save it as endpoint-secret.yaml:

    1. apiVersion: v1
    2. kind: Secret
    3. metadata:
    4. name: endpoint-secret (1)
    5. labels:
    6. app: containerized-data-importer
    7. type: Opaque
    8. data:
    9. accessKeyId: "" (2)
    10. secretKey: "" (3)
    1Specify the name of the Secret.
    2Specify the Base64-encoded key ID or user name.
    3Specify the Base64-encoded secret key or password.
  2. Apply the Secret manifest:

    1. $ oc apply -f endpoint-secret.yaml
  3. Create a DataVolume manifest, specifying the data source for the virtual machine image and Block for storage.volumeMode.

    1. apiVersion: cdi.kubevirt.io/v1beta1
    2. kind: DataVolume
    3. metadata:
    4. name: import-pv-datavolume (1)
    5. spec:
    6. storageClassName: local (2)
    7. source:
    8. http:
    9. url: "https://mirror.arizona.edu/fedora/linux/releases/35/Cloud/x86_64/images/Fedora-Cloud-Base-35-1.2.x86_64.qcow2" (3)
    10. secretRef: endpoint-secret (4)
    11. storage:
    12. volumeMode: Block (5)
    13. resources:
    14. requests:
    15. storage: 10Gi
    1Specify the name of the data volume.
    2Optional: Set the storage class or omit it to accept the cluster default.
    3Specify the HTTP or HTTPS URL of the image to import.
    4Specify the Secret name if you created a Secret for the data source.
    5The volume mode and access mode are detected automatically for known storage provisioners. Otherwise, specify Block.
  4. Create the data volume to import the virtual machine image:

    1. $ oc create -f import-pv-datavolume.yaml

You can reference this data volume in a VirtualMachine manifest before you create a virtual machine.

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

CDI now uses the OKD cluster-wide proxy configuration.

Additional resources