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.
Note
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.
-
The VM must be shut down for a VM export.
-
You have installed the OpenShift CLI (
oc).
-
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/v1beta1 kind: VirtualMachineExport metadata: name: example-export spec: source: apiGroup: "kubevirt.io" kind: VirtualMachine name: example-vm ttlDuration: 1h- Specify the appropriate API group:
-
"kubevirt.io"forVirtualMachine. -
"snapshot.kubevirt.io"forVirtualMachineSnapshot. -
""forPersistentVolumeClaim.
-
- Specify
VirtualMachine,VirtualMachineSnapshot, orPersistentVolumeClaim. - Optional. The default duration is 2 hours.
- Specify the appropriate API group:
-
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/v1beta1 kind: VirtualMachineExport metadata: name: example-export namespace: example spec: source: apiGroup: "" kind: PersistentVolumeClaim name: example-pvc tokenSecretRef: example-token status: conditions: - lastProbeTime: null lastTransitionTime: "2022-06-21T14:10:09Z" reason: podReady status: "True" type: Ready - lastProbeTime: null lastTransitionTime: "2022-06-21T14:09:02Z" reason: pvcBound status: "True" type: PVCReady links: external: cert: |- -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- volumes: - formats: - format: raw url: https://vmexport-proxy.test.net/api/export.kubevirt.io/v1beta1/namespaces/example/virtualmachineexports/example-export/volumes/example-disk/disk.img - format: gzip url: https://vmexport-proxy.test.net/api/export.kubevirt.io/v1beta1/namespaces/example/virtualmachineexports/example-export/volumes/example-disk/disk.img.gz name: example-disk internal: cert: |- -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- volumes: - formats: - format: raw url: https://virt-export-example-export.example.svc/volumes/example-disk/disk.img - format: gzip url: https://virt-export-example-export.example.svc/volumes/example-disk/disk.img.gz name: example-disk phase: Ready serviceName: virt-export-example-export- External links are accessible from outside the cluster by using an
IngressorRoute. - Internal links are only valid inside the cluster.
- External links are accessible from outside the cluster by using an
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.
-
You have installed the OpenShift CLI (
oc). -
You exported a virtual machine or VM snapshot by creating a
VirtualMachineExportcustom resource (CR).Note
VirtualMachineExportobjects that have thespec.source.kind: PersistentVolumeClaimparameter do not generate virtual machine manifests.
-
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/v1beta1 kind: VirtualMachineExport metadata: name: example-export spec: source: apiGroup: "kubevirt.io" kind: VirtualMachine name: example-vm tokenSecretRef: example-token status: #... links: external: #... manifests: - type: all url: https://vmexport-proxy.test.net/api/export.kubevirt.io/v1beta1/namespaces/example/virtualmachineexports/example-export/external/manifests/all - type: auth-header-secret url: https://vmexport-proxy.test.net/api/export.kubevirt.io/v1beta1/namespaces/example/virtualmachineexports/example-export/external/manifests/secret internal: #... manifests: - type: all url: https://virt-export-export-pvc.default.svc/internal/manifests/all - type: auth-header-secret url: https://virt-export-export-pvc.default.svc/internal/manifests/secret phase: Ready serviceName: virt-export-example-export-
status.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"
-
-
You can now create the
ConfigMapandVirtualMachineobjects on the target cluster by using the exported manifests.