Ubuntu 安装 QEMU/KVM 虚拟机
参见:KVM Network Configuration | Oracle Docs
Prerequisite
-
检查 CPU 虚拟化支持:
egrep -c '(vmx|svm)' /proc/cpuinfo # 计算虚拟处理器 VMX 或 SVM 的引用数输出不为
0即可。 -
安装依赖:
sudo apt install qemu-system-x86 libvirt-daemon-system libvirt-clients virtinst # bridge-utils virt-managerqemu-system-x86:QEMU x86 系统仿真器libvirt-daemon-system: 管理虚拟机的守护进程(libvirtd)libvirt-clients:与 libvirtd 通信的命令行接口(virsh等)virtinst:用于安装虚拟机(virt-install)bridge-utils:网桥管理(可选)virt-manager:与 libvirtd 通信的图形接口(可选)
-
将用户添加到
libvirt和kvm组:sudo usermod -aG libvirt,kvm $USER -
重新登录。
下载系统镜像:[releases.ubuntu.com] [mirrors.tuna.tsinghua.edu.cn]
创建虚拟机
Linux
使用 VNC 连接
-
创建虚拟磁盘映像:
qemu-img create -f qcow2 -o preallocation=off disk.qcow2 128G -
创建虚拟机:
virt-install \ --name my-vm \ --memory 4096 \ --vcpus 4 \ --cdrom '/path/to/ubuntu.iso' \ --osinfo ubuntu24.04 \ --disk '/path/to/disk.qcow2,bus=virtio' \ --network 'network=default,model=virtio' \ --boot 'loader=/usr/share/OVMF/OVMF_CODE_4M.fd' \ --graphics 'vnc,password=123456,port=5900,listen=127.0.0.1' \ --noautoconsole \ --connect qemu:///system--name:虚拟机名称--memory:虚拟机内存大小(MiB)--vcpus:虚拟核心数--cdrom:ISO 映像路径--osinfo:虚拟机操作系统--disk:虚拟磁盘路径--network:虚拟机网络接口--boot:虚拟机的引导配置,这里用来提供 UEFI 固件支持--graphics:虚拟机显示设置--noautoconsole:禁止自动连接虚拟机控制台--connect:连接指定 hypervisor
-
查询虚拟机 VNC 端口:
$ virsh -c qemu:///system vncdisplay my-vm 127.0.0.1:0实际的 VNC 端口为
5900+ 显示编号0
网络设置
--network 'network=default,model=virtio' # NAT
--network 'bridge=br0,model=virtio' # 桥接到 br0 网桥
--network 'type=direct,source=eth0,source_mode=bridge,model=virtio' # 直连到 eth0 接口
存储设置
--disk 'disk.qcow2,bus=virtio' # 使用磁盘文件
--disk 'pool=default,size=40,format=qcow2' # 使用存储池
--disk 'vol=default/disk.qcow2,device=disk,format=qcow2' # 使用存储卷
弹出安装介质
系统安装完成后需要弹出安装介质。
-
列出块设备:
$ virsh -c qemu:///system domblklist my-vm Target Source ---------------------------------------------------- sda /var/lib/libvirt/images/my-vm.qcow2 sdb /home/user/ubuntu.iso可以看到安装介质名为
sdb -
弹出介质:
virsh -c qemu:///system change-media my-vm sdb --eject
参考:
- The Ultimate Guide to Creating KVM Virtual Machines on Ubuntu 22.04 | Beam Networks
- Creating a VM with KVM: Step-by-Step Tutorial on Ubuntu | YouTube
- libvirt | Arch Linux 中文维基
- Configuring virtual machines with virsh | SUSE Docs
- How to get started with libvirt on Linux | rabexc.org
使用串口连接
这种方法只对部分 ISO 映像有效,如 Ubuntu。其他映像请使用 VNC 连接。
安装操作系统后可以手动修改内核启动参数将控制台消息转发到串口,然后再使用串口连接。
-
创建虚拟机:
virt-install \ --name my-vm \ --memory 4096 \ --vcpus 4 \ --location 'ubuntu.iso,kernel=casper/vmlinuz,initrd=casper/initrd' \ --extra-args 'console=ttyS0,115200n8 serial' \ --osinfo ubuntu24.04 \ --disk '/path/to/disk.qcow2,bus=virtio' \ --network 'network=default,model=virtio' \ --boot 'loader=/usr/share/OVMF/OVMF_CODE_4M.fd,loader_ro=yes,loader_type=pflash,nvram_template=/usr/share/OVMF/OVMF_VARS_4M.fd' \ --graphics none \ --connect qemu:///system--location:指定发行版树安装源--extra-args:从 location 安装时指定附加内核启动参数
开始安装后将自动连接到虚拟机串口。可以通过
Ctrl + ]断开连接。 -
手动连接虚拟机串口:
virsh -c qemu:///system console my-vm
参考:
Windows
-
准备材料:
-
wget https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.271-1/virtio-win.iso
-
创建虚拟机。
创建 Windows 虚拟机需要:
- 启用 TPM-CRB 2.0
- UEFI 固件启用 Secure Boot
virt-install \ --name my-vm \ --memory 4096 \ --vcpus 4 \ --cdrom 'Win11.iso' \ --disk 'disk.qcow2,bus=virtio' \ --disk 'path=virtio-win.iso,device=cdrom' \ --osinfo win11 \ --network 'network=default,model=virtio' \ --features 'kvm_hidden=on,smm=on' \ --tpm 'backend.type=emulator,backend.version=2.0,model=tpm-crb' \ --boot 'loader=/usr/share/OVMF/OVMF_CODE_4M.ms.fd,loader_ro=yes,loader_type=pflash,nvram_template=/usr/share/OVMF/OVMF_VARS_4M.ms.fd' \ --graphics 'vnc,password=123456,port=5900,listen=127.0.0.1' \ --noautoconsole \ --connect qemu:///system -
查询虚拟机 VNC 端口:
virsh -c qemu:///system vncdisplay my-vm -
安装硬盘驱动:
virtio-win.iso:\viostor\w11\amd64\viostor.inf -
安装网络驱动:
virtio-win.iso:\NetKVM\w11\amd64\netkvm.inf
参考:
- How to Properly Install a Windows 11 Virtual Machine on KVM | sysguides.com
- Creating a Windows 11 Virtual Machine on Libvirt | manuelcortez.net
- Driver installation | virtio-win/kvm-guest-drivers-windows Wiki
- Windows virtio drivers | KubeVirt user guide
删除虚拟机
-
强制关闭虚拟机:
virsh -c qemu:///system destroy my-vm -
删除虚拟机:
virsh -c qemu:///system undefine my-vm
导入虚拟机
如果只有虚拟机磁盘,而没有虚拟机定义文件,可以通过如下方式导入虚拟机:
virt-install \
--import \
--name windows \
--memory 4096 \
--vcpus 4 \
--disk 'path=disk.qcow2' \
--osinfo win11 \
--features 'kvm_hidden=on,smm=on' \
--tpm 'backend.type=emulator,backend.version=2.0,model=tpm-crb' \
--boot 'loader=/usr/share/OVMF/OVMF_CODE_4M.ms.fd,loader_ro=yes,loader_type=pflash,nvram_template=/usr/share/OVMF/OVMF_VARS_4M.ms.fd' \
--graphics 'vnc,password=123456,port=5900,listen=127.0.0.1' \
--noautoconsole \
--connect qemu:///system
GPU 直通
未完待续
GPU 直通通过 IOMMU 技术直接将 GPU 设备分配给虚拟机。此时宿主机将无法使用该 GPU 设备。
-
在内核启动参数中启用 IOMMU:
sudoedit /etc/default/grubGRUB_CMDLINE_LINUX_DEFAULT="intel_iommu=on iommu=pt kvm.ignore_msrs=1"更新 GRUB:
sudo update-grub重启系统:
sudo reboot检查 IOMMU 是否启用:
sudo dmesg | egrep 'DMAR|IOMMU'查看 IOMMU 分组:
for d in /sys/kernel/iommu_groups/*/devices/*; do n=${d#*/iommu_groups/*} n=${n%%/*} printf 'IOMMU Group %s ' "$n" lspci -nns "${d##*/}" done | grep "NVIDIA" | sort -nk3IOMMU Group 19 41:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:2bb5] (rev a1) IOMMU Group 32 01:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:2bb5] (rev a1) IOMMU Group 47 21:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:2bb5] (rev a1)这里有三个独立的 IOMMU 组,我们可以将其中两个组的设备用于 GPU 直通。
-
编辑 VFIO 内核模块参数:
sudoedit /etc/modprobe.d/vfio.confoptions vfio-pci ids=10de:2bb5ids是检查分组的输出中中括号内的 ID,用逗号隔开。 -
编辑内核模块加载列表:
sudoedit /etc/modules-load.d/vfio-pci.confvfio vfio_iommu_type1 vfio_pci -
将 PCI-e 设备连接到虚拟机:
参考:
- Ubuntu 22.04 GPU passthrough (QEMU) | Ask Ubuntu
- GPU passthrough with virt-manager, QEMU, and KVM | Gentoo Wiki
- clayfreeman/gpu-passthrough | GitHub
- KVM 虚拟机 VFIO 显卡直通教程 - 支持笔记本, 无需外接设备!| 博客园
Quickemu
Quickemu 是 QEMU 的封装,用于快速启动一个虚拟机。
安装
sudo apt-add-repository ppa:flexiondotorg/quickemu
sudo apt update
sudo apt install quickemu
使用
-
安装并启动虚拟机:
# 创建 Windows 11 虚拟机 quickget windows 11 "Chinese (Simplified)" quickemu --vm windows-11.conf --display spice # 创建 Ubuntu 24.04 虚拟机 quickget ubuntu 24.04 quickemu --vm ubuntu-24.04.conf --display spice # 创建 Arch Linux 虚拟机 quickget archlinux latest quickemu --vm archlinux-latest.conf --display spice -
安装 SPICE 客户端:
brew install remoteviewer其他平台的客户端可以在 spice-space.org 找到。
-
使用 RemoteViewer 连接 spice://127.0.0.1:5930。
也可以通过 SSH 连接:ssh://127.0.0.1:22220
检查连接端口:
cat <os>/<os>.ports
参考:Advanced quickemu configuration | quickemu Wiki
Troubleshooting
-
Couldn't find kernel for install tree
在创建虚拟机时提示无法找到用于安装树的内核:
ERROR Couldn't find kernel for install tree.问题原因:安装程序找不到内核和 initrd 文件。
解决方法:在
--location参数中指定内核和 initrd 文件路径。对于 Ubuntu,使用kernel=casper/vmlinuz,initrd=casper/initrd -
连接到串口后没有输出
$ virsh -c qemu:///system console ubuntu Connected to domain 'ubuntu' Escape character is ^] (Ctrl + ])问题原因:虚拟机没有启用串口控制台
解决方法:通过其他方式登录虚拟机后添加内核启动参数:
sudo grubby --update-kernel=ALL --args="console=ttyS0"参考:virsh console hangs whenever I connect to Virtual Machine | Stack Overflow
-
cannot undefine domain with nvram
$ virsh -c qemu:///system undefine windows error: Failed to undefine domain 'windows' error: Requested operation is not valid: cannot undefine domain with nvram问题原因:虚拟机启动时使用了 NVRAM(非易失性随机存取存储器)文件,销毁该虚拟机需要指定 NVRAM 的处理策略。
解决方法:
virsh -c qemu:///system undefine windows --nvram -
XXX may not be accessible by the hypervisor
$ virt-install --name windows --memory 4096 --vcpus 4 --cdrom windows_11.iso --osinfo win11 --disk size=128 --network 'network=default,model=virtio' --graphics 'vnc,password=12345,port=5900,listen=127.0.0.1' --noautoconsole --connect qemu:///system WARNING /home/ubuntu/windows_11.iso may not be accessible by the hypervisor. You will need to grant the 'libvirt-qemu' user search permissions for the following directories: ['/home/ubuntu']解决方法:为
libvirt-qemu用户授予指定目录的执行权限。setfacl -m u:libvirt-qemu:x /home/ubuntu参考:libvirt qemu cannot access image inside my home directory, even as root? | Stack Exchange
-
No URI is provided and cannot identify any listening daemon socket path to attempt to connect to
ERROR Operation not supported: No URI is provided and cannot identify any listening daemon socket path to attempt to connect to. Please ensure the expected daemon sockets are active and/or provide an explicit URI. For more information see https://libvirt.org/kbase/failed_connection_after_install.html问题原因:
libvirtd服务未启动。解决方法:
sudo systemctl start libvirtd -
network 'default' is not active
ERROR Requested operation is not valid: network 'default' is not active问题原因:
default网络未启动,或者没有连接系统级 hypervisor解决方法:
virsh -c qemu:///system net-start default

浙公网安备 33010602011771号