Kahibaro
Discord Login Register

Virtual machines (KVM/QEMU)

Understanding KVM and QEMU Together

KVM and QEMU are usually used together to provide full virtualization on Linux:

Typical stack:

$$
\text{hardware} \rightarrow \text{Linux kernel + KVM} \rightarrow \text{QEMU + libvirt} \rightarrow \text{guest VMs}
$$

Key roles:

Requirements and Basic Concepts

Hardware and Kernel Requirements

To use KVM acceleration:

Check if the CPU supports virtualization:

egrep -c '(vmx|svm)' /proc/cpuinfo

Non-zero output suggests virtualization features exist.

Check if KVM devices are present:

lsmod | grep kvm
ls -l /dev/kvm

If /dev/kvm exists and permissions are appropriate, KVM acceleration can be used by QEMU.

QEMU Modes: TCG vs KVM

QEMU operates in two major modes:

QEMU switches to KVM mode using options like -enable-kvm and a CPU type like -cpu host (details below).

Installing KVM/QEMU Tools

Names differ by distribution, but typical components are:

Example install (Debian/Ubuntu):

sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients virt-manager

Example (Fedora/RHEL-like):

sudo dnf install @virtualization virt-manager
sudo systemctl enable --now libvirtd

Confirm libvirt is running:

sudo systemctl status libvirtd

Running a Simple VM with QEMU Directly

While most production setups use libvirt and virt-manager, it’s useful to know how to start a VM with qemu-system-* directly.

Assume:

Creating a Disk Image

QEMU includes qemu-img to create and inspect disk images.

Create a 20G QCOW2 image:

qemu-img create -f qcow2 debian-12.qcow2 20G

Common formats:

Inspect an image:

qemu-img info debian-12.qcow2

Launching a Basic VM (KVM-Accelerated)

Example command:

qemu-system-x86_64 \
  -enable-kvm \
  -m 4096 \
  -cpu host \
  -smp 2 \
  -drive file=debian-12.qcow2,if=virtio,format=qcow2 \
  -cdrom debian-12.iso \
  -boot order=d \
  -display default

Key options:

Console-Only VM

To run a headless server VM using a text console:

qemu-system-x86_64 \
  -enable-kvm \
  -m 2048 \
  -cpu host \
  -smp 2 \
  -drive file=server.qcow2,if=virtio,format=qcow2 \
  -nographic \
  -serial mon:stdio

Notes:

Inside the guest, you must configure the OS to provide a login prompt on the serial console (e.g., console=ttyS0 kernel parameter and an appropriate getty).

Storage with QEMU/KVM

Disk Interfaces and Performance

Virtual disk performance depends on the interface:

VirtIO gives significantly better throughput and lower CPU overhead, but the guest OS must have VirtIO drivers (modern Linux distributions do).

Example with multiple drives:

qemu-system-x86_64 \
  -enable-kvm \
  -m 4096 \
  -drive file=os.qcow2,if=virtio,format=qcow2 \
  -drive file=data.raw,if=virtio,format=raw

Using `qemu-img` Features

Resize an image (grow only, shrinking is risky):

qemu-img resize debian-12.qcow2 +10G

Convert image formats:

qemu-img convert -f qcow2 -O raw debian-12.qcow2 debian-12.raw

Networking with QEMU/KVM

Networking configuration determines how the guest connects to the outside world.

User-Mode Networking (Simple, NAT)

Simplest option: user-mode networking (default if no NIC specified in some QEMU builds).

Example:

qemu-system-x86_64 \
  -enable-kvm \
  -m 2048 \
  -netdev user,id=net0 \
  -device virtio-net-pci,netdev=net0
-netdev user,id=net0,hostfwd=tcp::2222-:22

This forwards host port 2222 to guest port 22, allowing:

ssh -p 2222 user@localhost

Bridged Networking (VM as a Peer on LAN)

For production-like environments:

  1. Create/define a Linux bridge on the host (often via nmcli, /etc/network/interfaces, or NetworkManager).
  2. Attach host NIC and VM tap interface to the bridge.

Raw QEMU example (assuming existing br0 and manually created tap):

sudo ip tuntap add tap0 mode tap user $USER
sudo ip link set tap0 up
sudo ip link set tap0 master br0
qemu-system-x86_64 \
  -enable-kvm \
  -m 2048 \
  -netdev tap,id=net0,ifname=tap0,script=no,downscript=no \
  -device virtio-net-pci,netdev=net0

In practice, libvirt automates tap and bridge configuration via its own networks; you rarely have to manage tap interfaces by hand outside of low-level setups or containers.

Graphics and Remote Access

Display Options

Common display options:

  -display gtk     # modern, often default
  -display sdl
  -nographic
  -vnc :0

This starts a VNC server on display :0 (TCP port 5900). Connect with a VNC client to host:5900.

SPICE

SPICE provides better performance and integration for remote desktop access to VMs.

Basic usage:

qemu-system-x86_64 \
  -enable-kvm \
  -m 4096 \
  -device qxl-vga \
  -spice port=5930,disable-ticketing=on \
  -device virtio-serial-pci \
  -chardev spicevmc,id=vdagent,debug=0,name=vdagent \
  -device virtserialport,chardev=vdagent,name=com.redhat.spice.0

Connect with a SPICE client (remote-viewer spice://host:5930).
Typically, you let libvirt/virt-manager generate these options.

Managing VMs with libvirt and virt-manager (Quick Orientation)

While this chapter focuses on KVM/QEMU, a minimal orientation to the tools that wrap them is useful:

Basic checks:

virsh list --all
virsh dominfo vm-name

Creating a new VM through virt-manager will:

You can always inspect the XML for a VM to understand the underlying QEMU options:

virsh dumpxml vm-name

Tuning and Optimizing KVM/QEMU VMs

CPU and NUMA Considerations

Raw QEMU pinning is cumbersome; libvirt offers cputune, numatune, etc. in XML.

VirtIO for Network and Disk

Always prefer VirtIO devices for Linux guests unless you have special requirements:

For some non-Linux guests (e.g., Windows), you must install VirtIO drivers explicitly.

Snapshotting and Live Migration (Conceptual Overview)

KVM/QEMU support advanced lifecycle features often driven via libvirt:

Full configuration details and automation for these features are typically handled in higher-level management chapters.

Security Considerations Specific to KVM/QEMU

Minimal Hands-On Flow Summary

To cement the concepts, a concise end-to-end flow on a typical host:

  1. Install components
    • qemu-kvm, libvirt, virt-manager (or equivalents).
  2. Verify KVM
    • lsmod | grep kvm
    • ls /dev/kvm
  3. Create a VM disk
    • qemu-img create -f qcow2 vm.qcow2 20G
  4. Start a VM with QEMU manually (for learning):
   qemu-system-x86_64 \
     -enable-kvm \
     -m 4096 \
     -cpu host \
     -smp 2 \
     -drive file=vm.qcow2,if=virtio,format=qcow2 \
     -cdrom installer.iso \
     -boot order=d
  1. Later, manage VMs via libvirt/virt-manager for easier, repeatable setups.

This chapter’s focus is on how KVM and QEMU work together and how to use them directly. Higher-level management, container-specific virtualization, and orchestration aspects are handled in other chapters.

Views: 21

Comments

Please login to add a comment.

Don't have an account? Register now!