Virtual machines that use local volume storage can be moved so that they run on a specific node.

You might want to move the virtual machine to a specific node for the following reasons:

  • The current node has limitations to the local storage configuration.

  • The new node is better optimized for the workload of that virtual machine.

To move a virtual machine that uses local storage, you must clone the underlying volume by using a DataVolume. After the cloning operation is complete, you can edit the virtual machine configuration so that it uses the new DataVolume, or add the new DataVolume to another virtual machine.

Users without the cluster-admin role require additional user permissions in order to clone volumes across namespaces.

Cloning a local volume to another node

You can move a virtual machine disk so that it runs on a specific node by cloning the underlying PersistentVolumeClaim (PVC).

To ensure the virtual machine disk is cloned to the correct node, you must either create a new PersistentVolume (PV) or identify one on the correct node. Apply a unique label to the PV so that it can be referenced by the DataVolume.

The destination PV must be the same size or larger than the source PVC. If the destination PV is smaller than the source PVC, the cloning operation fails.

Prerequisites
  • The virtual machine must not be running. Power down the virtual machine before cloning the virtual machine disk.

Procedure
  1. Either create a new local PV on the node, or identify a local PV already on the node:

    • Create a local PV that includes the nodeAffinity.nodeSelectorTerms parameters. The following manifest creates a 10Gi local PV on node01.

      kind: PersistentVolume
      apiVersion: v1
      metadata:
        name: <destination-pv> (1)
        annotations:
      spec:
        accessModes:
        - ReadWriteOnce
        capacity:
          storage: 10Gi (2)
        local:
          path: /mnt/local-storage/local/disk1 (3)
        nodeAffinity:
          required:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/hostname
                operator: In
                values:
                - node01 (4)
        persistentVolumeReclaimPolicy: Delete
        storageClassName: local
        volumeMode: Filesystem
      1 The name of the PV.
      2 The size of the PV. You must allocate enough space, or the cloning operation fails. The size must be the same as or larger than the source PVC.
      3 The mount path on the node.
      4 The name of the node where you want to create the PV.
    • Identify a PV that already exists on the target node. You can identify the node where a PV is provisioned by viewing the nodeAffinity field in its configuration:

      $ oc get pv <destination-pv> -o yaml

      The following snippet shows that the PV is on node01:

      ...
      spec:
        nodeAffinity:
          required:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/hostname (1)
                operator: In
                values:
                - node01 (2)
      ...
      1 The kubernetes.io/hostname key uses the node host name to select a node.
      2 The host name of the node.
  2. Add a unique label to the PV:

    $ oc label pv <destination-pv> node=node01
  3. Create a DataVolume manifest that references the following:

    • The PVC name and namespace of the virtual machine.

    • The label you applied to the PV in the previous step.

    • The size of the destination PV.

      apiVersion: cdi.kubevirt.io/v1alpha1
      kind: DataVolume
      metadata:
        name: <clone-datavolume> (1)
      spec:
        source:
          pvc:
            name: "<source-vm-disk>" (2)
            namespace: "<source-namespace>" (3)
        pvc:
          accessModes:
            - ReadWriteOnce
          selector:
            matchLabels:
              node: node01 (4)
          resources:
            requests:
              storage: <10Gi> (5)
      1 The name of the new DataVolume.
      2 The name of the source PVC. If you do not know the PVC name, you can find it in the virtual machine configuration: spec.volumes.persistentVolumeClaim.claimName.
      3 The namespace where the source PVC exists.
      4 The label that you applied to the PV in the previous step.
      5 The size of the destination PV.
  4. Start the cloning operation by applying the DataVolume manifest to your cluster:

    $ oc apply -f <clone-datavolume.yaml>

The DataVolume clones the PVC of the virtual machine into the PV on the specific node.