Bootable Volumes

A bootable volume is a ready-to-use boot image that virtual machines can be created from. Each bootable volume is a KubeVirt DataSource (cdi.kubevirt.io/v1beta1) backed by a PVC that CDI populates from an import or clone source. Bootable volumes are aggregated across namespaces — including the shared kube-public namespace where platform "golden images" live — so they can be reused by many virtual machines.

When you create a virtual machine and choose Provision Method > Image Instance, the picker lists the bootable volumes you can boot from.

Notes

  • A bootable volume becomes selectable for virtual-machine creation only when its DataSource carries the virtualization.cpaas.io/* label contract (operating system, architecture, capacity, storage class, volume mode, access mode). A data source without these labels still appears in the management list but is not offered in the Image Instance picker.
  • The volume's Status is Importing while CDI populates the backing PVC and Ready once it can be used.
  • Local Upload as a source is not yet supported; use HTTP/HTTPS, Registry, Clone PVC, or Clone snapshot.

View bootable volumes

Bootable volumes are backed by DataSource objects and are aggregated across namespaces (including the shared kube-public namespace). List them directly:

kubectl get datasource -A

Add a bootable volume

A bootable volume supports four source types:

Source typeWhat it doesDataVolume source
HTTP/HTTPS (default)Import a qcow2/raw image from an HTTP(S) URLhttp
RegistryPull a container disk from a container registryregistry
Clone PVCDuplicate an existing PVCpvc
Clone snapshotRestore from a VolumeSnapshotsnapshot

Note: Create bootable volumes in your own project namespace. The shared kube-public namespace holds platform golden images published by a cluster administrator — ordinary project users can consume (clone and boot from) kube-public images out of the box, but creating or modifying objects in kube-public requires elevated platform permissions.

Adding a bootable volume creates two objects: a DataVolume (CDI imports the image into a PVC) and a DataSource that points at it and carries the label contract. The example imports an image over HTTP:

# 1) DataVolume — CDI imports the image into a PVC of the same name.
apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
  name: ubuntu-2204
  namespace: demo
spec:
  source:
    http:
      url: https://images.example.com/ubuntu-22.04.qcow2
      # secretRef: my-pull-secret   # for an authenticated source
  storage:
    resources:
      requests:
        storage: 20Gi
    storageClassName: sc-topolvm
    volumeMode: Filesystem
    accessModes:
      - ReadWriteOnce
---
# 2) DataSource — makes the PVC selectable as a bootable volume.
apiVersion: cdi.kubevirt.io/v1beta1
kind: DataSource
metadata:
  name: ubuntu-2204
  namespace: demo
  labels:
    virtualization.cpaas.io/image-os-type: ubuntu
    virtualization.cpaas.io/image-os-arch: amd64
    virtualization.cpaas.io/size: 20Gi
    virtualization.cpaas.io/storage-class: sc-topolvm
    virtualization.cpaas.io/volume-mode: Filesystem
    virtualization.cpaas.io/access-mode: ReadWriteOnce
    virtualization.cpaas.io/source-origin: url   # url | registry | pvc | snapshot
spec:
  source:
    pvc:
      name: ubuntu-2204
      namespace: demo

For the other source types, replace spec.source on the DataVolume:

# Registry
source:
  registry:
    url: docker://registry.example.com/library/fedora:40
# Clone an existing PVC
source:
  pvc:
    name: source-pvc
    namespace: demo
# Restore from a VolumeSnapshot
source:
  snapshot:
    name: source-snapshot
    namespace: demo

Apply and watch the import:

kubectl apply -f bootable-volume.yaml
kubectl get datavolume ubuntu-2204 -n demo -w

Create a virtual machine from a bootable volume

A virtual machine created from a bootable volume defaults to the bootable volume's namespace (a same-namespace clone).

Under the hood, the virtual machine references the data source in a dataVolumeTemplates entry — CDI clones the bootable volume into the new virtual machine's root disk:

spec:
  dataVolumeTemplates:
    - metadata:
        name: web-01-rootfs
      spec:
        sourceRef:
          kind: DataSource
          name: ubuntu-2204
          # The bootable volume's namespace. Use kube-public to boot from an
          # administrator-published golden image.
          namespace: demo
        storage:
          resources:
            requests:
              storage: 20Gi
          storageClassName: sc-topolvm
          volumeMode: Filesystem
          accessModes:
            - ReadWriteOnce

The clone source namespace is restricted to the current/target namespace and kube-public. Cloning from another non-public namespace may require additional CDI clone permissions.

Update or delete a bootable volume

Deleting a bootable volume removes its DataSource and the managed DataVolume. The backing PVC is owned by the DataVolume (via ownerReferences), so it is garbage-collected automatically when the DataVolume is deleted — do not delete the PVC while the DataVolume still exists, or CDI will re-provision it. The DataSource, DataVolume, and PVC share the same name:

kubectl delete datasource ubuntu-2204 -n demo
kubectl delete datavolume ubuntu-2204 -n demo

If CDI already garbage-collected the DataVolume after a successful import, kubectl delete datavolume returns NotFound and the PVC is left without an owner — delete it directly in that case:

kubectl delete pvc ubuntu-2204 -n demo