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

qemu-system-x86_64 启动失败:No bootable device
这是最常卡住新手的第一步,不是镜像坏了,大概率是启动顺序或设备没挂对。qemu-system-x86_64 默认不自动从硬盘找引导,得明确告诉它从哪读。
- 加
-boot d强制从光驱(CD-ROM)启动,适合装系统时用 ISO;装完系统后换成-boot c才能从硬盘启动 - 确保
-drive参数里指定了format=qcow2或raw,且文件真实存在、有读权限;路径别用波浪号~,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 list和virsh -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 那样开机自动做,得加进定时任务里。