Kvm

如何使用 qemu-guest-agent 獲取 VM 的主機名和 IP 地址

  • January 24, 2022

我正在使用執行虛擬機

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

之後,閱讀wiki後,我已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。

為了清楚起見,我已經檢查瞭如何找到 KVM 虛擬機的 IP 地址,我可以通過 SSH 進入它嗎?,但我沒有興趣使用virt-manager.

QEMU 文件範例中,socat可用於通過其套接字查詢來賓代理的 API。由於一切似乎都在 JSON 中,最好也jq安裝該工具。

mdroth@illuin:~$ sudo socat unix-connect:/tmp/qga.sock readline

$$ … $$

{"execute": "guest-info"}

$$ … $$

上面的命令除其他外提供了可以發送的所有可能命令的列表。

在我的 Debian 系統上,readline功能在 中被禁用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"'

引用自:https://unix.stackexchange.com/questions/687594