libvirt qemu VMs

Cover Image for libvirt qemu VMs
ndom91

4 min read

With a fresh desktop linux install, I wanted to avoid installing VirtualBox again and finally learn how to setup a KVM VM with tools such as qemu and libvirt.

libvirt is a management tool that can be used to talk to hypervisors such as qemu. This simplifies working with qemu - the actual tool which does the hardware emulation.

Just like the GUI based VM creation process, we're going to go through many of the same steps here.

  1. Create a Disk
  2. Create a Network Interface
  3. Start the VM
  4. Install the OS
  5. Profit

So lets get started..

Setup

  1. Dependencies.

No matter which distro you're on, you'll want to install a few packages. On arch we're going to execute:

yay qemu libvirt virt-install

I believe the packages have the same name in the Debian / Ubuntu world, so just replace yay with sudo apt install.

  1. Create Disk

First we have to create a disk image for the OS to install into. The following command will create a qcow2 image of 15gb. QCOW2 is the default storage format for virtual disks in the qemu world and stands for "QEMU Copy-on-write". This second version added support for encryption and multiple snapshots. In short, qcow2 images are a representation of a fixed size block device in a file.

We're going to use the qemu-img binary which ships with qemu to generate this 15GB image at /var/lib/libvirt/images/. Feel free to adjust the path, but this is the default storage location for libvirt images.

sudo qemu-img create -o preallocation=metadata -f qcow2 /var/lib/libvirt/images/test1.qcow2 15G
  1. Create Network Interface

The easiest setup to provide a network connection to a VM is via whats known as a network bridge aka a shared physical device. Here we're going to use virsh, which ships with libvirt, to create said bridge.

First, we'll need to create a bridge definition in /var/lib/libvirt/network.

sudo vim /var/lib/libvirt/network/br10.xml

Then enter the following:

<network>
  <name>br10</name>
  <forward mode='nat'>
    <nat>
      <port start='1024' end='65535'/>
    </nat>
  </forward>
  <bridge name='br10' stp='on' delay='0'/>
  <ip address='192.168.30.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.30.50' end='192.168.30.200'/>
    </dhcp>
  </ip>
</network>

Feel free to adjust the above ip ranges, bridge name, etc.

After you've saved the file, we'll go into virsh and define the network.

sudo virsh
net-define /var/lib/libvirt/network/br10.xml
net-start br10
quit

Now if you check your available network interfaces (ip link show), you should see br10 listed among your physical interface, loopback, maybe wifi, etc.

  1. Start Installation

Finally, we can begin the installation with the disk and network interface we just created!

With virt-install, you can actually automate the entire installation process if you wanted to so as to do a completely unattended install. However, we're going to do a bog standard install today with the following command:

sudo virt-install --virt-type kvm --name ubuntu2010 --ram 2048 \
   --disk /var/lib/libvirt/images/test1.qcow2,format=qcow2 \
   --network bridge=br10 \
   --graphics vnc,listen=0.0.0.0 \
   --os-type=linux --os-variant=ubuntu20.04 \
   --cdrom=/opt/images/ubuntu-20.10-beta-desktop-amd64.iso

You'll see here we're defining a few things, the type of vm (kvm), the name (ubuntu2010), the amount of ram in mb (2048), the disk image we created earlier as well as its format, the network bridge we just created, as well as a graphics settings (in this case, start vnc and listen on 0.0.0.0). Finally, we're telling it what type of OS we're install (linux) and where to find the boot image.

There are many flags for virt-install, so I won't go over all of them here, but you can view its man page either on your system if you have it installed, or online here

  1. Using your new VM

Finally, once the install is complete and you've shut it down for the first time, you're probably wondering how do I start the VM again?! Easy!

virsh start [vm name]

# connect to the console of the vm
virsh console [vm id]

# alternatively print VNC connection string
virsh domdisplay [vm name]

You can use virt-viewer and directly connect via the qemu socket like so, virt-viewer --connect qemu:///system 7

Wrapping Up

Most things can be done through the virsh command. You can always check virsh help if you forget a command or are looking for something new.

Oh and one last thing that confused me at first in libvirt world - VMs are called 'domains' here.

Finally, if you really want a GUI to manage your VMs, you can always install virtmanager, which is a VirtualBox-like GUI on top of libvirt.

Good luck!