我正在使用 KVM 进行虚拟化并通过 Libvirt 守护程序对其进行管理。
如何配置 Libvirt 或 KVM 来监听发送到虚拟机 NIC 的 MAC 地址的网络唤醒数据包,并在收到此类数据包时启动虚拟机?
答案1
我发现 Libvirt-wakeonlan 似乎可以做到这一点。我不知道它有多成熟,效果如何。这种方法似乎是正确的。https://github.com/simoncadman/libvirt-wakeonlan
答案2
您可以使用我的脚本,它本质上与 libvirt-wakeonlan 相同,我这样做是因为我无法让 libvirt-wakeonlan 工作......这只是一个简单的脚本,您可以将它放入启动脚本并让它在启动时运行。
它监听 udp 端口 9(据我所知有时也会使用端口 7,但我使用的远程 vnc/rdp guacamole 会在端口 9 发送信息),并在看到魔术包时检查 MAC 地址。如果 virsh 中有一个具有此 MAC 地址的虚拟机,它将唤醒该机器。
https://gitlab.com/-/snippets/2183494
#!/bin/bash
nc -dknl -p 9 -u | # listen to udp port 9 for packets, check if it is a magic packet
stdbuf -o0 xxd -c 6 -p |
stdbuf -o0 uniq |
stdbuf -o0 grep -v 'ffffffffffff' |
while read ; do
mac="${REPLY:0:2}:${REPLY:2:2}:${REPLY:4:2}:${REPLY:6:2}:${REPLY:8:2}:${REPLY:10:2}"
# parse mac found in magic packet
for i in $(virsh list --all --name); do # loop through libvirt machines
vmmac=$(virsh dumpxml $i | grep "mac address" | awk -F\' '{ print $2}') # get each machines MAC
if [ $vmmac = $mac ]; then # compare MACs, if match do;
echo $mac;
echo $i;
virsh start $i
virsh resume $i
fi
done
done
答案3
由于我目前无法对 Gotschi 的回答发表评论https://serverfault.com/a/1079289/962574(目前还没有声誉),我将在这里添加我的调整:
我自己修改了脚本。不确定不同的 netcat 版本是否适用,但在 Fedora 上需要进行一些调整。
#!/bin/bash
# listen to udp port 9 for packets, check if it is a magic packet
netcat -dkn -l 9 -u | stdbuf -o0 xxd -c 6 -p | stdbuf -o0 uniq | stdbuf -o0 grep -v 'ffffffffffff' | while read
do
echo "Got triggered with $REPLY"
mac="${REPLY:0:2}:${REPLY:2:2}:${REPLY:4:2}:${REPLY:6:2}:${REPLY:8:2}:${REPLY:10:2}"
# loop through libvirt machines
for vm in $(virsh list --all --name)
do
# Get the MAC address and compare with the magic packet
vmmac=$(virsh dumpxml $vm | grep "mac address" | awk -F\' '{ print $2}')
if [ $vmmac = $mac ]
then
state=$(virsh list --all|awk -v vm=$vm '{ if ($2 == vm ) print $3 }')
echo "Found $vm with $mac in $state state"
# Dependent on the state, resume or start
[ $state == "paused" ] && virsh -q resume $vm && virsh domtime --domain $vm --now
[ $state == "shut" ] && virsh -q start $vm
fi
done
done
答案4
非常好的脚本。如果 libvirt 机器有多个网卡,我会用循环来增强它
#!/bin/bash
virshCmd="ssh [email protected] virsh"
# listen to udp port 9 for packets, check if it is a magic packet
netcat -dkn -l 9 -u | stdbuf -o0 xxd -c 6 -p | stdbuf -o0 uniq | stdbuf -o0 grep -v 'ffffffffffff' | while read; do
# echo "Got triggered with $REPLY"
mac="${REPLY:0:2}:${REPLY:2:2}:${REPLY:4:2}:${REPLY:6:2}:${REPLY:8:2}:${REPLY:10:2}"
# echo "Got wol-package. Requested mac-addr: ${mac}"
# loop through libvirt machines
for vm in $( ${virshCmd} list --all --name); do
# Get the MAC address and compare with the magic packet
vmmacs=$( ${virshCmd} dumpxml $vm | grep "mac address" | awk -F\' '{ print $2}')
echo "VM: ${vm}"
for vmmac in ${vmmacs//\\n/
}; do
echo " MAC-Addr: $vmmac"
if [ $vmmac = $mac ]; then
state=$( ${virshCmd} list --all|awk -v vm=$vm '{ if ($2 == vm ) print $3 }')
echo "Found $vm with $mac in $state state"
# Dependent on the state, resume or start
[ $state == "paused" ] && ${virshCmd} -q resume $vm && ${virshCmd} domtime --domain $vm --now
[ $state == "pausiert" ] && ${virshCmd} -q resume $vm && ${virshCmd} domtime --domain $vm --now
[ $state == "shut" ] && ${virshCmd} -q start $vm
[ $state == "ausschalten" ] && ${virshCmd} -q start $vm
fi
done
done
echo ""
done