You can import an existing virtual machine image into your OpenShift Container Platform cluster. Container-native virtualization uses DataVolumes to automate the import of data and the creation of an underlying PersistentVolumeClaim (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 installed on the VM. Refer to the operating system documentation for details.

Prerequisites

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 types HTTP HTTPS HTTP basic auth Registry S3 Bucket Upload

KubeVirt(QCOW2)

✓ QCOW2
✓ GZ*
✓ XZ*

✓ 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

✓ RAW*
✓ GZ*
✓ XZ*

Archive+

✓ TAR

✓ TAR

✓ TAR

□ TAR

□ TAR

□ TAR

✓ Supported operation

□ Unsupported operation

* Requires scratch space

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

+ Archive does not support block mode DVs

About DataVolumes

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

Importing a virtual machine image into a container-native virtualization object with DataVolumes

To create a virtual machine from an imported image, specify the image location in the VirtualMachine configuration file before you create the virtual machine.

Prerequisites
  • Install the OpenShift Container Platform Command-line Interface (CLI), commonly known as oc

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

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

  • At least one available PersistentVolume

Procedure
  1. Identify an HTTP file server that hosts the virtual disk image that you want to import. You need the complete URL in the correct format:

  2. If your data source requires authentication credentials, edit the endpoint-secret.yaml file, and apply the updated configuration to the cluster:

    apiVersion: v1
    kind: Secret
    metadata:
      name: <endpoint-secret>
      labels:
        app: containerized-data-importer
    type: Opaque
    data:
      accessKeyId: "" (1)
      secretKey:   "" (2)
    1 Optional: your key or user name, base64 encoded
    2 Optional: your secret or password, base64 encoded
    $ oc apply -f endpoint-secret.yaml
  3. Edit the virtual machine configuration file, specifying the data source for the image you want to import. In this example, a Fedora image is imported:

    apiVersion: kubevirt.io/v1alpha3
    kind: VirtualMachine
    metadata:
      creationTimestamp: null
      labels:
        kubevirt.io/vm: vm-fedora-datavolume
      name: vm-fedora-datavolume
    spec:
      dataVolumeTemplates:
      - metadata:
          creationTimestamp: null
          name: fedora-dv
        spec:
          pvc:
            accessModes:
            - ReadWriteOnce
            resources:
              requests:
                storage: 2Gi
            storageClassName: local
          source:
            http:
              url: https://download.fedoraproject.org/pub/fedora/linux/releases/28/Cloud/x86_64/images/Fedora-Cloud-Base-28-1.1.x86_64.qcow2 (1)
              secretRef: "" (2)
              certConfigMap: "" (3)
        status: {}
      running: false
      template:
        metadata:
          creationTimestamp: null
          labels:
            kubevirt.io/vm: vm-fedora-datavolume
        spec:
          domain:
            devices:
              disks:
              - disk:
                  bus: virtio
                name: datavolumedisk1
            machine:
              type: ""
            resources:
              requests:
                memory: 64M
          terminationGracePeriodSeconds: 0
          volumes:
          - dataVolume:
              name: fedora-dv
            name: datavolumedisk1
    status: {}
    1 The HTTP source of the image you want to import.
    2 The secretRef parameter is optional.
    3 The certConfigMap is only required if the endpoint requires authentication. The referenced ConfigMap must be in the same namespace as the DataVolume.
  4. Create the virtual machine:

    $ oc create -f vm-<name>-datavolume.yaml

    The oc create command creates the DataVolume and the virtual machine. The CDI controller creates an underlying PVC with the correct annotation, and the import process begins. When the import completes, the DataVolume status changes to Succeeded, and the virtual machine is allowed to start.

    DataVolume provisioning happens in the background, so there is no need to monitor it. You can start the virtual machine, and it will not run until the import is complete.

Optional verification steps
  1. Run oc get pods and look for the importer Pod. This Pod downloads the image from the specified URL and stores it on the provisioned PV.

  2. Monitor the DataVolume status until it shows Succeeded.

    $ oc describe dv <data-label> (1)
    1 The data label for the DataVolume specified in the virtual machine configuration file.
  3. To verify that provisioning is complete and that the VMI has started, try accessing its serial console:

    $ virtctl console <vm-fedora-datavolume>

Template: DataVolume virtual machine configuration file

example-dv-vm.yaml

apiVersion: kubevirt.io/v1alpha3
kind: VirtualMachine
metadata:
  labels:
    kubevirt.io/vm: example-vm
  name: example-vm
spec:
  dataVolumeTemplates:
  - metadata:
      name: example-dv
    spec:
      pvc:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 1G
      source:
          http:
             url: "" (1)
  running: false
  template:
    metadata:
      labels:
        kubevirt.io/vm: example-vm
    spec:
      domain:
        cpu:
          cores: 1
        devices:
          disks:
          - disk:
              bus: virtio
            name: example-dv-disk
        machine:
          type: q35
        resources:
          requests:
            memory: 1G
      terminationGracePeriodSeconds: 0
      volumes:
      - dataVolume:
          name: example-dv
        name: example-dv-disk
1 The HTTP source of the image you want to import, if applicable.

Template: DataVolume import configuration file

example-import-dv.yaml

apiVersion: cdi.kubevirt.io/v1alpha1
kind: DataVolume
metadata:
  name: "example-import-dv"
spec:
  source:
      http:
         url: "" (1)
         secretRef: "" (2)
  pvc:
    accessModes:
      - ReadWriteOnce
    resources:
      requests:
        storage: "1G"
1 The HTTP source of the image you want to import.
2 The secretRef parameter is optional.