tag: qemu-ga, qemu guest agent, kvm, guest-file-write, inject
小慢哥的原创文章,欢迎转载
目录▪ 为什么要“注入”到VM内部
▪ 如何实现“注入”
▪ Step1. 为VM配置channel
▪ Step2. 部署qemu-ga
▪ Step3. 注入操作说明
▪ Step4. Base64计算
▪ Step5. 开始注入
▪ 附1. qemu-ga支持的所有指令
▪ 附2. 配置多个channel
▪ 参考文档
原因很简单:在VM外部无法实现,只能进入到VM内来实现
KVM不像Docker(container)只是对进程进行cgroup隔离,KVM是全封闭的环境。
对于基于KVM的虚拟机来说,通常存在如下需求:
▷ 在线修改密码
▷ 在线增加公钥
▷ 在线采集性能(如cpu使用率、负载、内存使用量等性能指标)
▷ 其他各种在线功能
上述这些场景的共性:仅在VM外部是无法实现的。因此就有了多种解决方案,但无论哪种解决方案都要同时满足以下2点才能实现:
▷ 通道:在VM内部与外部(宿主)之间打开一个通道,可以进行数据交互
▷ agent:在VM内部种下一个agent,用于接收外部的指令并反馈结果
在VM内部种下agent的做法可以形象地称之为"inject 注入"
如何实现“注入”第一步,打开通道
有2类方法:
▷ 走网络:会复杂一些,需要提前预插入一张管理网卡,或者利用已有网卡+特殊的路由来确保数据能走出去,这带来了较为复杂的网络拓扑
▷ 走设备:简单很多,只需在VM内部和宿主之间建立一个设备通道即可。比如为KVM虚拟机增加一个字符设备,并在宿主上映射为一个socket文件。字符设备与socket之间形成了一个channel,通过该channel就可以进行内外数据互通
“走网络”不是本文想要介绍的,接下来所有内容均为“走设备”
第二步,启动agent
在虚拟机里启动一个agent,实时读取字符设备,实现与宿主的数据交互。
在channel中发送与接收什么样的数据,是可以自己定义的,也可以使用KVM官方实现的解决方案,称为Qemu Guest Agent,简称qemu-ga。它包含2方面:
▷ channel中传送数据的协议定义:基于JSON的格式
▷ VM内的agent:启动一个名叫qemu-ga的守护进程,该进程将从字符设备里获取传进来的json指令,然后根据指令执行相关命令,并将结果通过字符设备返回给宿主
qemu-ga的好用之处在于其封装的指令兼容了一些不同的操作系统,比如写文件指令guest-file-write,既可以用于linux也可以用于windows。
关于qemu-ga的配置与使用,笔者之前已写过一篇文章《基于QMP实现对qemu虚拟机进行交互》,详细介绍其工作原理及基本使用方法,这里附上地址
https://www.toutiao.com/i6646012291059810823/由于本文主题是“注入写文件”,因此接下来将重点阐述如何写文件,不过也会将qemu-ga的部署与启用方法再次贴出。
Step1. 为VM配置channel通过libvirt启动的虚拟机,可以在XML里增加一段配置
<channel type='unix'> <source mode='bind' path='/tmp/channel.sock'/> <target type='virtio'/> </channel>注意:上面这段配置要放在<devices>段落中
Step2. 部署qemu-ga1️⃣ 安装qemu-ga
在VM内部安装并启动qemu-ga,linux和windows均支持qemu-ga,许多linux发行商都会提供自己的qemu-ga,比如rhel/CentOS、Fedora、Ubuntu、openSUSE都有提供编译好的qemu-ga,可以直接下载使用。而windows系统需要下载virtio-win,其中有包含一些virtio的win驱动以及qemu-ga安装包,也可以仅下载qemu-ga安装包
# rhel/centos yum install qemu-guest-agent # windows,最新virtio-win iso https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/ # windows,最新qemu-ga安装包 https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-qemu-ga/windows的qemu-ga安装包如图所示
2️⃣ 启动qemu-ga
以centos7为例
# 启动qemu-ga守护进程 systemctl start qemu-guest-agent # 加入开机启动 systemctl enable qemu-guest-agent启动后通过systemctl status qemu-guest-agent应当能看到进程已启动,如图所示