基于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,另外在里增加qemu:command
<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
基于QMP实现对qemu虚拟机进行交互的更多相关文章
- 基于DevExpress实现对PDF、Word、Excel文档的预览及操作处理
http://www.cnblogs.com/wuhuacong/p/4175266.html 在一般的管理系统模块里面,越来越多的设计到一些常用文档的上传保存操作,其中如PDF.Word.Excel ...
- 基于Python实现对PDF文件的OCR识别
http://www.jb51.net/article/89955.htm https://pythontips.com/2016/02/25/ocr-on-pdf-files-using-pytho ...
- 利用QMP和QEMU虚拟机交互的几种方式
QMP是一种基于JSON格式的传输协议,我们能利用它与一个QEMU虚拟机实例进行交互,例如查询,更改虚拟机的状态,获取设备信息等等.下面是几种创建QMP的方法以及对其它的一些基本命令的使用: 1.基于 ...
- 基于spring-boot和docker-java实现对docker容器的动态管理和监控[附完整源码下载]
(我是个封面) docker简介 Docker 是一个开源的应用容器引擎,和传统的虚拟机技术相比,Docker 容器性能开销极低,因此也广受开发者喜爱.随着基于docker的开发者越来越多,doc ...
- struts2视频学习笔记 22-23(基于XML配置方式实现对action的所有方法及部分方法进行校验)
课时22 基于XML配置方式实现对action的所有方法进行校验 使用基于XML配置方式实现输入校验时,Action也需要继承ActionSupport,并且提供校验文件,校验文件和action类 ...
- 用 Python 脚本实现对 Linux 服务器的监控
目前 Linux 下有一些使用 Python 语言编写的 Linux 系统监控工具 比如 inotify-sync(文件系统安全监控软件).glances(资源监控工具)在实际工作中,Linux 系统 ...
- 用 Python 脚本实现对 Linux 服务器的网卡流量监控
*这篇文章网上已经有相关代码,为了加深印象,我做了相关批注,希望对朋友们有帮助 工作原理:基于/proc文件系统 Linux 系统为管理员提供了非常好的方法,使其可以在系统运行时更改内核,而不需要重新 ...
- 基于本地存储的kvm虚拟机在线迁移
基于本地存储的kvm虚拟机在线迁移 kvm虚拟机迁移分为4种(1)热迁移基于共享存储(2)热迁移基于本地存储(3)冷迁移基于共享存储(4)冷迁移基于本地存储 这里介绍的是基于本地存储的热迁移 动态块迁 ...
- Java Web学习系列——Maven Web项目中集成使用Spring、MyBatis实现对MySQL的数据访问
本篇内容还是建立在上一篇Java Web学习系列——Maven Web项目中集成使用Spring基础之上,对之前的Maven Web项目进行升级改造,实现对MySQL的数据访问. 添加依赖Jar包 这 ...
随机推荐
- SQLServer inner join,left join,right join,outer join 备忘备忘
LEFT JOIN LEFT JOIN 关键字会从左表那里返回所有的行,即使在右表中没有匹配的行. 即LEFT JOIN 的 ON 条件不会对数据行造成影响 RIGHT JOIN RIGHT JOIN ...
- ubuntu 16.04 php5 环境搭建
Ubuntu 16.04默认安装php7.0环境,但是php7目前兼容性并不是很好,如果自行安装php5需要清除php7的已安装包,否则会报错. 移除默认及已安装的PHP包 sudo dpkg -l ...
- 【转载】Java实现word转pdf
最近遇到一个项目需要把word转成pdf,GOOGLE了一下网上的方案有很多,比如虚拟打印.给word装扩展插件等,这些方案都依赖于ms word程序,在java代码中也得使用诸如jacob或jcom ...
- winform右键菜单
public partial class Form1 : Form { ContextMenuStrip cms; Bitmap bm ; public Form1() { InitializeCom ...
- (转)Bootstrap 之 Metronic 模板的学习之路 - (6)自定义和扩展
https://segmentfault.com/a/1190000006815041 前面我们将 Metronic 的结构和源码大致浏览了一遍,Metronic 整个文件包有三百多兆,在实际项目中, ...
- 【前端分享】jQuery.lazyload详解(转)
jQuery实现图片延迟加载,不知道是否可以节省带宽呢?有人知道吗?这究竟只是一个视觉特效还是真的能延迟加载减少服务器的请求呢? <script type="text/javascri ...
- WebStorm 配置 svn
1.下载 SlikSVN. 2.安装.路径 D:\Program Files\slik\bin. 3.在WebStorm中配置 file->settings->Version Co ...
- 洛谷P3195 [HNOI2008]玩具装箱TOY 斜率优化
Code: #include<cstdio> #include<algorithm> using namespace std; const int maxn = 100000 ...
- Alios-Things的学习与使用(1)
目录 Alios-Things的学习与使用 1.简介 1.1 为什么要学alios-Things 2. 环境搭建 2.1 使用docker toolbox安装docker 2.2 测试使用dockde ...
- 51nod-活动安排问题之二
有若干个活动,第i个开始时间和结束时间是[Si,fi),活动之间不能交叠,要把活动都安排完,至少需要几个教室? 分析:能否按照之一问题的解法,每个教室安排尽可能多的活动,即按结束时间排序,再贪心选择不 ...