怎么读 QEMU 的命令行
一句话总结
QEMU 命令行是一份虚拟硬件的部件清单。每一个参数都决定了客户机能够看到的设备。
为什么需要理解命令行
实际工作中,大多数人使用 libvirt 或云控制台。但一旦出现问题,最终还是要阅读下层的 QEMU 命令行。libvirt XML 最后也会转换成这条命令,而使用 ps aux | grep qemu 确认实际运行参数,是诊断的第一步。
它是如何工作的
一台最小化 VM 如下所示。
qemu-system-x86_64 \
-accel tcg \
-m 512 \
-smp 2 \
-drive file=/root/vm/vm01.qcow2,if=virtio,format=qcow2 \
-netdev user,id=n0,hostfwd=tcp::12222-:22 \
-device virtio-net-pci,netdev=n0 \
-nographic \
-serial mon:stdio
各参数的含义如下。
| 参数 | 含义 | 实际工作中的要点 |
|---|---|---|
-accel kvm / tcg |
选择加速器 | 使用 -accel help 查看可用选项 |
-m 512 |
内存(MB) | 省略单位时默认为 MB |
-smp 2 |
vCPU 数量 | 可用 -smp 2,sockets=1,cores=2 指定拓扑 |
-drive ...,if=virtio |
磁盘与接口 | 为安全起见,必须显式指定 format= |
-netdev / -device |
后端 / 前端 | 两者总是成对出现 |
-nographic |
不启用图形界面 | 服务器环境的基本设置 |
-serial mon:stdio |
将串口连接到 stdio,同时复用监视器 | 通过 Ctrl-a c 切换 |
-monitor unix:<경로>,server,nowait |
把监视器绑定到 Unix 套接字 | 适合自动化 |
-netdev 与 -device 的分离一开始容易令人困惑。-netdev 表示主机一侧的后端,决定数据包去往哪里;-device 表示客户机看到的 NIC,决定它看起来是哪种网卡。两者通过 id= 连接。
网络模式
| 模式 | 特点 | 适用场景 |
|---|---|---|
user(SLIRP) |
用户空间 NAT,不需要特权 | 开发与测试,也是本实验环境唯一可用的选择 |
tap |
内核 TAP 设备 | 生产环境,需要特权 |
bridge |
把 TAP 连接到网桥 | VM 间通信、对外暴露 |
vhost-net |
在内核中处理环形队列 | 高性能场景 |
在 user 模式下,客户机能够访问外部网络,外部却不能主动连接客户机,所以必须用 hostfwd 打开端口。
-netdev user,id=n0,hostfwd=tcp::12222-:22
这会把进入主机 12222 端口的 TCP 流量转发到客户机的 22 端口。QEMU 一启动,这个监听套接字就会立刻打开——即使客户机仍在启动,ss -ltn 也能看到它。客户机尚未就绪时,连接只会被拒绝。
监视器
QEMU 监视器是与运行中 VM 交互的控制台。
-monitor unix:/root/vm/mon.sock,server,nowait
echo 'info status' | nc -U /root/vm/mon.sock
echo 'info block' | nc -U /root/vm/mon.sock
可用命令包括 info status(运行/停止状态)、info block(磁盘)、info network、system_powerdown(请求 ACPI 关机)、savevm/loadvm(运行时快照)等。自动化场景中的标准做法是通过套接字连接。
控制台
组合 -nographic 与 -serial 使用串口控制台。必须向客户机内核传递 console=ttyS0,内核消息才会输出到串口。若要把日志保存到文件,应使用 -serial file:/root/vm/console.log。
了解启动早期各种信息出现的顺序,就能判断启动进行到了哪一步。
SeaBIOS (version ...)——固件已启动Booting from Hard Disk...——已转交引导加载程序Linux version ...——内核已启动- 登录提示符——已进入用户空间
第一项会在 QEMU 启动后立即出现。 即使由于使用 TCG,第三项要等待很久,只要能看到第一、第二项,就说明磁盘与引导加载程序正常。
实际工作中会遇到的情况
使用 ps aux | grep qemu 确认实际参数。 libvirt XML 与实际运行参数有时并不一致,例如使用了缓存的域定义或热插拔设备。真正的事实在进程命令行中。
省略 format= 导致的问题。 QEMU 会根据文件内容猜测格式;如果客户机在磁盘开头写入看起来像 qcow2 头部的数据,下次启动时就可能误判。因此必须始终显式指定格式。
下一个实验要做什么
以 /opt/vm/ 中的镜像为后备文件创建覆盖层,使用准确参数编写启动脚本并实际运行,然后确认串口日志、监视器响应、hostfwd 监听套接字三项证据。