QGA 服务介绍
QGA 是 Qemu-Guest-Agent 的简称,即是在虚拟机上增加一个串口与宿主机进行socket通信,宿主机与虚拟机内的 QGA 通讯就扩展了对虚拟机的控制能力,例如在宿主机上获取虚拟机的 IP 地址等和监控功能。
qemu virtio串口模拟参数:
/usr/bin/kvm \
-device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x6 \
-device isa-serial,chardev=charserial1,id=serial1 \
-chardev socket,id=charchannel0,path=/var/lib/libvirt/qemu/org.qemu.guest_agent.0.instance-00000304.sock,server,nowait \
-device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,\
name=org.qemu.guest_agent.0
可根据 xml 文件来进行判断虚拟机是否开启了 QGA 服务:
<channel type='unix'>
<source mode='bind' path='/var/lib/libvirt/qemu/org.qemu.guest_agent.0.instance-00000304.sock'/>
<target type='virtio' name='org.qemu.guest_agent.0' state='connected'/>
<alias name='channel1'/>
<address type='virtio-serial' controller='0' bus='0' port='2'/>
</channel>
命令调用
通过宿主机调用虚拟机命令:
# 查看其所有支持的命令
virsh qemu-agent-command instance-000004db --pretty '{"execute":"guest-info"}'
# 测试 qga 服务是否联通,如果不返回错误信息,则成功
virsh qemu-agent-command instance-000004db --cmd '{"execute":"guest-ping"}'
# 获取虚拟机系统时间(相对于1970-01-01 in UTC)
virsh qemu-agent-command instance-000004db --cmd '{"execute":"guest-get-time"}'
# 虚拟机里执行命令,主要通过该命令获取监控项信息
virsh qemu-agent-command instance-000004db '{"execute":"guest-command-execute","arguments":{"path":"ping 192.168.17.44 -c 1"}}'
实时监控功能流程
核心代码:
def get_instance_monitor_info(self, instance, **kwargs):
...
#监控项
support_meters = ['disk', 'cpu', 'memory', 'network']
meters = kwargs.get('meter', 'None')
...
if monitor_info is None:
instance_uuid = instance.uuid
#获取监控数据
cmd = {'windows': self.qga_prefix +
'"python qga_main disk cpu memory network"}}',
'linux': self.qga_prefix +
'"qga_main disk cpu memory network"}}'}
try:
if instance.name not in self.domains:
self.add_domain(instance)
dom = self.domains.get(instance.name, None)
if dom is None:
return {}
# minimize the influence of qemuAgentCommand for cache
monitor_time = time.time()
try:
# 调用qga命令
output = libvirt_qemu.\
qemuAgentCommand(dom,
cmd[instance.os_type or 'linux'],
60, 0)
except:
...
#监控数据压缩
output = json.loads(output)
compress_output = output['return']['buf-b64'].strip()
当前监控方案问题
1、依赖云主机内部的python解释器;
2、定位问题一般都需要登录到云主机内部进行,对于采用密钥对登录的云主机来说定位问题比较困难;
3、windows镜像依赖virtio vioserial 和 Balloon driver 等驱动的安装;
4、已经运行的云主机内部的监控相关文件更新困难,导致新监控项的添加、推送周期、推送地址等的修改也比较困难,灵活性较差。