The commands and XML are generic examples and must be adjusted for the host version and actual resources. Network addresses use documentation ranges; choose a nonconflicting private network for real deployments. See the relevant sections for the conditions that apply to image modification and device passthrough.
1. Verifying hardware virtualization#
The installation commands in this article apply to different distributions and should not be run consecutively. On NixOS, maintain software and services through modules and Home Manager rather than directly editing /etc or dotfiles. AMD IOMMU is normally initialized by firmware and the kernel; iommu.strict=1 controls only the invalidation policy and is not an enable switch.
Before installing any software, confirm that the CPU supports hardware virtualization, the corresponding firmware extensions are enabled, and the kernel modules can load correctly.
1.1 Check CPU virtualization extensions
Intel platforms require VT-x (vmx); AMD platforms require AMD-V/SVM (svm).
# 统计 CPU 虚拟化标志位(> 0 表示支持)
egrep -c '(vmx|svm)' /proc/cpuinfoIf this returns 0, the CPU either does not support hardware virtualization or it is disabled in BIOS/UEFI.
Inspect the specific flags in more detail:
# 查看完整 flags 行
grep -E '(vmx|svm)' /proc/cpuinfo
# 使用 lscpu 查看虚拟化信息
lscpu | grep -i virtualizationExample expected output (Intel):
Virtualization: VT-xExample expected output (AMD):
Virtualization: AMD-V1.2 Additional checks with kvm-ok
kvm-ok comes from the cpu-checker package and checks both the CPU and the /dev/kvm device in one run.
# Ubuntu/Debian
sudo apt install cpu-checker
sudo kvm-ok
# Fedora
virt-host-validate qemu # Fedora 可用 libvirt 的验证工具;cpu-checker 包名不能跨发行版假定
sudo kvm-okExpected output:
INFO: /dev/kvm exists
KVM acceleration can be usedPossible failure output:
INFO: Your CPU does not support KVM extensions
KVM acceleration can NOT be used1.3 Check the KVM kernel modules
# 查看 KVM 模块是否已加载
lsmod | grep kvm
# 如果未加载,手动加载
sudo modprobe kvm # 通用 KVM 核心
sudo modprobe kvm_amd # AMD 平台
sudo modprobe kvm_intel # Intel 平台Expected output (Intel platform):
kvm_intel 385024 0
kvm 1134592 1 kvm_intelA common issue: AMD-V disabled in BIOS Some motherboards, particularly ASUS and MSI AMD boards, ship with AMD-V disabled by default. Press
Del/F2during boot to enter firmware settings, find SVM Mode under Advanced CPU Configuration, and set it to Enabled. On Linux, the following command provides a quick check:dmesg | grep -i "svm.*disabled by bios"If you see
svm: SVM disabled (by BIOS), that confirms it is disabled at the firmware level.
1.4 Check IOMMU support (a prerequisite for PCI passthrough)
If you plan to use VGA/PCI passthrough, such as GPU passthrough, also confirm IOMMU support.
# 检查 IOMMU 是否在内核日志中出现
dmesg | grep -i iommu
# 查看 IOMMU 分组
ls /sys/kernel/iommu_groups/ 2>/dev/nullOn Intel platforms, also check whether VT-d is enabled:
dmesg | grep -i "DMAR" | grep -i "IOMMU"If IOMMU is not enabled, add the following to the GRUB kernel command line:
- Intel:
intel_iommu=on - AMD: after enabling AMD-Vi in firmware, check kernel initialization and IOMMU groups;
iommu.strict=1is an optional DMA invalidation policy, not an enable switch
2. Installation guides by distribution#
The KVM virtualization stack includes the following core components:
| Component | Function | Key package name |
|---|---|---|
| KVM kernel module | CPU hardware virtualization acceleration | kvm.ko (included with the kernel) |
| QEMU | Device emulation and virtual-machine execution engine | qemu-kvm / qemu-full |
| libvirt | Virtual-machine management abstraction layer with a unified API | libvirt-daemon |
| virsh | libvirt command-line management tool | libvirt-clients |
| virt-manager | Graphical management interface (GUI) | virt-manager |
| bridge-utils | Bridge networking tools | bridge-utils |
2.1 Ubuntu 24.04+ / Debian
sudo apt update
sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients \
bridge-utils virt-manager virt-viewer qemu-utils| Package name | Description |
|---|---|
qemu-kvm |
QEMU userspace components with KVM acceleration; a virtual package that automatically pulls in the QEMU binary appropriate for the current architecture |
libvirt-daemon-system |
The libvirt system daemon and systemd service unit files; replaces the older libvirt-bin |
libvirt-clients |
Command-line clients: virsh, virt-admin, and virt-host-validate |
bridge-utils |
Provides the brctl command for manually creating Linux bridges (bridge networking) |
virt-manager |
GTK graphical management tool that manages virtual machines through the libvirt API |
virt-viewer |
SPICE/VNC console viewer (the virt-viewer command), a lightweight alternative |
qemu-utils |
Provides utilities such as qemu-img for creating/converting disk images and qemu-io for I/O testing |
Optional but recommended additional packages:
sudo apt install libguestfs-tools virt-top ovmflibguestfs-tools: guest disk tools such asvirt-builderandvirt-resizevirt-top: real-time virtual-machine resource monitoring, similar totopovmf: UEFI firmware for creating virtual machines that boot with UEFI
2.2 Fedora
# 方式一:安装 @virtualization 组(推荐,一键安装全部相关包)
sudo dnf install @virtualization
# 方式二:手动按需安装
sudo dnf install qemu-kvm libvirt-daemon libvirt-client \
virt-manager virt-viewer bridge-utilsAbout the Fedora package group The
@virtualizationgroup includes qemu-kvm, libvirt-daemon, virt-manager, virt-viewer, edk2-ovmf, guestfs-tools, and other packages. It is Fedora's officially recommended installation method. Compared with installing packages manually, the group ensures correct dependencies and matching versions.
On Fedora, libvirt uses the modular daemon architecture by default; see 02_Installation_and_Setup.
2.3 Arch Linux
sudo pacman -S qemu-full virt-manager virt-viewer libvirt \
dnsmasq edk2-ovmf swtpm iptables-nft| Package name | Description |
|---|---|
qemu-full |
The complete QEMU package, including all system emulators, such as qemu-system-x86_64 and qemu-system-aarch64. If you only need x86_64 virtualization, you can use qemu-base instead, but this is not recommended because it is too limited. |
virt-manager |
Graphical management interface |
virt-viewer |
SPICE/VNC console |
libvirt |
Main package, including the libvirtd daemon |
dnsmasq |
DHCP/DNS service required by libvirt NAT virtual networks, such as the default network |
edk2-ovmf |
UEFI firmware (OVMF), required for creating UEFI virtual machines |
swtpm |
TPM 2.0 emulator. Required for Windows 11 installation: Win11 requires TPM 2.0, and without swtpm it cannot pass the installation checks. |
iptables-nft |
Tools used by the iptables-compatible backend; newer libvirt versions also support native nftables. Check the actual version, network firewall_backend, and distribution defaults. |
Optional packages:
sudo pacman -S dmidecode guestfs-tools virt-topqemu-full vs qemu-base vs qemu-desktop
qemu-base: includes onlyqemu-system-x86_64, suitable for minimal setupsqemu-desktop: includes x86_64 and common UI backends (SPICE, OpenGL), suitable for desktop usersqemu-full: includes QEMU emulators for all architectures; recommended for development/experimental environments to avoid repeated compilation later because an emulator is missing
2.4 openSUSE
# 安装 KVM 服务器模式(含 libvirt、QEMU、virt-manager)
sudo zypper install -t pattern kvm_server
# 补充图形管理界面(若 pattern 未包含)
sudo zypper install virt-manageropenSUSE's kvm_server pattern installs the complete KVM virtualization stack; the kvm_tools pattern provides additional guest-management tools and can be installed as needed.
2.5 Basic post-installation checks
Regardless of distribution, run the following commands after installation to confirm that the components are in place:
# 检查 QEMU 版本和可用架构
qemu-system-x86_64 --version
# 检查 libvirt 版本
virsh --version
# 检查 virt-manager 是否可启动
virt-manager --version
# 运行 libvirt 宿主机验证
virt-host-validate qemuvirt-host-validate checks IOMMU, CPU extensions, device permissions, and other items individually, marking each PASS/FAIL/WARN.
3. User and permission configuration#
libvirt controls access through UNIX sockets and PolicyKit. To let a non-root user manage virtual machines, add that user to the corresponding UNIX groups.
3.1 Add the user to the virtualization groups
# 将当前用户加入 libvirt 和 kvm 组
sudo usermod -aG libvirt,kvm $USER| Group name | Permission scope |
|---|---|
libvirt |
Allows management of virtual machines, networks, and storage pools through the libvirt socket (/var/run/libvirt/libvirt-sock) |
kvm |
Allows access to the /dev/kvm device node to run QEMU processes with KVM acceleration |
3.2 Make group changes take effect
usermod -aG changes the group membership loaded when a user logs in; existing shell sessions do not automatically inherit the new groups.
# 方式一:在当前 shell 临时生效(仅影响此 shell 及其子进程)
newgrp libvirt
# 方式二:登出后重新登录(永久生效,推荐)
# 注销当前桌面会话并重新登录
# 方式三:重启系统(最彻底)
sudo rebootGroup changes must take effect If you run
virsh list --allbefore the group changes take effect, you will receiveFailed to connect to the hypervisororPermission denied. Make sure the current session has membership in thelibvirtgroup.
3.3 Verify permissions
# 确认当前用户已加入目标组
id -nG | grep -E 'libvirt|kvm'
# 期望输出中包含 libvirt 和 kvm
# 示例: user adm cdrom sudo dip plugdev libvirt kvm docker
# 测试 libvirt 连接(不应需要 sudo)
virsh list --all
# 期望输出
# Id Name State
# --------------------If virsh list --all runs without sudo and returns an empty list, the permissions are configured correctly.
4. Managing the libvirtd service#
4.1 Start and enable
# 启动并设为开机自启(一次性操作)
sudo systemctl enable --now libvirtd
# 检查运行状态
sudo systemctl status libvirtdKey expected output line:
Active: active (running) since ...Socket activation On most distributions, libvirtd is configured to be socket-activated by default. This means that
systemctl status libvirtdmay show eitheractive (running)orinactive (dead), and both can be normal:
- When no clients are connected, libvirtd may be idle
- When
virshorvirt-managerinitiates a connection, systemd automatically starts libvirtd through the socketCheck the socket state to confirm that the service is ready:
systemctl status libvirtd.socket libvirtd-ro.socket libvirtd-admin.socket
4.2 The modular daemon architecture
In modern distributions (Fedora 35+, Ubuntu 24.04+, Arch Linux), libvirt has been split from a monolithic libvirtd into multiple specialized daemons:
| Traditional daemon | Modern modular replacement | Responsibility |
|---|---|---|
libvirtd (monolithic) |
virtqemud |
QEMU/KVM virtual-machine management |
virtnetworkd |
Virtual network management (NAT, bridge, DHCP) | |
virtstoraged |
Storage pool management (dir, LVM, iSCSI, and others) | |
virtnodedevd |
Host device management (PCI, USB, and others) | |
virtsecretd |
Key/password management (Ceph, iSCSI CHAP, and others) | |
virtinterfaced |
Host network interface management | |
virtproxyd |
Unified proxy entry point that routes requests to the appropriate module |
Check which architecture is in use:
# 查看模块化 daemon 是否在运行
systemctl status virtqemud virtnetworkd virtstoraged 2>/dev/null
# 查看 libvirt 连接 URI(会显示使用哪个 daemon)
virsh uri- With the modular architecture,
virsh urioutputsqemu:///system, which is actually handled byvirtqemud - The monolithic architecture also outputs
qemu:///system, but it is handled bylibvirtd
From the user's perspective, virsh and virt-manager make exactly the same API calls with either architecture; the difference is transparent.
4.3 Troubleshooting service failures
# 查看 libvirtd 日志
sudo journalctl -u libvirtd -f
# 查看模块化 daemon 日志
sudo journalctl -u virtqemud -f
# 检查配置文件语法
sudo virt-host-validate qemu
# 查看 systemd 托管服务的日志;避免重复 daemon
journalctl -u libvirtd -b # 检查已托管 daemon 的日志,不另起第二个实例5. Default network configuration#
After installation, libvirt automatically creates a NAT virtual network named default, using the virbr0 bridge.
5.1 Network parameters
| Parameter | Value |
|---|---|
| Network name | default |
| Bridge interface | virbr0 |
| Network address | 192.0.2.0/24 |
| DHCP address pool | 192.0.2.2 - 192.0.2.254 |
| Host IP (on this network) | 192.0.2.1 |
| DNS/DHCP service | dnsmasq (automatically managed by libvirt) |
5.2 Manage the default network
# 启动 default 网络
sudo virsh net-start default
# 设为自动启动(宿主机开机后自动创建)
sudo virsh net-autostart default
# 查看所有虚拟网络
virsh net-list --all
# 期望输出:
# 名称 状态 自动启动 持久
# -------------------------------------------
# default 活跃 是 是
# 查看 virbr0 网桥接口
ip addr show virbr0
# 查看 DHCP 租约
virsh net-dhcp-leases default5.3 Restore a missing network
If the default network was accidentally deleted or was never created:
# 从 libvirt 默认网络 XML 模板重新定义
sudo virsh net-define /usr/share/libvirt/networks/default.xml
# 启动并设为自启
sudo virsh net-start default
sudo virsh net-autostart defaultThe location of default.xml may vary slightly by distribution:
- Debian/Ubuntu:
/usr/share/libvirt/networks/default.xml - Fedora:
/usr/share/libvirt/networks/default.xml - Arch:
/etc/libvirt/qemu/networks/default.xml
5.4 Understanding NAT network communication
graph LR
VM[虚拟机 / 192.0.2.x] -->|eth0| Bridge[virbr0 / 192.0.2.1]
Bridge -->|NAT/Masquerade| Host[宿主机物理网卡 / enpXsY]
Host -->|路由| LAN[外部网络/互联网]- Outbound from a virtual machine: traffic is translated by NAT and leaves through the host's physical NIC; the host must have IP forwarding enabled
- Host to virtual machine: the host can directly ping
192.0.2.x - External access to a virtual machine: configure port forwarding on the host or use bridged networking; see Advanced Network Configuration
Verify that IP forwarding is enabled KVM NAT networking depends on the host's IP forwarding. Check its status:
sysctl net.ipv4.ip_forward # 期望: net.ipv4.ip_forward = 1If the value is 0, libvirt normally enables it automatically when starting the default network. However, disabling it manually may prevent virtual machines from reaching external networks.
6. Verifying the installation#
This section uses CirrOS 0.6.2, a historical smoke-test image; the x86_64 disk file listed in the official directory is approximately 20 MiB. MD5SUMS can check only for accidental transfer corruption, not provide strong source authentication. Check the signatures and strong-checksum chain available for the actual release. Do not use this kind of test image or its publicly known default password for externally exposed services. Paths read by system QEMU must also satisfy security policies and directory permissions; --graphics none does not automatically make an arbitrary guest provide a serial login.
Use a CirrOS test image for end-to-end verification. CirrOS is a minimal Linux distribution of only about 12MB, designed specifically for OpenStack/KVM testing.
6.1 Download the test image
# 下载 CirrOS(x86_64 压缩磁盘镜像)
wget https://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img
# 校验文件完整性(可选)
wget https://download.cirros-cloud.net/0.6.2/MD5SUMS
grep cirros-0.6.2-x86_64-disk.img MD5SUMS | md5sum -c -6.2 Create and start the test virtual machine
virt-install --connect qemu:///system \
--name test \
--ram 512 \
--vcpus 1 \
--disk path=cirros-0.6.2-x86_64-disk.img \
--import \
--os-variant cirros0.6 \
--graphics none \
--network network=default| Parameter | Meaning |
|---|---|
--name test |
The virtual machine's name in libvirt |
--ram 512 |
Allocate 512MB of memory |
--vcpus 1 |
Allocate 1 virtual CPU core |
--disk path=... |
Specify the disk image file path |
--import |
Skip operating-system installation and use the existing disk image directly; importantly, without this option virt-install will try to launch an OS installer |
--os-variant cirros0.6 |
Tell libvirt the guest OS type to optimize default settings, such as virtio drivers |
--graphics none |
Do not start a graphical console; connect output directly to the current terminal, suitable for testing or environments without a desktop |
--network network=default |
Connect to the default NAT virtual network |
After the virtual machine starts, the terminal directly displays the CirrOS boot process and login prompt:
=== cirros: cirros 0.6.2 ===
login:Default CirrOS login credentials:
- Username:
cirros - Password:
<CIRROS_TEST_PASSWORD_FROM_RELEASE>
Press Ctrl+] to leave the console connection; the virtual machine continues running in the background.
6.3 Check the virtual machine state
# 列出所有虚拟机
virsh list --all
# 期望输出:
# Id Name State
# -----------------------
# 1 test running
# 查看虚拟机详细信息
virsh dominfo test
# 期望输出关键字段:
# Id: 1
# Name: test
# UUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
# OS Type: hvm
# State: running
# CPU(s): 1
# Max memory: 524288 KiB
# Used memory: 524288 KiB6.4 Clean up the test virtual machine
# 强制关闭虚拟机(相当于拔电源)
virsh destroy test
# 若虚拟机已正常关机(shutdown),用 undefine 直接删除定义即可
# 从 libvirt 中注销虚拟机定义(不删除磁盘文件)
virsh undefine test
# 可选:删除下载的测试镜像
rm cirros-0.6.2-x86_64-disk.imgdestroy vs shutdown vs undefine
virsh destroy <name>: forcibly stop the virtual machine, similar to cutting power; data not yet written to disk may be lost. It does not delete the virtual-machine definition or disks.virsh shutdown <name>: send an ACPI shutdown signal to the guest for a graceful shutdown; the guest needs an ACPI service installedvirsh undefine <name>: remove the virtual-machine configuration from the libvirt database; it does not delete disk files. Add--remove-all-storageto also delete the associated storage volumes.
7. Recommended post-installation configuration#
7.1 Set the default libvirt URI
When using virsh, avoid having to specify -c qemu:///system every time:
# 写入 shell 配置文件
echo 'export LIBVIRT_DEFAULT_URI="qemu:///system"' >> ~/.bashrc
source ~/.bashrc
# 或者一次性设置(已有 shell 会话)
export LIBVIRT_DEFAULT_URI="qemu:///system"7.2 Configure the VM storage directory
pool-define-as creates a persistent definition, which is then activated by pool-start. pool-create-as creates only a transient pool, so do not assume it can autostart. System QEMU needs actual directory-traversal and file read/write permissions; home directories are often restricted by permissions or security policies. Choose an authorized storage directory rather than using chmod to open up the entire home directory.
Create a dedicated directory for virtual-machine disks and ISO images:
# 创建存储目录
mkdir -p ~/vm/images # 虚拟机磁盘文件
mkdir -p ~/vm/isos # 操作系统 ISO 镜像
mkdir -p ~/vm/cloud-init # cloud-init 配置文件(可选)
# 注册为 libvirt 存储池(方便 virt-manager 可视化操作)
virsh pool-define-as --name vm-images --type dir --target ~/vm/images
virsh pool-define-as --name vm-isos --type dir --target ~/vm/isos
virsh pool-start vm-images
virsh pool-autostart vm-images
virsh pool-start vm-isos
virsh pool-autostart vm-isos7.3 Configure remote management (optional)
Prefer an SSH tunnel: the remote account needs both SSH authentication and group or polkit authorization for the remote system libvirt socket. Permission to log in over SSH alone does not grant libvirt management access.
virsh -c qemu+ssh://user@server.example.com/system list --allTLS management requires a CA, server and client certificates, correct hostname verification, private-key permissions, access control, and the appropriate socket configuration. Historical monolithic-daemon configuration keys include listen_tls, tls_port, key_file, cert_file, and ca_file. For socket activation or virtproxyd deployments, follow the official documentation for the architecture in use; editing the old libvirtd.conf alone is insufficient.
The historical combination of plaintext TCP listen_tcp and unauthenticated auth_tcp grants full management capability to anyone who can reach the port; it should not be the default even on a "trusted internal network." TLS commonly uses port 16514, while plaintext TCP commonly uses 16509. The port number does not prove that a connection is authenticated or encrypted.
Summary#
Whether the default NAT network is defined, started, or configured to autostart depends on the distribution's installation and existing state. NAT provides outbound forwarding, not complete security isolation; guests can usually still access the host's virtual bridge and other guests on the same network. The example subnet uses a documentation range to illustrate the topology. Replace it with a nonconflicting RFC1918 private network when creating a real network.
After configuration, verify each of the following conditions. The commands in this article have not been run:
- KVM hardware acceleration is ready
- The QEMU + libvirt software stack is installed
- User permissions are configured correctly, allowing virtual-machine management without
sudo - libvirtd, or the equivalent modular daemons, starts automatically at boot
- The
defaultNAT network is available
Next: Creating and Managing Virtual Machines covers the creation process, configuration parameters, and lifecycle management in depth.
References & further reading
- libvirt daemons and sockets ↗
- libvirt remote management ↗
- libvirt network XML ↗
- Linux kernel parameters ↗
Adapted from technical notes. Examples use generic names.