KVM (Kernel-based Virtual Machine) and QEMU (Quick EMUlator) are both open source virtualisation technologies that run on Linux, but they are different on the why they accomplish the same tasks.

While KVM [Link] is a Linux kernel module that makes it function as a hypervisor with the usage of hardware virtualisation features (Intel VT-x and AMD-V), QEMU is an emulator.

QEMU it is capable of emulating different architectures and peripherals as the expense of related overhead. But it also can work with KVM to take advantages of the hardware virtualisation.


KVM + QEMU

  • Install steps.
sudo apt-get update
sudo apt-get install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virt-manager -y
sudo reboot
  • Checking
egrep -c '(vmx|svm)' /proc/cpuinfo
sudo systemctl status libvirtd

Note: if it returns 0, the virtualisation must be enabled on the BIOS. The service libvirtd must be active (running). The users that will manager the VMs need to be members of libvirt and kvm groups or use sudo.

GUI Interface

nohup sudo virt-manager &

KVM

  • Listing all VMs
virsh list --all
  • Managing VMs
virsh start vmName
virsh suspend vmName
virsh resume vmName
virsh shutdown vmName
virsh destroy vmName
virsh undefine vmName
virsh console vmName
  • Snapshots of a VM
virsh snapshot-list vmName
virsh snapshot-create-as --domain vmName --name snapshotName --description "Add description or comments here."
virsh snapshot-revert vmName snapshotName
virsh snapshot-delete vmName snapshotName
  • Getting information about OS Variants.
virt-install --os-variant list
virt-install --osinfo ubuntu22.04
  • Deploying a Kali VM from an ISO with VNC and a bridged network.
virt-install --name Kali --memory 4096 --vcpus 4 --os-variant debian11 --network bridge=virbr0 --graphics vnc --cdrom kali.iso --disk size=100,format=qcow2

Note: to proceed with the installation use a VNC client from the host machine connecting to 127.0.0.1 or use SSH to port forward port 5900.

  • Connecting via VNC
virsh vncdisplay vmName

In its VM configuration file it will look like the following:

<graphics type='vnc' port='-1' autoport='yes'>
  <listen type='address'/>
</graphics>

Configure it accordingly. For example:

<graphics type='vnc' port='5900' autoport='no' tls='yes'>
  <listen type='address' address='192.168.10.10'/>
</graphics>
  • Cloning a VM
virt-clone --original vmName --name vmNameCloned --auto-clone

OR

virt-clone --original vmName --name vmNameCloned --file /var/lib/libvirt/images/vmNameCloned.qcow2
  • Configuring a VMs
virsh dominfo vmName
virsh autostart vmName
virsh edit vmName
  • Managing Networks
virsh net-list --all
virsh net-define /PATH/networkConfig.xml
virsh net-start networkName
virsh net-autostart networkName

Note: out of the box the default network might be not started and not set to auto start. And alternatively to the command line, KVM has a nice GUI called Virtual Machine Manager if you are running on a host with graphic environment.


QEMU

  • Listing all VMs

Because QEMU emulates virtual machines, each one will be shown as a separated process and can be identified and killed using htop, for example.

  • Creating a Disk
qemu-img create -f qcow2 /PATH/vmImage.qcow2 100G
  • Lunching a VM – Basic Syntax
    • [arch]
      • x86-64 for x86 64 bits.
      • i386 for x86 32 bits.
      • arch64 for ARM 64 bits.
      • arm for ARM 32 bits.
      • ppc for PowerPC.
      • more
    • [memory]
      • 2048 for explicit in megabytes (default).
      • 2G for explicit in gigabytes.
    • [cores]
      • 2 for the number of virtual cores/threads (integer).
    • [boot]
      • order=d (or just d) to first try to boot the disk.
      • menu=on will prompt a menu that will allow selecting the desired boot order.
    • -drive
      • It is the complete way or setting disks to the VM and optionally accept additional options. It is compatible with .vhd (VirtualPC), .vdi (VirtualBox), .vmdk (VMWare), and more.
      • E.g. -drive file=vmImage.qcow2 or -drive file=vmImage.img,if=ide,format=raw,cache=writeback
    • -hda, -hdb, -hdc, and so on.
      • Alternatively to the -drive, it is a short hand to sets hard disk images.
      • E.g. -hda vmImage.qcow2
    • -cdrom
      • It is used to run an installation or recovery live CD.
    • -enable-kvm -cpu host
      • Allows QEMU to use the hardware virtualisation features of KVM for better performance because it will not emulate the CPU if the Guest has the same architecture of the Host.
    • -vga virtio -display [display]
      • virtio is a paravirtualised video device.
        • vnc=127.0.0.1:0 it is strongly recommended to only bind on localhost and use an SSH tunnel to connect to. If set to bind on one or all interfaces of the Host, make sure the firewall rules as restricted appropriately.
        • sdl uses Simple DirectMedia Layer library and provides a good performance because it supports 3D emulation.
        • gtk uses GIMP Toolkit library but does not provide not optimal performance.
        • none does not display video output (headless).
    • -vga qxl
      • Uses SPICE to remote desktop and requires enabling the module by issuing sudo modprobe qxl bochs_drm.
    • -device virtio-gpu-pci
      • Check this option to “pass-through” a GPU/Video adapter placed in a PCI Express slot to the VM.
qemu-system-[arch] -m [memory] -smp [cores] -boot [boot] -hda [PATH] -cdrom [PATH] -enable-kvm -cpu host -vga virtio -display [display]
qemu-system-x86_64 -m 4G -smp 4 -boot menu=on -hda /PATH/vmImage.qcow2 -cdrom /PATH/file.iso -enable-kvm -cpu host -vga virtio -display vnc=127.0.0.1:0
qemu-system-x86_64 -m 2048 -drive file=vmImage.qcow2,format=qcow2 -netdev tap,id=net0,ifname=tap0,script=no,downscript=no -device virtio-net-pci,netdev=net0,mac=52:54:00:12:34:56
qemu-system-x86_64 -m 2G -hda vmImage.qcow2 -usb -device usb-host,hostbus=2,hostaddr=4

Note: use lsusb to find out the bus and address of the USB device you want to pass-through.

  • Managind Volumes
qemu-img info vmImage.qcow2
qemu-img resize vmImage.qcow2 +10G
qemu-img commit vmImage.qcow2
qemu-img convert -O vmdk -O qcow2 vmImage.vmdk vmImage.qcow2 
  • ARM VMs
sudo apt-get install qemu-system-arm -y
qemu-system-arm -M help
qemu-system-arm -M virt -enable-kvm -m 256 -kernel vmlinuz-3.2.0-4-virt -initrd initrd.img-3.2.0-4-virt -hda ARMvmImage.qcow2 -append "root=/dev/vda1" -netdev user,id=usernet,hostfwd=tcp::2222-:22 -device virtio-net-device,netdev=usernet

Note: managing the volumes and networks is the same for all architectures.


GUEST AGENT

  • Install
apt update && apt -y install qemu-guest-agent -y
systemctl enable qemu-guest-agent
systemctl start qemu-guest-agent

REFLECTIONS

Unless there is a reason to emulate a VM, like a different architecture for example, it is recommended to use KVM for most of the cases.