阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

基于QMP实现对QEMU虚拟机进行交互

357次阅读
没有评论

共计 5272 个字符,预计需要花费 14 分钟才能阅读完成。

基于 QMP 实现对 QEMU 虚拟机进行交互

本文详解 QMP,包含 qmp、hmp、qemu-guest-agent 的介绍、工作原理、配置方法、范例

小慢哥的原创文章,欢迎转载


目录

▪ QMP 介绍
▪ QMP 语法
▪ 单独使用 qemu,启用 QMP
▪ 通过 libvirt 启动 qemu,启用 QMP
▪ qemu-guest-agent(qemu-ga)
▪ 官方参考文档

QMP 介绍

qemu 对外提供了一个 socket 接口,称为 qemu monitor,通过该接口,可以对虚拟机实例的整个生命周期进行管理,主要有如下功能

▷ 状态查看、变更
▷ 设备查看、变更
▷ 性能查看、限制
▷ 在线迁移
▷ 数据备份
▷ 访问内部操作系统

通过该 socket 接口传递交互的协议是 qmp,全称是 qemu monitor protocol,这是基于 json 格式的协议

在继续往下讲之前,需要先了解 qemu、kvm、libvirt 之间的区别(因为有很多童鞋对这三者的理解是混乱的)

▷ qemu:虚拟机仿真器。通过软件模拟出 cpu、内存、磁盘、主板、网卡等设备
▷ kvm:高性能的 cpu 仿真器。由于软件模拟的 cpu 性能很差,因此出现了 kvm,这是通过硬件与内核的支持实现接近 native 性能的 cpu 仿真器,可以理解为虚拟机里的 cpu 任务直接交给物理机 cpu 完成。
▷ libvirt:虚拟机管理平台。能纳管 qemu、lxc、esx 等虚拟化软件,通过编写 xml 实现对虚拟机、存储、网络等进行配置和管理

上面只描述最核心的功能,另有一些高级功能,以及互相重叠的功能在这里不做描述,否则容易混淆

QMP 语法

# 不带参数的指令
{"execute" : "XXX" }

# 带参数的指令
{"execute" : "XXX", "arguments" : {... } }

单独使用 qemu,启用 QMP

启动 qemu 虚拟机

# qemu monitor 采用 tcp 方式,监听在 127.0.0.1 上,端口为 4444
/usr/libexec/qemu-kvm -qmp tcp:127.0.0.1:4444,server,nowait

# qemu monitor 采用 unix socket,socket 文件生成于 /opt/qmp.socket
/usr/libexec/qemu-kvm -qmp unix:/opt/qmp.socket,server,nowait

连接 qemu monitor

# tcp 可以通过 telnet 进行连接,方法如下
> telnet 127.0.0.1 4444
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
{"QMP": {"version": {"qemu": {"micro": 0, "minor": 12, "major": 2}, "package": "qemu-kvm-ev-2.12.0-18.el7_6.1.1"}, "capabilities": []}}

# unix socket 可以通过 nc - U 进行连接,方法如下
> nc -U qmp.socket
{"QMP": {"version": {"qemu": {"micro": 0, "minor": 12, "major": 2}, "package": "qemu-kvm-ev-2.12.0-18.el7_6.1.1"}, "capabilities": []}}

按照上面执行完命令后,不会退出而是继续等待输入,但这个时候还无法使用,接着,需要输入一条 qmp 指令才可以

{"execute" : "qmp_capabilities" }

此时屏幕会输出以下内容,表示从 ”capabilities negotiation 模式 ” 进入了 ”command” 模式

{"return": {}}

接下来,就可以执行 qmp 的指令了,qmp 指令非常多,由于篇幅有限,这里仅举几个例子(更多内容请参考官方文档,本文最后附上网址)

# 查看支持哪些 qmp 指令
{"execute": "query-commands" }

# 虚拟机状态
{"execute": "query-status" }

# 虚拟机暂停
{"execute": "stop" }

# 磁盘查看
{"execute": "query-block" }

# 磁盘在线插入
{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "node-name": "drive-virtio-disk1", "file": {"driver": "file", "filename": "/opt/data.qcow2" } } }
{"execute": "device_add", "arguments": {"driver": "virtio-blk-pci", "drive": "drive-virtio-disk1" } }

# 磁盘完整备份
{"execute" : "drive-backup" , "arguments" : {"device" : "drive-virtio-disk0" , "sync" : "full" , "target" : "/opt/backuptest/fullbackup.img" } }

除了使用 telnet、nc 从外部连接,还可以在 qemu 启动时候进入一个交互的 cli 界面,直接输入指令,只不过这个时候输入的是 hmp(human monitor protocol),而不是 qmp。hmp 简化了 qmp 的使用,但实际在底层依然是转化为 qmp 进行操作的,配置方法如下

/usr/libexec/qemu-kvm -qmp tcp:127.0.0.1:4444,server,nowait -monitor stdio

此时会出现交互界面,输入 help,就可以看到 hmp 支持的所有命令

(qemu) help

使用 hmp 不需要输入类似 qmp 的{“execute” : “qmp_capabilities”}

这里列出几个范例

# 直接输入 info 回车,可以看到所有查询类的指令使用方法
(qemu) info

# 查看块设备
(qemu) info block

# 在线增加磁盘
(qemu) drive_add 0 file=/opt/data.qcow2,format=qcow2,id=drive-virtio-disk1,if=none
(qemu) device_add virtio-blk-pci,scsi=off,drive=drive-virtio-disk1

通过 libvirt 启动 qemu,启用 QMP

有 2 种方法:

1. xml 里不做任何额外配置,默认就会启用 QMP,但通过这种方法启用的 QMP,只能通过 libvirt 接口(比如 virsh 命令或 libvirt api)来进行 QMP 指令的输入,而不能通过 telnet、nc 之类的,因为默认启用的 QMP,只会生成 unix socket(位于 /var/lib/libvirt/qemu/domain-xx-DOMAIN/monitor.sock),而该 socket 被 libvirtd 始终连接占用着。此时通过 ps aux 命令可以看到 qemu 进程参数,和之前有点不太一样,不是 -qmp,而是如下

-chardev socket,id=charmonitor,fd=36,server,nowait \
-mon chardev=charmonitor,id=monitor,mode=control

qemu 命令参数支持 2 种方法配置 qmp,即 -qmp 和 -mon

这里通过 virsh 做个简单示范

virsh qemu-monitor-command DOMAIN --pretty '{"execute":"query-block"}'

使用 –pretty 是为了让 json 的输出具有换行缩进的格式化效果,而不是打印在一行里
不需要在执行其他指令前执行{“execute” : “qmp_capabilities”}

2. 在 xml 里额外增加 2 段配置,注意看下面这个 xml 的第一行,需要增加一个 xmlns:qemu,另外在里增加

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
  ...
  <devices>
    ...
  </devices>
  <qemu:commandline>
    <qemu:arg value='-qmp'/>
    <qemu:arg value='unix:/tmp/qmp-sock,server,nowait'/>
  </qemu:commandline>
</domain>

接着通过 libvirt 启动 qemu(比如 virsh start xxx),就创建了 2 个 qmp 通道,一个是 libvirt 默认创建的,可以依然使用 libvirt 接口来执行 QMP 指令,另一个就是自定义的 qmp,可以通过上面提到的 nc 来使用

nc -U /tmp/qmp-sock

libvirt 也支持 hmp:

virsh qemu-monitor-command DOMAIN --hmp 'info block'

qemu-guest-agent(qemu-ga)

通过 qmp 还可以对虚拟机内的操作系统进行 RPC 操作,其原理是:

1. 先在 xml 里配置 channel 段,然后启动虚拟机,会在宿主机上生成一个 unix socket,同时在 vm 里生成一个字符设备,生成的 unix socket 和字符设备可以理解为一个 channel 隧道的两端
2. 虚拟机里要启动 qemu-guest-agent 守护进程,该守护进程会监听字符设备
3. 然后可以在宿主机上将虚拟机里的 qemu-guest-agent 所支持的 RPC 指令经过 channel 发送到虚拟机里,虚拟机里的 qemu-guest-agent 从字符设备收到数据后,执行指令,比如读写文件、修改密码等等

若要使用 qemu-guest-agent 需要满足以下条件

1. xml 里配置 channel,范例:

<domain type='kvm'>
  ...
  <devices>
    ...
    <channel type='unix'>
      <source mode='bind' path='/tmp/channel.sock'/>
      <target type='virtio' name='org.qemu.guest_agent.0'/>
    </channel>
  </devices>
</domain>

注意,path 可以自定义,但 name 需要保持 org.qemu.guest_agent.0,因为这会影响虚拟机里字符设备的文件名,而虚拟机里的 qemu-guest-agent 服务默认读取的是对应 org.qemu.guest_agent.0 的字符设备,如果改了 name,那么 qemu-guest-agent 的配置文件也要跟着改,改成对应 name 的路径

2. 虚拟机内的操作系统内核需要支持(linux、windows 均支持)

3. 虚拟机里要安装并启动 qemu-ga 的服务(比如 CentOS 可以 yum install qemu-ga && systemctl start qemu-guest-agent,windows 通过导入 virtio-win 的 iso,该 iso 里包含有 qemu-ga 程序)

当按照上述配置好后,可以在宿主机上进行 RPC 操作

# 测试虚拟机里的 qemu-guest-agent 是否可用
virsh qemu-agent-command DOMAIN --pretty '{"execute": "guest-ping" }'

# 查看支持的 qemu-guest-agent 指令
virsh qemu-agent-command DOMAIN --pretty '{"execute": "guest-info" }'

# 获得网卡信息
virsh qemu-agent-command DOMAIN --pretty '{"execute": "guest-network-get-interfaces" }'

# 执行命令,这是异步的,第一步会返回一个 pid,假设为 797,在第二步需要带上这个 pid
virsh qemu-agent-command DOMAIN --pretty '{"execute": "guest-exec", "arguments": {"path": "ip", "arg": ["addr", "list" ], "capture-output": true } }'
virsh qemu-agent-command DOMAIN --pretty '{"execute": "guest-exec-status", "arguments": {"pid": 797 } }'

qemu-guest-agent 不支持 hmp 调用

虚拟机里的 /etc/sysconfig/qemu-ga 内容中的 BLACKLIST_RPC 参数可以配置禁止哪些指令

官方参考文档

# qemu
https://qemu.weilnetz.de/doc/qemu-doc.html

# qmp
https://qemu.weilnetz.de/doc/qemu-qmp-ref.html

# qemu-guest-agent
https://qemu.weilnetz.de/doc/qemu-ga-ref.html

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计5272字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中