LabHub
学习 学习路径 课程

虚拟化与 QEMU/KVM

怎么读 QEMU 的命令行

在 LabHub 中继续学习

一句话总结

QEMU 命令行是一份虚拟硬件的部件清单。每一个参数都决定了客户机能够看到的设备。

概念图: 虚拟硬件的部件清单 · format= · -netdev 与 -device 的分离 · 主机一侧的后端

为什么需要理解命令行

实际工作中,大多数人使用 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 networksystem_powerdown(请求 ACPI 关机)、savevm/loadvm(运行时快照)等。自动化场景中的标准做法是通过套接字连接。

控制台

组合 -nographic-serial 使用串口控制台。必须向客户机内核传递 console=ttyS0,内核消息才会输出到串口。若要把日志保存到文件,应使用 -serial file:/root/vm/console.log

了解启动早期各种信息出现的顺序,就能判断启动进行到了哪一步。

  1. SeaBIOS (version ...)——固件已启动
  2. Booting from Hard Disk...——已转交引导加载程序
  3. Linux version ...——内核已启动
  4. 登录提示符——已进入用户空间

第一项会在 QEMU 启动后立即出现。 即使由于使用 TCG,第三项要等待很久,只要能看到第一、第二项,就说明磁盘与引导加载程序正常。

实际工作中会遇到的情况

使用 ps aux | grep qemu 确认实际参数。 libvirt XML 与实际运行参数有时并不一致,例如使用了缓存的域定义或热插拔设备。真正的事实在进程命令行中。

省略 format= 导致的问题。 QEMU 会根据文件内容猜测格式;如果客户机在磁盘开头写入看起来像 qcow2 头部的数据,下次启动时就可能误判。因此必须始终显式指定格式。

下一个实验要做什么

/opt/vm/ 中的镜像为后备文件创建覆盖层,使用准确参数编写启动脚本并实际运行,然后确认串口日志、监视器响应、hostfwd 监听套接字三项证据。