qemu guest agent簡稱qga, 是運行在虛擬機內部的一個守護程序(qemu-guest-agent.service),他可以管理應用程序,執行宿主機發出的命令。
QEMU為宿主機和虛擬機提供了一個數據通道(channel),這個通道的兩端分別是在虛擬機內看到的串口和在宿主機上看到的unix socket文件。
宿主機與虛擬機內的qga通訊就擴展了對虛擬機的控制能力,例如在宿主機上獲取虛擬機的ip地址等。
libvrit提供了專門的virDomainQemuAgentCommand API(對應virsh qemu-agent-command命令)來和qemu-guest-agent通訊,
另外有些libvirt內置api也可以支持qga,例如reboot、shutdown等。
下面的實踐分為兩種方式,虛擬機的channel的target的name使用org.qemu.guest_agent.0和不是用org.qemu.guest_agent.0。
兩種方式在libvirt和宿主機中的qemu-guest-agent中都有所不同。
【使用org.qemu.guest_agent.0】
宿主機上libvirt的虛擬機xml配置channel:
<channeltype='unix'>
<sourcemode='bind' path='/var/lib/libvirt/qemu/org.qemu.guest_agent.0'/>
<targettype='virtio' name='org.qemu.guest_agent.0'/>
</channel>
注意這里target的name要使用org.qemu.guest_agent.0
虛擬機內部:
yum install qemu-guest-agent
setenforce0
systemctl restart qemu-guest-agent.service
在宿主機上測試功能:
virsh
virsh #qemu-agent-commandcentos '{"execute":"guest-info"}'
virsh #qemu-agent-commandcentos '{"execute":"guest-network-get-interfaces"}'
virsh # reboot --mode agent centos
上面的命令直接讀出了虛擬機中的ip地址信息。
【不使用org.qemu.guest_agent.0】
如果在宿主機上libvirt的xml配置channel中target的name不是org.qemu.guest_agent.0,例如下面的org.qemu.guest_agent.1。
那么在宿主機上的libvirt將不會建立與socket建立連接。在虛擬機上qemu-guest-agent服務也無法運行。
宿主機上的libvirt的xml:
<channeltype='unix'>
<sourcemode='bind' path='/var/lib/libvirt/qemu/org.qemu.guest_agent.1'/>
<targettype='virtio' name='org.qemu.guest_agent.1'/>
</channel>
不使用org.qemu.guest_agent.0的情況下怎么處理呢?
首先,在虛擬機內部通訊串口的名字變為了org.qemu.guest_agent.1,此時需要手動修改/lib/systemd/system/qemu-guest-agent.service文件,把所有的默認org.qemu.guest_agent.0改為用戶配置的名字org.qemu.guest_agent.1。
其次,在宿主機上自己去連接socket文件:
[root@node2 ~]#socat unix-connect:/var/lib/libvirt/qemu/org.qemu.guest_agent.1 readline
{"execute": "guest-info"}
【功能簡單介紹】
注:帶*指的是win也支持
guest-sync-delimited*
宿主機發送一個int數字給qga,qga返回這個數字,並且在后續返回字符串響應中加入ascii碼為0xff的字符,
其作用是檢查宿主機與qga通信的同步狀態,主要用在宿主機上多客戶端與qga通信的情況下客戶端間切換過程的狀態同步檢查,
比如有兩個客戶端A、B,qga發送給A的響應,由於A已經退出,目前B連接到qga的socket,所以這個響應可能被B收到,如果B連接到socket之后,立即發送該請求給qga,響應中加入了這個同步碼就能區分是A的響應還是B的響應;
在qga返回宿主機客戶端發送的int數字之前,qga返回的所有響應都要忽略。
guest-sync*
與上面相同,只是不在響應中加入0xff字符
guest-ping*
Ping the guest agent, a non-error return implies success
guest-get-time*
獲取虛擬機時間(返回值為相對於1970-01-01 in UTC,Time in nanoseconds.)
guest-set-time*
設置虛擬機時間(輸入為相對於1970-01-01 in UTC,Time in nanoseconds.)
guest-info*
返回qga支持的所有命令
guest-shutdown*
關閉虛擬機(支持halt、powerdown、reboot,默認動作為powerdown)
guest-file-open
打開虛擬機內的某個文件(返回文件句柄)
guest-file-close
關閉打開的虛擬機內的文件
guest-file-read
根據文件句柄讀取虛擬機內的文件內容(返回base64格式的文件內容)
guest-file-write
根據文件句柄寫入文件內容到虛擬機內的文件
……