Linux QEMU 管理与优化实践

9次阅读

用 qemu-system-x86_64 启动最小 linux 虚拟机需指定 -kernel 和 -initrd,加 console=ttys0 与 -nographic 才有串口输出;内存至少 -m 512;-cpu qemu64,+nx,-svm 可绕过硬件虚拟化缺失;网络选 -netdev user(开箱即用)或 -device virtio-net-pci(需客户机支持);-smp 多核需客户机内核启用 config_x86_local_apic 和 config_x86_io_apic。

Linux QEMU 管理与优化实践

如何用 qemu-system-x86_64 启动一个最小可用的 Linux 虚拟机

直接跑起来比调参重要。一个没加任何优化参数的 qemu-system-x86_64 命令,只要配对了内核和 initramfs,就能进 shell。

  • 必须指定 -kernel(路径要绝对或相对当前目录可访问)和 -initrd,否则报 Kernel panic - not syncing: VFS: Unable to mount root fs
  • -append "console=ttyS0" 是关键,不然串口没输出,看着像卡死;加上 -nographic 才能纯终端交互
  • 内存至少给 -m 512,低于 256M 容易在解压 initramfs 阶段 OOM
  • 不加 -cpu 时默认用 qemu64,老宿主上可能缺 svmvmx 导致启动失败,临时换成 -cpu qemu64,+nx,-svm 可绕过

-device virtio-net-pci-netdev user 的实际区别在哪

不是“要不要网络”,而是“谁管网络栈、谁暴露端口、谁决定 DNS”。-netdev user 是 QEMU 自带的用户态 NAT 网络,开箱即用但不可直连宿主机服务;virtio-net-pci 是半虚拟化网卡驱动,性能好但依赖客户机装 virtio_net 模块。

  • -netdev user,id=net0,hostfwd=tcp::2222-:22:客户机 SSH 端口映射到宿主机 2222,适合调试,但客户机 ping 不通宿主机 IP
  • -device virtio-net-pci,netdev=net0,mac=52:54:00:12:34:56 必须和上面 -netdevid 对应,否则报 Device 'virtio-net-pci' could not be initialized
  • 如果客户机没加载 virtio_netip link 看不到 eth0,dmesg 里有 virtio_net: probe of virtio0 failed with error -2
  • 生产环境别混用:user 模式下再加 virtio 设备无意义,QEMU 会忽略或报错

为什么 -smp 4 后客户机只看到 1 个 CPU

不是 QEMU 没传过去,是客户机内核启动时没识别到 APIC 或 SMP 支持被关了。尤其用自编译内核或精简发行版时常见。

  • 检查客户机 dmesg | grep -i "smp|apic",出现 APIC: disable apic facility 说明内核配置缺 CONFIG_X86_LOCAL_APICCONFIG_X86_IO_APIC
  • -smp 4,cores=2,threads=2 这种拓扑写法,某些旧版 QEMU(cores,退化成单核,建议先用 -smp 4 简写验证
  • 客户机内 cat /proc/cpuinfo | grep processor | wc -l 才是真实逻辑 CPU 数,nproc 有时受 cgroup 限制返回不准
  • 如果客户机是 Alpine 或 Buildroot,默认内核常裁剪掉 SMP 支持,换 linux-vanilla 或加 CONFIG_SMP=y 重编译

-drive if=virtio 启动慢或读写卡顿的几个硬坑

virtio-blk 性能远超 ide,但卡顿往往不是 I/O 本身,而是队列、缓存、或客户机驱动没跟上。

  • -drive file=disk.img,if=virtio,cache=none,aio=native,format=qcow2 是推荐组合:其中 cache=none 避免双重缓存,aio=native 启用 Linux io_uring(QEMU ≥ 6.0),否则 fallback 到线程池,小文件随机读写延迟翻倍
  • 客户机没装 virtio_blk 模块时,lsblk 看不到磁盘,dmesgvirtio_blk: probe of virtio0 failed with error -2,需确认内核 config 含 CONFIG_VIRTIO_BLK=y
  • qcow2 格式嵌套太多层(比如 base → snap1 → snap2)会导致 CoW 元数据查找变慢,实测 3 层以上随机写入延迟升 30%+,非必要不用快照链
  • 宿主机 ext4 文件系统挂载时用了 noatime,nodiratime 可减少元数据更新开销,对 cache=writeback 场景尤其明显

最常被跳过的其实是客户机内核的 CONFIG_VIRTIO_* 选项——QEMU 参数再全,客户机没驱动就是零。别只盯着 -smp-m 调,先 dmesg | grep virtio 看清底层有没有认设备。

text=ZqhQzanResources