Ubuntu 安装 QEMU/KVM 虚拟机

参见:KVM Network Configuration | Oracle Docs

Prerequisite

  1. 检查 CPU 虚拟化支持:

    egrep -c '(vmx|svm)' /proc/cpuinfo  # 计算虚拟处理器 VMX 或 SVM 的引用数
    

    输出不为 0 即可。

  2. 安装依赖:

    sudo apt install qemu-system-x86 libvirt-daemon-system libvirt-clients virtinst # bridge-utils virt-manager
    
    • qemu-system-x86:QEMU x86 系统仿真器
    • libvirt-daemon-system: 管理虚拟机的守护进程(libvirtd)
    • libvirt-clients:与 libvirtd 通信的命令行接口(virsh 等)
    • virtinst:用于安装虚拟机(virt-install
    • bridge-utils:网桥管理(可选)
    • virt-manager:与 libvirtd 通信的图形接口(可选)
  3. 将用户添加到 libvirtkvm 组:

    sudo usermod -aG libvirt,kvm $USER
    
  4. 重新登录。

下载系统镜像:[releases.ubuntu.com] [mirrors.tuna.tsinghua.edu.cn]

创建虚拟机

Linux

使用 VNC 连接

  1. 创建虚拟磁盘映像:

    qemu-img create -f qcow2 -o preallocation=off disk.qcow2 128G
    
  2. 创建虚拟机:

    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
  3. 查询虚拟机 VNC 端口:

    $ virsh -c qemu:///system vncdisplay my-vm
    127.0.0.1:0
    

    实际的 VNC 端口为 5900 + 显示编号 0

  4. 连接虚拟机:vnc://:123456@127.0.0.1:5900

网络设置

--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'  # 使用存储卷

弹出安装介质

系统安装完成后需要弹出安装介质。

  1. 列出块设备:

    $ virsh -c qemu:///system domblklist my-vm
     Target   Source
    ----------------------------------------------------
     sda      /var/lib/libvirt/images/my-vm.qcow2
     sdb      /home/user/ubuntu.iso
    

    可以看到安装介质名为 sdb

  2. 弹出介质:

    virsh -c qemu:///system change-media my-vm sdb --eject
    

参考:

使用串口连接

这种方法只对部分 ISO 映像有效,如 Ubuntu。其他映像请使用 VNC 连接。
安装操作系统后可以手动修改内核启动参数将控制台消息转发到串口,然后再使用串口连接。

  1. 创建虚拟机:

    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 + ] 断开连接。

  2. 手动连接虚拟机串口:

    virsh -c qemu:///system console my-vm
    

参考:

Windows

  1. 准备材料:

  2. 创建虚拟机。

    创建 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
    
  3. 查询虚拟机 VNC 端口:

    virsh -c qemu:///system vncdisplay my-vm
    
  4. 连接虚拟机:vnc://:123456@127.0.0.1:5900

  5. 安装硬盘驱动:virtio-win.iso:\viostor\w11\amd64\viostor.inf

  6. 安装网络驱动:virtio-win.iso:\NetKVM\w11\amd64\netkvm.inf

参考:

删除虚拟机

  1. 强制关闭虚拟机:

    virsh -c qemu:///system destroy my-vm
    
  2. 删除虚拟机:

    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 设备。

  1. 在内核启动参数中启用 IOMMU:

    sudoedit /etc/default/grub
    
    GRUB_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 -nk3
    
    IOMMU 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 直通。

  2. 编辑 VFIO 内核模块参数:

    sudoedit /etc/modprobe.d/vfio.conf
    
    options vfio-pci ids=10de:2bb5
    

    ids 是检查分组的输出中中括号内的 ID,用逗号隔开。

  3. 编辑内核模块加载列表:

    sudoedit /etc/modules-load.d/vfio-pci.conf
    
    vfio
    vfio_iommu_type1
    vfio_pci
    
  4. 将 PCI-e 设备连接到虚拟机:

参考:

Quickemu

Quickemu 是 QEMU 的封装,用于快速启动一个虚拟机。

安装

sudo apt-add-repository ppa:flexiondotorg/quickemu
sudo apt update
sudo apt install quickemu

使用

  1. 安装并启动虚拟机:

    # 创建 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
    
  2. 安装 SPICE 客户端:

    brew install remoteviewer
    

    其他平台的客户端可以在 spice-space.org 找到。

  3. 使用 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
    

    参考:删除虚拟机时提示 cannot undefine domain with 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
    
posted @ 2025-04-04 03:30  Undefined443  阅读(494)  评论(0)    收藏  举报