How to Convert Virtual Machine Image Formats

Introduction

When you are working with a remote cloud server, you are usually working with a virtual machine: a sandboxed, isolated instance of an entire operating system that is running within a larger server cluster. You can also work with virtual machines locally on your desktop, using software like QEMU or VirtualBox. Virtual machines may include an entire desktop interface, or they may only run an SSH server to allow terminal connections. In either case, they are technically similar, and make similar assumptions. Apart from any large-scale cloud optimizations, the only significant difference between virtualization environments is that the virtual machine hard disks and configuration options. These are referred to as virtual machine images, and are formatted differently across providers.


In this tutorial, you will learn how to convert between virtual machine image formats (including qcow2, vdi, vhd, and vmdk), so that you can take your virtual environments from your desktop to the cloud and back again as needed.


Prerequisites


The commands in this tutorial can be run on Windows, macOS, or Linux, as long as you can install QEMU and VirtualBox along with their command line tools. This tutorial provides installation instructions using the Homebrew package manager. You can install Homebrew on macOS, on Linux, or on Windows under WSL2.


If you are running on a DigitalOcean droplet, you should have at least 2 CPUs and 2GB of memory.


You will also need at least 10GB of free space to run the commands in this tutorial.



Note: If you are using macOS with an Apple Silicon CPU (manufactured in 2020 and later), you will only be able to use QEMU and not VirtualBox.



QEMU


QEMU is the most powerful and widely supported open source virtualization software. It runs on all major platforms (including Windows, macOS, Linux, and other operating systems like Android) and is capable of both virtualization and emulation as needed. For instance, if you are running a Linux server image on a Windows desktop (a common use case), both of those platforms share a common underlying architecture (Intel/AMD x86), so QEMU can achieve full performance through virtualization. If you are using QEMU to mix and match architectures, for example by running x86 Linux or Windows (as either the “host” or the “guest” operating system) with the ARM architectures of macOS or Android, QEMU will automatically use emulation to translate architectures.


Compared with virtualization, emulation is usually not used in production environments because it adds a significant performance penalty. However, QEMU treating virtualization and emulation as near-equivalent provides significant compatibility advantages, since it means that the same image formats and the same tools can be used in every scenario.


QEMU is command line software, and has a high learning curve compared to desktop virtualization software like VMware or VirtualBox due to the huge number of options that virtual machines can be configured with. It can optionally be used with GUI frontends such as QtEmu on Windows or Linux and UTM on macOS. This tutorial will provide command line instructions for working with QEMU.


Installing QEMU


To install QEMU, use Homebrew’s brew install:


brew install qemu

This will provide the entire suite of QEMU tools and commands, including qemu-img, which is used to convert virtual machine images on the command line. Verify that you have access to the qemu-img command by running which qemu-img:


which qemu-img

Output/usr/local/bin/qemu-img


Note: You can also install QEMU on Windows using its native installer, if you prefer to work on Windows without WSL2.



QEMU provides most of the functionality that you will need in this tutorial. You can also install VirtualBox, another popular virtualization package.


VirtualBox


VirtualBox is open source virtualization software provided by Oracle. It supports all x86 operating systems (Windows, Linux, and macOS computers manufactured before 2020). It does not support emulation or non-x86 architectures, making it primarily useful for running Linux under Windows and vice versa. However, it is also more straightforward to use than QEMU, provides widely compatible default settings, and includes a desktop interface by default.


It does not provide as much command line functionality as QEMU, so it is often paired with dedicated orchestration software like Vagrant to automate and reproduce virtual machine configurations. However, it does include the VBoxManage command-line tool, which can be used to manipulate some virtual machine images.


Installing VirtualBox


To install VirtualBox on macOS, use brew install with the –cask flag, because VirtualBox is distributed as a full application bundle, which Homebrew calls a cask:


brew install --cask virtualbox

To install VirtualBox on Ubuntu or Debian-derived Linux distributions (including under WSL2), first use apt update to refresh your package sources, then apt install:


sudo apt update
sudo apt install virtualbox

To install VirtualBox on Windows without WSL2, refer to its download page.


After installing VirtualBox, verify that you have access to the vboxmanage command by running which vboxmanage:


which vboxmanage

Output​​/usr/local/bin/vboxmanage

There are alternatives available to QEMU and VirtualBox for virtualization. However, most of these are platform-specific (such as Hyper-V on Windows) or designed for large-scale enterprise use (such as VMware). They will not be covered directly in this tutorial, but you will convert their image formats in the following steps.


Creating a Virtual Machine Image using QEMU


To demonstrate converting virtual machine images, you can start by creating an image with QEMU. You can skip this section if you already have an image to convert.


Use the qemu-img create command with the -f qcow2 flag to create an image in QEMU’s default qcow2 format:


qemu-img create -f qcow2 ubuntu-desktop-22.04.qcow2 10G

At this point, you will have created an empty virtual machine image. Even though you named it ubuntu-desktop-22.04.qcow2 and provided a capacity of 10G, at this point it will neither have Ubuntu 22.04 installed nor be 10GB large.


OutputFormatting 'ubuntu-desktop-22.04.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=10737418240 lazy_refcounts=off refcount_bits=16

QEMU images will always take up as little space as possible on your disk, while reflecting their maximum declared capacity to any software running within the virtual machine. In this case, 10GB would be the capacity that your virtual machine thinks it has available, and the maximum size that the virtual machine image will automatically scale up to.


A typical next step would be to install Ubuntu 22.04 onto the virtual machine, using a Ubuntu 22.04 ISO. However, you can skip this step for this tutorial, as you won’t actually be working directly with this virtual machine. An ISO is another type of disk image that is usually read-only, and was historically written onto CD and DVD installation media, rather than an image of a writable hard disk. Other software exists for manipulating ISO images, such as mkisofs and dd. To learn more about installing Linux using QEMU, refer to the QEMU documentation.


Converting a QEMU Image to Another Format


Once you’ve created a VM image, you can use qemu-img convert to convert it to other formats. vdi is the default image format of VirtualBox. By default, this will not erase the original VM image, only create a new one:


qemu-img convert -f qcow2 ubuntu-desktop-22.04.qcow2 -O vdi ubuntu-desktop-22.04.vdi

The -f flag is used to specify the input format and the input filename. The -O flag is used to specify the output format and the output filename. You can also include the -p flag to show a progress bar, which is helpful when converting very large images. The image that you created in the last step will convert instantly, because it does not have any contents yet. You can confirm that you created ubuntu-desktop-22.04.vdi using ls:


ls ubuntu-desktop-22.04.vdi

Outputubuntu-desktop-22.04.vdi

Other common formats include vmdk, used primarily by VMware, and vhd, used primarily by Microsoft’s Hyper-V. You can also create a “raw” image if your software requires it, following the next step.


Converting Other Virtual Machine Formats to QEMU


If you have an image in vdi format, you can use the vboxmanage command provided by VirtualBox to convert it:


vboxmanage clonemedium ubuntu-desktop-22.04.vdi ubuntu-desktop-22.04.img --format raw

Output0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Clone medium created in format 'raw'. UUID: 0501e707-c94e-4103-9069-d7b64a933d78

Note that this will automatically register the created image with your local VirtualBox configuration, which may be inconvenient if you are trying to create transient copies. You may have to manually remove any new entries from the VirtualBox interface if you inadvertently register duplicates.


Raw virtual machine images are not compressed at all, so this command will actually create a full 10GB file, unlike before. You can convert it back to qcow2 format for use with QEMU by reversing the syntax from the last step:


qemu-img convert -f raw ubuntu-desktop-22.04.img -O qcow2 ubuntu-desktop-22.04-new.qcow2

You can now delete the raw image to reclaim disk space:


rm ubuntu-desktop-22.04.img

Finally, you can use the qemu-img check and qemu-img info commands to output some metadata from your virtual machine images:


qemu-img check ubuntu-desktop-22.04.qcow2

OutputNo errors were found on the image.
Image end offset: 262144

qemu-img info ubuntu-desktop-22.04.qcow2

Outputimage: ubuntu-desktop-22.04.qcow2
file format: qcow2
virtual size: 10 GiB (10737418240 bytes)
disk size: 196 KiB
cluster_size: 65536
Format specific information: compat: 1.1 compression type: zlib lazy refcounts: false refcount bits: 16 corrupt: false extended l2: false

For further information on converting images with qemu-img, refer to the qemu-img manual page or its official documentation.



Note: You can also upload these Virtual Machine images to DigitalOcean to use as cloud server images, by following DigitalOcean’s Custom Image documentation



Conclusion


In this tutorial, you used QEMU and VirtualBox’s command line tools to create, convert, and export virtual machine images. You reviewed some common examples of virtual machine image formats, as well as some useful default assumptions for working with virtual machines. It’s always helpful to understand the technologies underlying common concepts like virtualization, especially if you need to migrate architectures or cloud providers.


Next, you may want to review our guide to scaling virtual machines for your needs.