qemu – simplest command-line for a performant VM

TL;DR

You need to tell qemu to: use the local host CPU (rather than emulating one) and enable hypervisor mode, include a couple of CPU cores for performance, give it a hard disk and some memory and finally (after setting up a bridge network device on your host system) use a bridged network with a MAC address unique to your network. The final bit about networking requires root access – hence the sudo:

sudo qemu-system-x86_64 \
-cpu host \
-smp 2 \
-enable-kvm \
-hda disk01.qcow2 \
-m 2G \
-nic bridge,model=virtio-net-pci,mac=52:54:00:01:02:03 \
&

If you’re not worried about network performance (for most uses where your VM will mostly be making moderate out-going network accesses) you can skip the bridge and the root access (so very handy for developers without root access) and you can run the following. I include a host forward allowing you to ssh from your host to localhost:2222 to log into the VM:

qemu-system-x86_64 \
-cpu host \
-smp 2 \
-enable-kvm \
-hda disk01.qcow2 \
-m 2G \
-net nic -nic user,hostfwd=tcp::2222-:22
\
&

In (brief) detail

At current, calling “qemu-system-x86_64 --help” returns a handy 520 or so lines of short-form help / documentation – revealing at a glance the many options available to you (and that’s before you consider the emulation commands for systems other than x86).

So how many command line options do you actually need to launch a performant VM (both in terms of performance and efficiency)? Note I’m considering basic usage with a handful of VMs running on a workstation or server.

Two key performance factors are:

  1. qemu by default runs a full emulation of the virtual system and CPU (which allows a VM image to be shared between completely different underlying host platforms with little effort) however qemu also supports hooking into system hypervisor support (on linux KVM)
  2. Similarly when enabling networking by default qemu chooses a highly compatible but less performant virtual device.

For the first item – qemu needs to know to use the system CPU and to hook into the system hypervisor if possible (and I suggest at least a couple of CPU cores otherwise the in-VM performance suffers):

-cpu host -smp 2 --enable-kvm

You need a hard disk (or boot media – which can be a URL to an online resource):

-hda disk01.qcow

Some memory:

-m 2G

And finally (unless you don’t need network access!):


-nic bridge,model=virtio-net-pci,mac=52:54:00:01:02:03

In order to enable bridged networking you need to add a network bridge device and ensure tap drivers are installed, and you’ll need to run qemu as root.

Specifying a bridge means that qemu will use it’s qemu-bridge-helper utility to set up and configure a new tap device for each VM on the bridge. To allow multiple VMs to use the network ensure they are given a unique MAC address on your network. qemu VMs need to have a MAC address in the range 52:54:00:AB:00:00 – 52:54:00:AB:FF:FF.

Bridged networking is very efficient and allows the VMs to handle high-volume incoming and outgoing network traffic, but if you only need moderate volume outgoing (or really low-volume incoming) traffic you can use the slower emulated “user” device and avoid the need to run qemu as root:

-net nic -nic user,hostfwd=tcp::2222-:22

Further Reading

Leave a Reply

Your email address will not be published. Required fields are marked *