In this article, I will walk you through the steps to export the KVM virtual machine disk and configurations and later import them into the same machine or into a different machine. I will also show you how to export and import KVM virtual machines with a Bash script.
Table of Contents
Introduction
Recently I switched my hypervisor from Oracle VirtualBox to KVM for its native features and performance. As far as I tested, the KVM virtual machines are running fast compared to Virtualbox VMs.
It is always important to backup your VMs periodically. So in case of any discrepancy, you can use the backup image to restore the virtual machine. Exporting and Importing KVM virtual machines is a two-step process.
- First, you have to check where the disk images are stored and copy the disk image to a backup location.
- Secondly, export the machine configurations, so they can be later used to create the domain.
Virtual Machine Definition
There are two ways to get virtual machine domain information. Either you can use the "Virsh" program or use "Virt-manager".
You can get the name of the VM from the Virt-manager or by running the following virsh
command.
$ virsh list --all Id Name State ------------------------------------ - Linux_Mint_20 shut off - mxlinux shut off - popos_21_10 shut off - rocky_linux_8 shut off - ubuntu20.04 shut off - ubuntu20.04-clone shut off
You can run the following command to view entire domain information(VM Configuration) about a particular virtual machine. This will display the result in XML format.
$ virsh dumpxml vm_name | less
$ virsh dumpxml ubuntu20.04-clone | less
You can also grab a particular machine configuration by piping it to the grep command. Let’s say if you want to view the memory allocation, then you can run the following command.
$ virsh dumpxml ubuntu20.04-clone | grep -i "MEMORY" <memory unit='KiB'>5632000</memory> <currentMemory unit='KiB'>5632000</currentMemory>
If you prefer Virt-manager, then you can grab this information in XML format by pressing the XML tab under the "show virtual hardware" section.
Virtual Machine Disk Location
The virtual machine's disks are created in qcow2
format. By default, the virtual machine disk is stored in the /var/lib/libvirt/images/
directory unless you explicitly stored the disk in a separate directory.
Run the following command to get the disk directory path.
$ virsh dumpxml ubuntu20.04-clone | grep -i "source" <source file='/var/lib/libvirt/images/ubuntu20.04-clone.qcow2'/>
From the Virt-manager, under the Overview section, check for the <disk>
section.
If you have used different paths to store the disk images and if you wish to know all the VM disk paths, then you can run the following snippet from the terminal or from the shell script.
VM_NAMES=($(virsh list --all| awk '(NR>2)' | awk '{ print $2 }')) for VM in ${VM_NAMES[@]}; do DISK_PATH=$(virsh dumpxml ${VM} | grep -i "<source file") echo "${VM} ${DISK_PATH}" done | column -t
Export Domain Information and Copy Disk
Now you know how to get the disk path and domain information, it’s time to export the domain information for a VM and copy the disk image to a different location.
To export the domain information, you can run the following "virsh dumpxml
" and store the output in an XML
file.
$ virsh dumpxml vm-name > /path/to/xm_file.xml
$ virsh dumpxml ubuntu20.04-clone > ~/Documents/ubuntu.xml
Now copy the disk image to a different place which can be used later.
$ sudo cp /var/lib/libvirt/images/ubuntu20.04-clone.qcow2 ~/Documents/
Export process is completed. It is that simple!
Heads Up: You should use sudo
or copy the disk with the root
user since the disk is owned by the root user.
Import KVM Virtual Machine
To import the KVM virtual machine, you have to define the domain from the exported XML file by running the following command.
$ virsh define --file <path-to-xml-file>
$ virsh define –file ~/Documents/ubuntu.xml
Now you can check the Virt-manager or run the virsh
command, the domain should be successfully created. You have to copy the disk image to the directory path that is defined in the XML file. In my case it is the default location /var/lib/libvirt/images/
.
$ sudo cp ~/Documents/ubuntu20.04-clone.qcow2 /var/lib/libvirt/images/
Import process is completed. Now you can start the virtual machine.
A Bash Script to Export and Import KVM Virtual Machines
I have created a bash script that will take care of exporting all the configuration and disk images. If you are interested, you can take a look at this script in my GitHub repository. Your suggestions to improve this script will be much appreciated.
#!/usr/bin/env bash # ---------------------------------------------------------------------------------------------------- # AUTHOR : KARTHICK S # PURPOSE : THIS SCRIPT WILL EXPORT/IMPORT THE CONFIG AND VM DISK. # # usage: # export function will take care of exporting the necessary for all VM. Run as "<scriptname.sh> export" # import function will take care of importing the necessary for all VM. Run as "<scriptname.sh> import" # # NOTE: Do not add trailing / for the directory when giving export and import path. #------------------------------------------------------------------------------------------------------ # Trigger the script with root user or exit. if [[ ${UID} -ne 0 ]]; then echo -e "[EXIT] - Run the script as root user or with sudo privilege..." exit fi function export_vm(){ # Get the export location. read -p "Provide the directory path where disk and config files to be exported: " EXPORT_LOCATION # Create the destination directory if not exists. [[ -d ${EXPORT_LOCATION} ]] || mkdir -p ${EXPORT_LOCATION} # Exporting the config using virsh dumpxml command. VM_NAMES=($(virsh list --all| awk '(NR>2)' | awk '{ print $2 }')) for VM in ${VM_NAMES[@]}; do virsh dumpxml ${VM} > ${EXPORT_LOCATION}/${VM}.xml done # Using rsync copy the entire directory from default location. echo -e "\n[ Copying disk images ]\n" && sudo rsync -avxp --progress /var/lib/libvirt/images ${EXPORT_LOCATION} echo -e "\n[ Exported Files ] \n" && ls -lR ${EXPORT_LOCATION} } function import_vm(){ # Get the source location. read -p "Provide the directory path where disk and config files are stored: " SOURCE_LOCATION # Throws error if directory is not available and exit. [[ -d ${SOURCE_LOCATION} ]] || { echo "Directory not available"; exit 1 ; } # Copy all the files to default disk location. echo -e "[ Copying disk images ]\n" && sudo rsync -avxp --progress ${SOURCE_LOCATION}/images /var/lib/libvirt/ if [[ $? -eq 0 ]]; then # Define VM echo -e "\n[ Defining VM ]\n" for XML_FILE in ${SOURCE_LOCATION}/*.xml; do virsh define --file ${XML_FILE} done echo -e "\n[ Imported VM List ]\n" && virsh list --all fi } case $1 in export ) export_vm ;; import ) import_vm ;; *) echo -e "USAGE : kvm_export_import.sh export - Export config and disk kvm_export_import.sh import - Define VM and copy the disk"; exit esac
Usage of this script is as follows.
You can run the following command to clone the gist from GitHub.
$ git clone https://gist.github.com/d6c671597592fe5634a39b7974bc8029.git
The script does backup(i.e. export) as well as restore(i.e restore).
Let us export the KVM virtual machine using this script like below.
$ sudo bash kvm_export_import.sh export
You have to provide the directory path where the XML file and disk image are to be copied/exported. Do not add trailing /
slash when giving export directory. It will first copy the disk image(.qcow2
) and run the "virsh dumpxml
" command to export all configurations.
The below image shows how export works.
When you pass "import
" as the argument, it will first copy the disk image to the default location /var/lib/libvirt/
and run the "virsh define
" command against all the export XML files.
$ sudo bash kvm_export_import.sh import
Conclusion
In this article I have shown you how to export the KVM virtual machine and import them into the same or different machine. Building the virtual machine from scratch is a time-consuming task. So a proper strategy to be followed to protect the images from being lost due to any situation. If you have any tricks or tips for this article we would love to hear them from you.
2 comments
You may want to give this project a try for a more advanced approach supporting incremental backups too:
https://github.com/abbbi/virtnbdbackup
Greetings ,
How do I use your script to back up only 1 virtual machine?