我正在使用运行虚拟机
qemu-system-x86_64 -accel kvm,thread=multi -cpu host -smp 1 -m 2048 \
-drive file=ubuntu-server1.qcow2,if=virtio -vga virtio -display none -daemonize \
-nic bridge,model=virtio-net-pci,mac=DE:AD:BE:EF:E0:00
要获取 IP 地址,我必须使用:
ps -ef | grep qemu
arp | grep -i DE:AD:BE:EF:38:C4
ip neigh | grep -i DE:AD:BE:EF:38:C4
之后,阅读维基百科,我已经qemu-guest-agent
在来宾中安装并启用了。
sudo apt install qemu-guest-agent
sudo systemctl start qemu-guest-agent
sudo systemctl enable qemu-guest-agent
我已经使用运行虚拟机
qemu-system-x86_64 -accel kvm,thread=multi -cpu host -smp 1 -m 2048 \
-drive file=ubuntu-server1.qcow2,if=virtio -vga virtio -display none -daemonize \
-nic bridge,model=virtio-net-pci,mac=DE:AD:BE:EF:E0:00 \
-chardev socket,path=/tmp/qga.sock,server,nowait,id=qga0 \
-device virtio-serial \
-device virtserialport,chardev=qga0,name=org.qemu.guest_agent.0
所以,套接字位于/tmp/qga.sock
.
现在我不明白如何使用这个套接字来获取来宾的主机名和IP。
为了清楚起见,我已经检查过如何找到可以通过 SSH 连接的 KVM 虚拟机的 IP 地址?,但我没兴趣使用virt-manager
。
答案1
来自QEMU 文档例如,socat
可用于通过套接字查询访客代理的 API。由于一切似乎都是 JSON 格式,因此最好jq
也安装该工具。
mdroth@illuin:~$ sudo socat unix-connect:/tmp/qga.sock readline
[...]
{"execute": "guest-info"}
[...]
上面的命令除其他外还给出了可以发送的所有可能命令的列表。
在我的 Debian 系统上,阅读线功能被禁用于socat
,手册页告诉我们使用stdio
(alias -
) 来代替。唉,有时输出不会发生或不完整,我怀疑socat
在这种情况下不能最佳地处理 EOF 条件。在左侧添加延迟似乎可以解决此问题。
这变成(作为 root 或适当的用户):
{ echo '{"execute": "guest-info"}'; sleep 2; } | socat unix-connect:/tmp/qga.sock -| jq .
[...]
{
"enabled": true,
"name": "guest-network-get-interfaces",
"success-response": true
},
[...]
现在可以发送{"execute": "guest-network-get-interfaces"}
并使用一些过滤器(并且一些训练) 使用jq
:
# { echo '{"execute": "guest-network-get-interfaces"}'; sleep 2; } |
socat unix-connect:/tmp/qga.sock - |
jq -j '."return"[] | ."name", (."ip-addresses"[] | " ", ."ip-address","/",."prefix"),"\n"'
lo 127.0.0.1/8 ::1/128
ens3 192.0.2.2/24
空值(没有地址的接口)的错误处理留作练习。
对于主机名部分,更简单,有一个值。命令是"guest-get-host-name"
:
{ echo '{"execute": "guest-get-host-name"}'; sleep 2; } | socat unix-connect:/tmp/qga.sock - | jq -r '."return"."host-name"'