Qemu(+KVM) is a powerful virtualization solution for linux oses. KVM (Kernel based Virtual Machine) is a module built into the linux kernel that provides it virtualization capabilities. Qemu is a hardware emulator that uses kvm to provides all necessary features to create and launch virtual machines with guest operating systems.
The other more commonly used virtualization solution is virtualbox which is an all gui solution and allows to easily create and manage virtual machine and supports all major operating systems as guest.
However, Qemu+KVM has a much smaller footprint and is lightweight compared to virtualbox without much compromise on features.
In a previous post we saw how to boot Ubuntu live iso with Qemu: How to Boot Ubuntu 23.04 Live ISO with Qemu/KVM on Ubuntu Host
In this article we shall take a look at how to create a virtual disk using qemu and then install Ubuntu as guest os in it. In our current setup we are using Kubuntu 23.04 as the host os and Ubuntu 23.04 will be installed as the guest os.
Qemu Version on our host system:
$ qemu-system-x86_64 -version QEMU emulator version 7.2.0 (Debian 1:7.2+dfsg-5ubuntu2) Copyright (c) 2003-2022 Fabrice Bellard and the QEMU Project developers enlightened@enlightened:~$
Create Virtual Disk
The first step is to create a virtual disk, where the guest os will be installed. The file format of the virtual disk is is "qcow" (Qemu copy-on-write v2). The qemu-img command is used like this:
qemu-img create -f qcow2 ubuntu2304.qcow 20G
It takes only a few seconds to finish.
$ qemu-img create -f qcow2 ubuntu2304.qcow 20G Formatting 'ubuntu2304.qcow', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=21474836480 lazy_refcounts=off refcount_bits=16 $
Boot ISO with virtual disk attached
Boot with the cdrom iso and the virtual disk attached. So that we can install from the live boot session. Here is the command
qemu-system-x86_64 --enable-kvm -cpu host -smp 4 -m 4096 -device virtio-vga -boot d -cdrom ubuntu-23.04-desktop-amd64.iso -drive file=ubuntu2304.qcow,format=qcow2
Before installation check that your virtual disk is being seen by qemu. In the live ubuntu guest session run the lsblk command as shown below. Note the 20G ATA sda drive which we just created using the qemu-img command.
ubuntu@ubuntu:~$ lsblk -e7 -o "NAME,PTTYPE,FSTYPE,SIZE,LABEL,PARTLABEL,PATH,PHY-SEC,VENDOR" NAME PTTYPE FSTYPE SIZE LABEL PARTLABEL PATH PHY-SEC VENDOR fd0 4K /dev/fd0 512 sda 20G /dev/sda 512 ATA sr0 PMBR iso9660 4.6G Ubuntu 23.04 amd64 /dev/sr0 2048 QEMU ubuntu@ubuntu:~$
The 20G sda virtual disk is where the ubuntu guest shall be installed.
Run the Installation
Now click on Install Ubuntu and follow the process to install Ubuntu as you would normally do on any desktop. We shall not be elaborating this part in much detail, and expect you to know what to do and how.
Once the installation process is complete, shutdown the system.
Boot into installed Guest
Now we can finally boot into the installed guest using the virtual disk file. Note that we shall not be attaching the cdrom iso anymore as we don't need it after the installation is complete.
qemu-system-x86_64 --enable-kvm -cpu host -smp 4 -m 4096 -vga virtio -boot c -drive file=ubuntu2304.qcow,format=qcow2
If all goes fine you should be presented with the Ubuntu desktop ready for work.
Check configurations
Once we have booted installed ubuntu we can check couple of things to understand how the qemu system is setup and configured.
Checking the file systems: We can check the file systems in use with the df command. The output shows that about 10GB out of the 20GB space has been used by ubuntu for installation.
silver@silverqemukvm:~$ df -h Filesystem Size Used Avail Use% Mounted on tmpfs 390M 1.5M 389M 1% /run /dev/sda2 20G 9.9G 8.7G 54% / tmpfs 2.0G 0 2.0G 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 390M 168K 390M 1% /run/user/1000 silver@silverqemukvm:~$
PCI Devices: Check the output of lspci for emulated hardware details.
silver@silverqemukvm:~$ lspci 00:00.0 Host bridge: Intel Corporation 440FX - 82441FX PMC [Natoma] (rev 02) 00:01.0 ISA bridge: Intel Corporation 82371SB PIIX3 ISA [Natoma/Triton II] 00:01.1 IDE interface: Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II] 00:01.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 03) 00:02.0 Ethernet controller: Intel Corporation 82540EM Gigabit Ethernet Controller (rev 03) 00:03.0 VGA compatible controller: Red Hat, Inc. Virtio GPU (rev 01) silver@silverqemukvm:~$
Video Device (VGA)
silver@silverqemukvm:~$ lspci -vnn | grep -i vga -A 12 00:03.0 VGA compatible controller [0300]: Red Hat, Inc. Virtio GPU [1af4:1050] (rev 01) (prog-if 00 [VGA controller]) Subsystem: Red Hat, Inc. Virtio GPU [1af4:1100] Flags: bus master, fast devsel, latency 0, IRQ 11 Memory at fe000000 (32-bit, prefetchable) [size=8M] Memory at fe800000 (64-bit, prefetchable) [size=16K] Memory at febb0000 (32-bit, non-prefetchable) [size=4K] Expansion ROM at 000c0000 [disabled] [size=128K] Capabilities: <access denied> Kernel driver in use: virtio-pci silver@silverqemukvm:~$
Network Configuration: According to ifconfig output the network adapter is in NAT mode, which gives it an ip not on the same subnet as the host or lan router. This makes it difficult to access the device from ssh, unless some other settings are used.
The guest os can access the internet fine, but there is no way for the host os to communicate with the guest os through networking, unless bridge network or port forwarding is configured.
silver@silverqemukvm:~$ ifconfig ens2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.0.2.15 netmask 255.255.255.0 broadcast 10.0.2.255 inet6 fec0::dbed:bcb8:ecb8:4ad6 prefixlen 64 scopeid 0x40<site> inet6 fec0::4c0e:69b4:cab2:90e8 prefixlen 64 scopeid 0x40<site> inet6 fe80::e0c6:1ce6:e461:81aa prefixlen 64 scopeid 0x20<link> ether 52:54:00:12:34:56 txqueuelen 1000 (Ethernet) RX packets 27092 bytes 28884455 (28.8 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 12249 bytes 1540180 (1.5 MB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 1477 bytes 185623 (185.6 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1477 bytes 185623 (185.6 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 silver@silverqemukvm:~$
OpenGL: The opengl renderer is Mesa llvmpipe which indicates software based emulation of opengl and no gpu driver available.
silver@silverqemukvm:~$ glxinfo | grep -i opengl OpenGL vendor string: Mesa OpenGL renderer string: llvmpipe (LLVM 15.0.7, 256 bits) OpenGL core profile version string: 4.5 (Core Profile) Mesa 23.0.2 OpenGL core profile shading language version string: 4.50 OpenGL core profile context flags: (none) OpenGL core profile profile mask: core profile OpenGL core profile extensions: OpenGL version string: 4.5 (Compatibility Profile) Mesa 23.0.2 OpenGL shading language version string: 4.50 OpenGL context flags: (none) OpenGL profile mask: compatibility profile OpenGL extensions: OpenGL ES profile version string: OpenGL ES 3.2 Mesa 23.0.2 OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20 OpenGL ES profile extensions: silver@silverqemukvm:~$
Post Installation
After the installation is complete you would need to update all packages first before you can install anything:
sudo apt update && sudo apt dist-upgrade -y
Now you can proceed with installation of needed packages.
Host OS Details
Here are the details of the host os kernel version.
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 23.04 Release: 23.04 Codename: lunar $
Kernel version:
$ uname -a Linux enlightened 6.2.0-20-generic #20-Ubuntu SMP PREEMPT_DYNAMIC Thu Apr 6 07:48:48 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux $
Conclusion
The qemu supports native resolution for the guest operating system very easily. However other features like shared clipboard, drag and drop are a bit more difficult to get to work. We shall be covering those features in future articles.
In this article we used only command line tools to create and setup the virtual machines. If you want a gui tool look at virt-manager which uses libvirt to create and manage qemu virtual machines and provides an easy user interface similar to virtualbox.
Links and Resources
https://manpages.debian.org/testing/qemu-system-x86/qemu-system-x86_64.1.en.html
https://www.dedoimedo.com/computers/qemu-virgil.html