一、qemu-guest-agent介绍

qemu-guest-agent简称ga,是运行在虚拟机内部的一个服务,可以用于执行宿主机上发送过来的命令。

qemu在宿主机和虚拟机之间创建了一个数据通道,这个数据通道的两端对应的分别是虚拟机内部的串口和宿主机上的unix socket文件。宿主机可以直接通过unix socket来对虚拟机执行一些操作,例如通过unix socket获取虚拟机中的ip地址等信息。

在libvirt中,提供了专门的virDomainQemuAgentCommand API的接口来执行与qemu-guest-agent之间的通信。

二、qemu-guest-agent使用方式

qemu-guest-agent使用十分简单,首先需要虚拟机的xml配置文件中有使用对应的channel。channel应该添加到devices标签中。

<channel type='unix'> 
    <source mode='bind' path='/var/lib/libvirt/qemu/org.qemu.guest_agent.0'/>
    <target type='virtio' name='org.qemu.guest_agent.0'/> 
    <address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>

在虚拟机内部需要安装qemu-guest-agent软件包

yum install qemu-guest-agent

启动qemu-guest-agent.service服务

systemctl start qemu-guest-agent.service

正常情况下,现在在宿主机上执行相关命令就能够实现与虚拟机的通信了。

在宿主机上执行virsh命令,进入virsh的命令行模式,执行如下命令获取qemu-agent-command能够执行的命令,其中centos8是虚拟机的名称。

qemu-agent-command centos8 '{"execute":"guest-info"}'

执行如下命令能够获取虚拟机的网络信息

 qemu-agent-command centos8 '{"execute":"guest-network-get-interfaces"}'

如果我们需要使用修改的unix socket端口,可以在虚拟机的配置文件中修改channel,例如我们创建一个新的名为org.qemu.guest_agent.1的串口

<channel type='unix'>
    <source mode='bind' path='/var/lib/libvirt/qemu/org.qemu.guest_agent.1'/> 
    <target type='virtio' name='org.qemu.guest_agent.1'/> 
    <address type='virtio-serial' controller='0' bus='0' port='1'/> 
</channel>

在虚拟机中需要手动修改qemu-guest-agent的服务文件/usr/lib/systemd/system/qemu-guest-agent.service,将原本配置为org.qemu.guest_agent.0的位置修改为org.qemu.guest_agent.1(如果需要多个channel可以创建额外的qemu-guest-agent服务文件并启动多个qemu-guest-agent服务)

然后再重新启动qemu-guest-agent服务。

在宿主机上,不能够直接使用virsh命令来进行连接了,而是需要使用socat命令连接对应的socket套接字,使用如下命令进行连接,在命令行中输入对应的命令执行。

socat unix-connect:/var/lib/libvirt/qemu/org.qemu.guest_agent.1 readline

然后输入

{"execute":"guest-info"}

如果需要执行带有参数的命令,可以执行如下命令创建一个/root/test的文件夹

qemu-agent-command centos8 '{"execute":"guest-exec","arguments":{"path":"mkdir","arg":[“-p”,"/root/test"],"capture-output":"true"}}'

执行完成后会返回一个pid,可以使用这个pid来查询上述命令是否执行成功,例如返回的pid是1588,可以执行如下命令

qemu-agent-command centos8 '{"execute":"guest-exec-status","arguments":{"pid":1588}}'

三、qemu-guest-agent禁用和启用命令配置

默认情况下,qemu-guest-agent服务禁用了某些命令,可以在虚拟机的/etc/sysconfig/qemu-ga文件中修改BLACKLIST_RPC字段,此字段表示了禁用的命令。

四、通过qemu-guest-agent向虚拟机中写入文件

如果需要向虚拟机中写入文件,必须要打开qemu-guest-agent中的guest-file-opne,guest-file-write和guest-file-close命令,在/etc/sysconfig/qemu-ga中修改。

guest-file-write命令只能够支持base64编码,因此在写入任何文件的时候需要将文件进行base64的编码。例如我们写一个DeInfate.java文件到虚拟机centos8的/root/.ssh目录中。

需要先将DeInfate.java的内容进行base64编码

cat DeInflate.java | base64 -w 0

先在虚拟机的/root/.ssh目录中创建一个DeInflate.java文件。

qemu-agent-command centos8 '{"execute":"guest-exec", "arguments":{"path":"touch","arg":["/root/.ssh/DeInflate.java"], "capture-output":true}}'

以读写的方式打开文件

qemu-agent-command centos8 '{"execute":"guest-file-open", "arguments":{"path":"/root/.ssh/DeInflate.java","mode":"w+"}}'

会返回一个句柄,假设返回的句柄是1000,执行写入操作

qemu-agent-command centos8 '{"execute":"guest-file-write", "arguments":{"handle":1000,"buf-b64":"LyoNCiAqIENvcHlyaWdodCAoYykgMjAxMSwgMjAxOCwgT3J==“}}‘

执行文件关闭操作

qemu-agent-command centos8 '{"execute":"guest-file-close","arguments":{"handle":1000}}'

此时查看虚拟机中的/root/.ssh/DeInflate.java文件应该能够看到输入的内容了。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐