Deploy a Virtual Machine#
This deployment procedure is common to Windows and Linux images. It uploads the QCOW2 image that the operating-system-specific procedure prepares and deploys a VM from it.
Holoscan for Media recommends rook-ceph-block as the storage class for the uploaded source PVC and the cloned root disk of each VM.
The examples use ReadWriteMany block volumes, which match the recommended Rook Ceph configuration.
Upload the QCOW2 Image#
Upload the release image to a versioned PVC in the VM namespace:
virtctl image-upload pvc <image-pvc-name> \
--namespace=<vm-project> \
--image-path=<release-image.qcow2> \
--size=<virtual-disk-size> \
--storage-class=rook-ceph-block \
--access-mode=ReadWriteMany \
--volume-mode=block \
--insecure
Set --size to at least the virtual size that qemu-img info reports. Use the virtctl version provided for the KubeVirt environment and run it as the authenticated cluster user without sudo.
Wait for the upload to complete and verify that the PVC is Bound:
kubectl get pvc <image-pvc-name> -n <vm-project>
Create a DataSource from the Uploaded PVC#
Create image-datasource.yaml.
Set metadata.name to a versioned image name and set spec.source.pvc.name to the PVC that virtctl image-upload created:
apiVersion: cdi.kubevirt.io/v1beta1
kind: DataSource
metadata:
name: <image-datasource>
namespace: <vm-project>
spec:
source:
pvc:
name: <uploaded-image-pvc>
namespace: <vm-project>
Create and verify the DataSource:
kubectl apply -f image-datasource.yaml
kubectl get datasource <image-datasource> -n <vm-project>
The DataSource is the stable reference to the versioned source image. Create a new PVC and DataSource name for each image release instead of replacing a source that existing deployments use.
Create a VM from the DataSource#
Create virtual-machine.yaml.
The dataVolumeTemplates entry clones the DataSource into a dedicated writable root disk for the VM:
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: <vm-name>
namespace: <vm-project>
labels:
app: <application-name>
spec:
runStrategy: Manual
instancetype:
kind: VirtualMachineInstancetype
name: <virtual-machine-instancetype>
preference:
kind: VirtualMachineClusterPreference
name: <operating-system-preference>
dataVolumeTemplates:
- metadata:
name: <vm-name>-rootdisk
spec:
sourceRef:
kind: DataSource
name: <image-datasource>
namespace: <vm-project>
storage:
accessModes:
- ReadWriteMany
resources:
requests:
storage: <virtual-disk-size>
storageClassName: rook-ceph-block
volumeMode: Block
template:
metadata:
labels:
app: <application-name>
kubevirt.io/domain: <vm-name>
spec:
domain:
devices:
disks:
- name: rootdisk
disk:
bus: <disk-bus>
interfaces:
- name: default
masquerade: {}
networks:
- name: default
pod: {}
volumes:
- name: rootdisk
dataVolume:
name: <vm-name>-rootdisk
Use the instance type provided for the application.
Set <operating-system-preference> to the cluster preference that matches the
image. On this cluster, windows.2k22 provides UEFI with Secure Boot, SATA,
and e1000e defaults for Windows Server 2022. Use it only for an image that
you built with that firmware and device profile. For a VirtIO-built Windows
image, use windows.2k22.virtio instead. For Linux, use the preference
matching the selected Linux image, such as ubuntu.
Set <disk-bus> to the device that you used when you built the image, such as sata or virtio.
Create and start the VM:
kubectl apply -f virtual-machine.yaml
kubectl get datavolume <vm-name>-rootdisk -n <vm-project> --watch
virtctl start <vm-name> -n <vm-project>
kubectl get vm,vmi <vm-name> -n <vm-project>
Wait for the cloned DataVolume phase to become Succeeded before starting the VM.
To create another Windows or Linux VM from the same image, use unique VM and root-disk names while keeping sourceRef.name set to the same DataSource.