如何使用 qemu-guest-agent 获取虚拟机的主机名和 IP 地址

如何使用 qemu-guest-agent 获取虚拟机的主机名和 IP 地址

我正在使用运行虚拟机

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"'

相关内容