Linux QEMU 虚拟机管理实践

1次阅读

no bootable device 错误主因是启动顺序或设备挂载不当:需用 -boot d/c 指定光驱/硬盘启动,确保 -drive 参数正确且路径为绝对路径;virsh 与裸跑 qemu 互不感知;user-mode 网络下虚拟机无法访问宿主机 localhost,需桥接或端口转发;qcow2 缩容须客户机执行 fstrim 并启用 discard。

Linux QEMU 虚拟机管理实践

qemu-system-x86_64 启动失败:No bootable device

这是最常卡住新手的第一步,不是镜像坏了,大概率是启动顺序或设备没挂对。qemu-system-x86_64 默认不自动从硬盘找引导,得明确告诉它从哪读。

  • -boot d 强制从光驱(CD-ROM)启动,适合装系统时用 ISO;装完系统后换成 -boot c 才能从硬盘启动
  • 确保 -drive 参数里指定了 format=qcow2raw,且文件真实存在、有读权限;路径别用波浪号 ~qemu 不展开,写绝对路径更稳
  • 如果用了 -cdrom 但没关机就重跑命令,QEMU 可能锁住 ISO 文件,报 “Could not open ‘xxx.iso’” —— 先 killall qemu-system-x86_64 再试

virsh list 显示空,但 ps 看得到 qemu 进程

virsh 和裸跑 qemu-system-x86_64 是两套管理体系。直接敲命令起的虚拟机,libvirt 根本不知道,自然不会出现在 virsh list 里。

  • 想用 virsh 管理,就得用 virsh define 导入 xml 描述,再 virsh start;不能靠手动起进程“骗过” libvirt
  • 检查当前连接的是不是默认 hypervisor:virsh -c qemu:///system listvirsh -c qemu:///session list 看到的结果可能完全不同 —— root 下跑的和普通用户下跑的互不可见
  • 如果只是临时测试,别硬套 libvirt,直接用 qemu-system-x86_64 更轻量;但要做快照、热迁移、网络桥接,绕不开 virsh 配置

虚拟机里无法访问宿主机服务(比如 localhost:3000)

QEMU 默认用 user-mode 网络(-netdev user),它做了 NAT,宿主机对虚拟机是“不可见”的,反过来也一样 —— 虚拟机里的 localhost 指的是它自己,不是宿主机。

  • 简单方案:改用 -netdev bridge,id=net0,br=virbr0 + -device virtio-net-pci,netdev=net0,前提是宿主机已配好网桥(如 virbr0),且你有 root 权限
  • 不想配桥接?用端口转发:-netdev user,id=net0,hostfwd=tcp::2222-:22 把宿主机 2222 映射到虚拟机 22,ssh 就通了;http 服务同理,但注意别冲突
  • 别信“改 /etc/hosts 加宿主机 IP”,user-mode 网络下虚拟机压根 ping 不通宿主机 IP,这是设计限制,不是配置错

qcow2 镜像越用越大,删文件也不缩容

qcow2 文件大小增长是正常的,但删除客户机里的文件并不会自动释放空间 —— 客户机操作系统只标记块为“空闲”,没通知 QEMU 底层丢弃这些块。

  • 客户机里要先运行 fstrim -v /(ext4/xfs 支持),触发 TRIM 命令;需确认虚拟机磁盘启用了 discard:-drive file=disk.qcow2,discard=unmap,...
  • 宿主机上手动收缩:qemu-img convert -O qcow2 disk.qcow2 disk-new.qcow2 && mv disk-new.qcow2 disk.qcow2,但会中断运行,慎用于生产环境
  • 长期建议:创建镜像时加 -o lazy_refcounts=on,cluster_size=2M,提升大镜像性能;别用 copy-on-write 链太深,超过 5 层易出元数据错误

真正麻烦的不是怎么缩,而是很多人根本没意识到客户机里要跑 fstrim —— 它不像物理 SSD 那样开机自动做,得加进定时任务里。

text=ZqhQzanResources