Exporting virtual machines

You can export a virtual machine (VM) and its associated disks in order to import a VM into another cluster or to analyze the volume for forensic purposes.

You create a VirtualMachineExport custom resource (CR) by using the command line interface.

Alternatively, you can use the virtctl vmexport command to create a VirtualMachineExport CR and to download exported volumes.

Creating a VirtualMachineExport custom resource

You can create a VirtualMachineExport custom resource (CR) to export the following objects:

  • Virtual machine (VM): Exports the persistent volume claims (PVCs) of a specified VM.

  • VM snapshot: Exports PVCs contained in a VirtualMachineSnapshot CR.

  • PVC: Exports a PVC. If the PVC is used by another pod, such as the virt-launcher pod, the export remains in a Pending state until the PVC is no longer in use.

The VirtualMachineExport CR creates internal and external links for the exported volumes. Internal links are valid within the cluster. External links can be accessed by using an Ingress or Route.

The export server supports the following file formats:

  • raw: Raw disk image file.

  • gzip: Compressed disk image file.

  • dir: PVC directory and files.

  • tar.gz: Compressed PVC file.

Prerequisites

  • The VM must be shut down for a VM export.

Procedure

  1. Create a VirtualMachineExport manifest to export a volume from a VirtualMachine, VirtualMachineSnapshot, or PersistentVolumeClaim CR according to the following example and save it as example-export.yaml:

    VirtualMachineExport example

    1. apiVersion: export.kubevirt.io/v1alpha1
    2. kind: VirtualMachineExport
    3. metadata:
    4. name: example-export
    5. spec:
    6. source:
    7. apiGroup: "kubevirt.io" (1)
    8. kind: VirtualMachine (2)
    9. name: example-vm
    10. ttlDuration: 1h (3)
    1Specify the appropriate API group:
    • “kubevirt.io” for VirtualMachine.

    • “snapshot.kubevirt.io” for VirtualMachineSnapshot.

    • “” for PersistentVolumeClaim.

    2Specify VirtualMachine, VirtualMachineSnapshot, or PersistentVolumeClaim.
    3Optional. The default duration is 2 hours.
  2. Create the VirtualMachineExport CR:

    1. $ oc create -f example-export.yaml
  3. Get the VirtualMachineExport CR:

    1. $ oc get vmexport example-export -o yaml

    The internal and external links for the exported volumes are displayed in the status stanza:

    Output example

    1. apiVersion: export.kubevirt.io/v1alpha1
    2. kind: VirtualMachineExport
    3. metadata:
    4. name: example-export
    5. namespace: example
    6. spec:
    7. source:
    8. apiGroup: ""
    9. kind: PersistentVolumeClaim
    10. name: example-pvc
    11. tokenSecretRef: example-token
    12. status:
    13. conditions:
    14. - lastProbeTime: null
    15. lastTransitionTime: "2022-06-21T14:10:09Z"
    16. reason: podReady
    17. status: "True"
    18. type: Ready
    19. - lastProbeTime: null
    20. lastTransitionTime: "2022-06-21T14:09:02Z"
    21. reason: pvcBound
    22. status: "True"
    23. type: PVCReady
    24. links:
    25. external: (1)
    26. cert: |-
    27. -----BEGIN CERTIFICATE-----
    28. ...
    29. -----END CERTIFICATE-----
    30. volumes:
    31. - formats:
    32. - format: raw
    33. url: https://vmexport-proxy.test.net/api/export.kubevirt.io/v1alpha1/namespaces/example/virtualmachineexports/example-export/volumes/example-disk/disk.img
    34. - format: gzip
    35. url: https://vmexport-proxy.test.net/api/export.kubevirt.io/v1alpha1/namespaces/example/virtualmachineexports/example-export/volumes/example-disk/disk.img.gz
    36. name: example-disk
    37. internal: (2)
    38. cert: |-
    39. -----BEGIN CERTIFICATE-----
    40. ...
    41. -----END CERTIFICATE-----
    42. volumes:
    43. - formats:
    44. - format: raw
    45. url: https://virt-export-example-export.example.svc/volumes/example-disk/disk.img
    46. - format: gzip
    47. url: https://virt-export-example-export.example.svc/volumes/example-disk/disk.img.gz
    48. name: example-disk
    49. phase: Ready
    50. serviceName: virt-export-example-export
    1External links are accessible from outside the cluster by using an Ingress or Route.
    2Internal links are only valid inside the cluster.

Accessing exported virtual machine manifests

After you export a virtual machine (VM) or snapshot, you can get the VirtualMachine manifest and related information from the export server.

Prerequisites

  • You exported a virtual machine or VM snapshot by creating a VirtualMachineExport custom resource (CR).

    VirtualMachineExport objects that have the spec.source.kind: PersistentVolumeClaim parameter do not generate virtual machine manifests.

Procedure

  1. To access the manifests, you must first copy the certificates from the source cluster to the target cluster.

    1. Log in to the source cluster.

    2. Save the certificates to the cacert.crt file by running the following command:

      1. $ oc get vmexport <export_name> -o jsonpath={.status.links.external.cert} > cacert.crt (1)
      1Replace <export_name> with the metadata.name value from the VirtualMachineExport object.
    3. Copy the cacert.crt file to the target cluster.

  2. Decode the token in the source cluster and save it to the token_decode file by running the following command:

    1. $ oc get secret export-token-<export_name> -o jsonpath={.data.token} | base64 --decode > token_decode (1)
    1Replace <export_name> with the metadata.name value from the VirtualMachineExport object.
  3. Copy the token_decode file to the target cluster.

  4. Get the VirtualMachineExport custom resource by running the following command:

    1. $ oc get vmexport <export_name> -o yaml
  5. Review the status.links stanza, which is divided into external and internal sections. Note the manifests.url fields within each section:

    Example output

    1. apiVersion: export.kubevirt.io/v1alpha1
    2. kind: VirtualMachineExport
    3. metadata:
    4. name: example-export
    5. spec:
    6. source:
    7. apiGroup: "kubevirt.io"
    8. kind: VirtualMachine
    9. name: example-vm
    10. tokenSecretRef: example-token
    11. status:
    12. #...
    13. links:
    14. external:
    15. #...
    16. manifests:
    17. - type: all
    18. url: https://vmexport-proxy.test.net/api/export.kubevirt.io/v1alpha1/namespaces/example/virtualmachineexports/example-export/external/manifests/all (1)
    19. - type: auth-header-secret
    20. url: https://vmexport-proxy.test.net/api/export.kubevirt.io/v1alpha1/namespaces/example/virtualmachineexports/example-export/external/manifests/secret (2)
    21. internal:
    22. #...
    23. manifests:
    24. - type: all
    25. url: https://virt-export-export-pvc.default.svc/internal/manifests/all (3)
    26. - type: auth-header-secret
    27. url: https://virt-export-export-pvc.default.svc/internal/manifests/secret
    28. phase: Ready
    29. serviceName: virt-export-example-export
    1Contains the VirtualMachine manifest, DataVolume manifest, if present, and a ConfigMap manifest that contains the public certificate for the external URL’s ingress or route.
    2Contains a secret containing a header that is compatible with Containerized Data Importer (CDI). The header contains a text version of the export token.
    3Contains the VirtualMachine manifest, DataVolume manifest, if present, and a ConfigMap manifest that contains the certificate for the internal URL’s export server.
  6. Log in to the target cluster.

  7. Get the Secret manifest by running the following command:

    1. $ curl --cacert cacert.crt <secret_manifest_url> -H \ (1)
    2. "x-kubevirt-export-token:token_decode" -H \ (2)
    3. "Accept:application/yaml"
    1Replace <secret_manifest_url> with an auth-header-secret URL from the VirtualMachineExport YAML output.
    2Reference the token_decode file that you created earlier.

    For example:

    1. $ curl --cacert cacert.crt https://vmexport-proxy.test.net/api/export.kubevirt.io/v1alpha1/namespaces/example/virtualmachineexports/example-export/external/manifests/secret -H "x-kubevirt-export-token:token_decode" -H "Accept:application/yaml"
  8. Get the manifests of type: all, such as the ConfigMap and VirtualMachine manifests, by running the following command:

    1. $ curl --cacert cacert.crt <all_manifest_url> -H \ (1)
    2. "x-kubevirt-export-token:token_decode" -H \ (2)
    3. "Accept:application/yaml"
    1Replace <all_manifest_url> with a URL from the VirtualMachineExport YAML output.
    2Reference the token_decode file that you created earlier.

    For example:

    1. $ curl --cacert cacert.crt https://vmexport-proxy.test.net/api/export.kubevirt.io/v1alpha1/namespaces/example/virtualmachineexports/example-export/external/manifests/all -H "x-kubevirt-export-token:token_decode" -H "Accept:application/yaml"

Next steps

  • You can now create the ConfigMap and VirtualMachine objects on the target cluster by using the exported manifests.

Additional resources