Export a virtual machine
Export a virtual machine (VM) and its associated disks to import it into another cluster, or for another use case, such as forensic volume analysis.
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.
You can migrate virtual machines between OpenShift Virtualization clusters by using the Migration Toolkit for Virtualization.
Creating a VirtualMachineExport custom resource
You can create a VirtualMachineExport custom resource (CR) to export persistent volume claims (PVCs) from a VirtualMachine, VirtualMachineSnapshot, or PersistentVolumeClaim CR.
You can export the following objects:
- VM: Exports the persistent volume claims of a specified VM.
- VM snapshot: Exports PVCs contained in a
VirtualMachineSnapshotCR. - PVC: Exports a PVC. If the PVC is used by another pod, such as the
virt-launcherpod, the export remains in aPendingstate 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.
- You have installed the OpenShift CLI (
oc).
Procedure
-
Create a
VirtualMachineExportmanifest to export a volume from aVirtualMachine,VirtualMachineSnapshot, orPersistentVolumeClaimCR according to the following example and save it asexample-export.yaml.VirtualMachineExportexample:apiVersion: export.kubevirt.io/v1beta1kind: VirtualMachineExportmetadata:name: example-exportspec:source:apiGroup: "kubevirt.io"kind: VirtualMachinename: example-vmttlDuration: 1hspec.source.apiGroupdefines the API group of the resource that you want to export:- Use
"kubevirt.io"forVirtualMachine. - Use
"snapshot.kubevirt.io"forVirtualMachineSnapshot. - Use
""forPersistentVolumeClaim.
- Use
spec.source.kinddefines the data source for the export. There are three primary values used for this field:VirtualMachineVirtualMachineSnapshotPersistentVolumeClaim
spec.ttlDurationdefines the length of time before the export resource is automatically deleted. The default is 2 hours.
-
Create the
VirtualMachineExportCR:$ oc create -f example-export.yaml -
Get the
VirtualMachineExportCR:$ oc get vmexport example-export -o yamlThe internal and external links for the exported volumes are displayed in the
statusstanza:Output example:
apiVersion: export.kubevirt.io/v1beta1kind: VirtualMachineExportmetadata:name: example-exportnamespace: examplespec:source:apiGroup: ""kind: PersistentVolumeClaimname: example-pvctokenSecretRef: example-tokenstatus:conditions:- lastProbeTime: nulllastTransitionTime: "2022-06-21T14:10:09Z"reason: podReadystatus: "True"type: Ready- lastProbeTime: nulllastTransitionTime: "2022-06-21T14:09:02Z"reason: pvcBoundstatus: "True"type: PVCReadylinks:external:cert: |------BEGIN CERTIFICATE-----...-----END CERTIFICATE-----volumes:- formats:- format: rawurl: https://vmexport-proxy.test.net/api/export.kubevirt.io/v1beta1/namespaces/example/virtualmachineexports/example-export/volumes/example-disk/disk.img- format: gzipurl: https://vmexport-proxy.test.net/api/export.kubevirt.io/v1beta1/namespaces/example/virtualmachineexports/example-export/volumes/example-disk/disk.img.gzname: example-diskinternal:cert: |------BEGIN CERTIFICATE-----...-----END CERTIFICATE-----volumes:- formats:- format: rawurl: https://virt-export-example-export.example.svc/volumes/example-disk/disk.img- format: gzipurl: https://virt-export-example-export.example.svc/volumes/example-disk/disk.img.gzname: example-diskphase: ReadyserviceName: virt-export-example-exportstatus.links.externaldefines external links that are accessible from outside the cluster by using anIngressorRoute.status.links.internaldefines internal links that are valid only 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 have installed the OpenShift CLI (
oc). -
You exported a virtual machine or VM snapshot by creating a
VirtualMachineExportcustom resource (CR).noteVirtualMachineExportobjects that have thespec.source.kind: PersistentVolumeClaimparameter do not generate virtual machine manifests.
Procedure
-
To access the manifests, you must first copy the certificates from the source cluster to the target cluster.
-
Log in to the source cluster.
-
Save the certificates to the
cacert.crtfile by running the following command:$ oc get vmexport <export_name> -o jsonpath={.status.links.external.cert} > cacert.crtReplace
<export_name>with themetadata.namevalue from theVirtualMachineExportobject. -
Copy the
cacert.crtfile to the target cluster.
-
-
Decode the token in the source cluster and save it to the
token_decodefile by running the following command:$ oc get secret export-token-<export_name> -o jsonpath={.data.token} | base64 --decode > token_decodeReplace
<export_name>with themetadata.namevalue from theVirtualMachineExportobject. -
Copy the
token_decodefile to the target cluster. -
Get the
VirtualMachineExportcustom resource by running the following command:$ oc get vmexport <export_name> -o yaml -
Review the
status.linksstanza, which is divided intoexternalandinternalsections. Note themanifests.urlfields within each section, for example:apiVersion: export.kubevirt.io/v1beta1kind: VirtualMachineExportmetadata:name: example-exportspec:source:apiGroup: "kubevirt.io"kind: VirtualMachinename: example-vmtokenSecretRef: example-tokenstatus:#...links:external:#...manifests:- type: allurl: https://vmexport-proxy.test.net/api/export.kubevirt.io/v1beta1/namespaces/example/virtualmachineexports/example-export/external/manifests/all- type: auth-header-secreturl: https://vmexport-proxy.test.net/api/export.kubevirt.io/v1beta1/namespaces/example/virtualmachineexports/example-export/external/manifests/secretinternal:#...manifests:- type: allurl: https://virt-export-export-pvc.default.svc/internal/manifests/all- type: auth-header-secreturl: https://virt-export-export-pvc.default.svc/internal/manifests/secretphase: ReadyserviceName: virt-export-example-exportstatus.links.external.manifests.urlwhere thetypeisallcontains theVirtualMachinemanifest,DataVolumemanifest, if present, and aConfigMapmanifest that contains the public certificate for the external URL’s ingress or route.status.links.external.manifests.urlwhere thetypeisauth-header-secretcontains a secret containing a header that is compatible with Containerized Data Importer (CDI). The header contains a text version of the export token.
-
Log in to the target cluster.
-
Get the
Secretmanifest by running the following command:$ curl --cacert cacert.crt <secret_manifest_url> -H \"x-kubevirt-export-token:token_decode" -H \"Accept:application/yaml"-
Replace
<secret_manifest_url>with anauth-header-secretURL from theVirtualMachineExportYAML output. -
Reference the
token_decodefile that you created earlier. For example:$ curl --cacert cacert.crt https://vmexport-proxy.test.net/api/export.kubevirt.io/v1beta1/namespaces/example/virtualmachineexports/example-export/external/manifests/secret -H "x-kubevirt-export-token:token_decode" -H "Accept:application/yaml"
-
-
Get the manifests of
type: all, such as theConfigMapandVirtualMachinemanifests, by running the following command:$ curl --cacert cacert.crt <all_manifest_url> -H \"x-kubevirt-export-token:token_decode" -H \"Accept:application/yaml"-
Replace
<all_manifest_url>with a URL from theVirtualMachineExportYAML output. -
Reference the
token_decodefile that you created earlier. For example:$ curl --cacert cacert.crt https://vmexport-proxy.test.net/api/export.kubevirt.io/v1beta1/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
ConfigMapandVirtualMachineobjects on the target cluster by using the exported manifests.
Additional resources