KVM and libvirt
KVM turns the Linux kernel itself into a hypervisor using the CPU's own virtualization extensions, QEMU supplies the virtual hardware, and libvirt is the standard management layer (virsh, virt-manager) on top of both.
See Containers vs. Virtual Machines for why a VM needs a fundamentally different, heavier mechanism than a container. On Linux, that mechanism is KVM.
KVM: the kernel as hypervisor
KVM (Kernel-based Virtual Machine) is a kernel module, not a separate application - loading it turns the Linux kernel itself into a type-1 (bare-metal) hypervisor, using virtualization extensions built into the CPU (Intel VT-x or AMD-V) to run guest code directly on the physical CPU rather than emulating it in software.
egrep -c '(vmx|svm)' /proc/cpuinfo # non-zero: CPU supports hardware virtualization
lsmod | grep kvm # kvm_intel or kvm_amd should be loaded
kvm_intel 327680 0
kvm 1245184 1 kvm_intel
Without hardware virtualization support (rare on any machine from the last decade, but common inside nested cloud VMs unless explicitly enabled), KVM can't load, and virtualization falls back to pure software emulation - dramatically slower.
QEMU: the virtual hardware
KVM alone only accelerates CPU execution; it doesn't provide virtual disks, network cards, or a BIOS. QEMU supplies that: the emulated hardware a guest OS actually boots against and talks to. Used together (the overwhelmingly common setup on Linux) as "QEMU/KVM," QEMU handles device emulation while KVM accelerates the CPU-bound parts - QEMU can technically run entirely alone with no KVM, doing full software emulation, but that's orders of magnitude slower and mainly useful for emulating a different CPU architecture than the host's.
libvirt: the management layer
Neither KVM nor QEMU is pleasant to drive directly for day-to-day use. libvirt is the standard toolkit on top of both, providing a consistent API and tools regardless of the hypervisor underneath:
virsh list --all # list VMs (domains, in libvirt terms) and their state
virsh start myvm
virsh shutdown myvm # graceful ACPI shutdown
virsh destroy myvm # immediate power-off, like pulling the plug
virsh console myvm # attach to a text console
Id Name State
--------------------------
3 myvm running
virt-manager is the graphical front-end for the same underlying
libvirt API - creating VMs, adjusting resources, and getting a display
console without the command line. virt-install scripts VM creation
from the command line instead, for reproducible or automated setups:
virt-install --name myvm --memory 2048 --vcpus 2 \
--disk size=20 --cdrom /path/to/install.iso --os-variant debian12
Storage and networking
VM disks are typically stored as qcow2 image files - a copy-on-write format supporting snapshots and growing on demand, rather than pre-allocating full size up front:
qemu-img create -f qcow2 myvm.qcow2 20G
qemu-img snapshot -c before-upgrade myvm.qcow2
Networking defaults to a NAT'd virtual network (virbr0, created
automatically by libvirt) giving guests outbound access without being
directly reachable from the LAN; a bridged network instead attaches
a guest's virtual NIC to the host's physical one, making it appear as
its own device on the local network - the choice that matters if the VM
needs to be reachable from other machines directly, the way a server
normally would (see Networking Basics).
Where this fits
KVM/libvirt is what most self-hosted Linux virtualization runs on directly - and, under a different name, it's also what much of the public cloud runs on: AWS, Google Cloud, and others build their VM offerings on KVM (or a close relative) at the hypervisor layer, with their own management control planes replacing libvirt's. Desktop alternatives like VirtualBox or VMware Workstation solve the same problem with their own hypervisor stack instead of KVM, trading some of libvirt's server-oriented tooling for a friendlier standalone desktop app.