Check out this updated post which includes the details on creating default Windows Images. One of the advantages of virtualization is in its ability to allow rapid deployment of development systems for DevOps workflows. These workflows rely on stable base images that are cloned as needed by developers through a self-service interface. This article shows how to set up such a workflow on OpenShift Virtualization using the OpenShift Console to prepare a default operating system image.

Prepare the Default OS Image

A default OS image is a disk image of an installed operating system backed by a Persistent Volume Claim in the openshift-virtualization-os-images project Namespace. By default, this Namespace is readable by all users. This image is cloned to become the disk image of a VM when the VM is created. To make an existing image a default OS image, it must be cloned to the openshift-virtualization-os-images namespace.

Please note that any existing image on a PVC should be generalized before VMs are created from it. There are multiple methods of doing this. Microsoft Windows has a tool called sysprep.exe and Red Hat Enterprise Linux contains a service called cloud-init.

There are two paths to populate a default operating system image in OpenShift Virtualization, and both require administrative access (or at least write access to the openshift-virtualization-os-images Namespace.)

For images that require manual intervention to prepare (for example, Microsoft Windows images that require driver installation), a relevant virtual machine image must be set up by a regular user on the system as a Persistent Volume. It is advised to install the VirtIO drivers and guest agent plus any other common configurations and software desired. Previous blogs address this task of installing or converting a Microsoft Windows 10 virtual machine.

Operating systems that do not require additional drivers to work on KVM may be uploaded by the administrator directly into a default OS image, but they must be in QCOW2 or RAW format. If this is not the case, qemu-img may be used to convert the image from other disk formats. For a matrix of supported upload formats and sources, see the DataVolumes documentation. You will need to know the virtual expanded size of the image before uploading, and ensure your web browser accepts the certificate offered by the Containerized Data Importer (CDI) proxy in the openshift-cnv namespace. You can do this from the administrator console by browsing to Networking -> Routes and setting Project to openshift-cnv. On the cdi-uploadproxy line, click on the hyperlink under the Location column and accept (if required) the SSL certificate, ignoring any 404 errors.

Upload a Default Image From Local Disk

To upload a local QCOW2 image to a default OS image, browse to Storage -> Persistent Volume Claims and click the Create Persistent Volume Claim button then With Data upload form Use the Upload Data browser to select the QCOW2 file from local storage and check the box for Attach this data to a Virtual Machine operating system. Choose the relevant Operating System from the available choices. Notice that Namespace and Persistent Volume Claim Name become pre-populated and grayed out, indicating that they are now immutable. Enter the size for the expanded disk image and select Upload. Keep the browser tab open as instructed while the image uploads.

Cloning a Default OS Image From an Existing PVC

The process to clone the PVC into the openshift-virtualization-os-images project namespace must be done from the command line. Log into the cluster using a user account that has cluster admin privileges:

$ oc login https://api.CLUSTERNAME.CLUSTERDOMAIN:6443

Change to the openshift-virtualization-os-images project namespace:

$ oc project openshift-virtualization-os-images

Cloning the PVC into the openshift-virtualization-os-images namespace can easily be accomplished with a simple YAML file. To do this, specify the name for the newly cloned PVC, its size, and the name and Namespace of the existing PVC to clone.

The name for the newly cloned PVC should match the name stored in the system templates if one exists for the OS. A list of these can be gathered by running the following command:

$ oc -n openshift get template \
   -l template.kubevirt.io/type=base \
   -o jsonpath='{range .items[*]}{@.metadata.name}{"\t"}{@.parameters[?(@.name=="SRC_PVC_NAME")].value}{"\n"}'

The command will display the template names followed by the name it expects for its default OS image. The following output from the above command is truncated for readability:

Fedora-desktop-large-v0.11.3 fedora32
Rhel6-desktop-large-v0.11.3 rhel6
Rhel7-desktop-large-v0.11.3 rhel7
Rhel8-desktop-large-v0.11.3 rhel8
Windows-server-large-v0.12.3 win2k19
windows10-desktop-medium-v0.11.3 win10
windows2k12r2-server-large-v0.12.3 win2k12r2
Windows2k16-server-large-v0.12.3 win2k16
Windows2k19-server-large-v0.12.3 win2k19

Create a file called clone-dv.yaml and use the example below as a guide for its contents.

apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
 name: BASE_OS_IMAGE_NAME
spec:
 source:
   pvc:
     namespace: SOURCE_PROJECT
     name: SOURCE_PVC
 pvc:
   accessModes:
     - ReadWriteOnce
   resources:
     requests:
       storage: SIZE

BASE_OS_IMAGE_NAME is the name for the newly cloned DataVolume (DV). This name should match the name generated by the previous command.

SOURCE_PROJECT is the project namespace the PVC to be cloned is in.

SOURCE_PVC is the name of the PVC to be cloned.

SIZE should be at least the size of PVC to be cloned. This is the storage size that will be requested for the cloned DV.

Please note that when using the hostpath-provisioner, the size displayed for the PVC is the size of the backing storage and not of the actual PVC. The size of the PVC can be gathered by looking at the DV that created it. The following command will display the requested PVC size for the original image and should be used for SIZE.

The following file will clone a 40 Gi PVC called windows10base-rootdisk-msm9z that exists in the sandbox project and is an image of a Windows 10 VM.

apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
 name: win10
spec:
 source:
   pvc:
     namespace: sandbox
     name: windows10base-rootdisk-msm9z
 pvc:
   accessModes:
     - ReadWriteOnce
   resources:
     requests:
       storage: 40Gi

Make sure you are in the openshift-virtualization-os-images project Namespace and create the new default OS image using the yaml file:

$ oc create -f clone-dv.yaml

Note: The DataVolume resource is a powerful concept. It is capable of pulling images from a number of different sources such as an image hosted by a web server. Refer to the DataVolumes documentation for more details.

Use the oc get dv command to watch the progress of the cloning procedure. It will take a minute for the PROGRESS to change from N/A to a numeric percentage.

$ oc get dv
NAME    PHASE            PROGRESS   RESTARTS   AGE
win10   CloneScheduled   N/A                   41s

$ oc get dv
NAME    PHASE            PROGRESS   RESTARTS   AGE
win10   Succeeded        100.00%               118s

Once the PROGRESS reaches 100.00%, the PHASE will change to Succeeded. This means the cloning process is complete. The original PVC can now be deleted.

Create a Virtual Machine

Now that the default OS image is prepared and available, it can be used to create VMs. VMs can be created directly from the image or from a template. The procedures to create a VM or to define a template are identical, the only difference is selecting either the Virtual Machines tab or the Virtual Machines Templates tab under the Virtualization Workload.

Navigate to Workloads -> Virtualization. Select an appropriate project to create the VM (or template) in. We use sandbox for the project in our environment.

Click the Virtual Machines tab, or the Virtual Machines Templates tab if creating a template, and choose New with Wizard. A Create Virtual Machine window will appear. The first section is for the General configuration of the VM. Give the VM a Name.

The default OS image that was created was for Microsoft Windows 10. Select Microsoft Windows 10 (Source Available) for the Operating System. It is marked with Source Available because the default OS Image was named win10 as expected by the OS template for a Microsoft Windows 10 system.

A checkbox Clone available operating system source will appear and will be checked. With this checked, the win10 default OS image will be automatically cloned and used as the OS disk for the VM.

A Mount Windows guest tools checkbox will also appear. This can be unchecked because the guest agent and drivers should already be installed in the image.

 

Complete the remaining configuration sections as needed. In the Storage section, the source for the rootdisk will show Attach Cloned Disk. The Boot Source will automatically be set to rootdisk.

If a template was created instead of a VM, VMs can be created by navigating to Workloads -> Virtualization and selecting Create Virtual Machine after the template that was created.

 

The General section of the wizard will have the values in the Operating System, Boot Source, and Workload Profile fields grayed out. These fields are populated by the template; they are immutable and cannot be changed.

Complete the sections in the wizard to create a VM.

Whether the VM was created directly from the default OS image or from a template using a default OS image, the disk will start the cloning process after the VM is started for the first time.