Czy istnieje sposób ustalenia, który interfejs wirtualny należy do maszyny wirtualnej na hoście KVM?

10

Korzystam z qemu / kvm z mostkiem sieciowym. W maszynie hosta znajduje się kilka interfejsów sieciowych „vnetX” bez adresu IP. Szukam sposobu, aby dowiedzieć się, który vnetX należy do maszyny wirtualnej.

Próbowałem dopasować wartości adresów MAC na tych interfejsach do adresów MAC na maszynach wirtualnych (lub XML, który je definiuje), ale nie pasują.

Jest program brctl, który pokazuje interfejsy vnet należące do mostu, ale nie jest to użyteczna informacja.

Czy istnieje sposób na poznanie tej relacji? Dzięki!!

teista
źródło

Odpowiedzi:

14

Co powiesz na to (przykład na vnet13):

$ VNET=vnet13; for vm in $(virsh list | grep running | awk '{print $2}'); do virsh dumpxml $vm|grep -q "$VNET" && echo $vm; done

Tutaj używamy virsh dumpxmldo wyświetlania dynamicznych właściwości maszyny wirtualnej, które nie są dostępne w statycznej definicji XML maszyny wirtualnej w /etc/libvirt/qemu/foo.xml. Który vnetXinterfejs jest dołączony do której maszyny wirtualnej jest tak dynamiczną właściwością. To samo dotyczy adresów MAC maszyny wirtualnej.

daff
źródło
4
Używam tego lekką modyfikację listy, która VM którego interfejsu:for vm in $(virsh list | grep running | awk '{print $2}'); do echo -n "$vm:"; virsh dumpxml $vm| grep -oP "vnet\d+" ; done
zje
Jeśli sprawdzasz „węzeł” oVirt, możesz użyć tego samego polecenia, ale virsh powinien być uruchomiony w trybie „tylko do odczytu”. Wystarczy dodać parametr -r do każdego wywołania virsh.
karlacio
6

Spróbuj virsh dumpxml $domain, zobaczysz coś takiego:

  <interface type='network'>
  <mac address='52:54:00:9d:9d:10'/>
  <source network='default'/>
  <target dev='vnet1'/>
  <model type='e1000'/>
  <alias name='net1'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x0c' function='0x0'/>

alias nameto, co jest wykorzystywane w wierszu polecenia qemu-kvm, więc jeśli uruchomić ps -ef |grep qemu|grep net1z moim przykładzie widać rzeczywistą składnię poleceń używanych dla tego interfejsu.

dyasny
źródło
2

Każde z powyższych rozwiązań zakłada, że ​​maszynami wirtualnymi zarządza libvirt. Bez tego możliwe jest uruchamianie maszyn wirtualnych QEMU, w którym to przypadku nie można użyć virsh lub spojrzeć na XML, aby znaleźć odpowiedź.

W przypadku uruchamiania maszyn wirtualnych QEMU z wiersza polecenia „surowego”:

  1. tcpdump -i tap0 -f 'icmp' (zamień dowolny interfejs tapa, który Cię interesuje)

  2. Pinguj każdą kandydującą maszynę wirtualną, aż zobaczysz pakiety w śladzie. Interfejs, który śledzisz, gdy pojawiają się pakiety ICMP, jest tym, którego szukasz!

I odwrotnie, możesz uruchomić polecenie ping do konkretnej maszyny wirtualnej, a następnie tcpdump kolejno każdy interfejs z kranem, aż jeden się „zapali”. Zależy, czy chcesz znaleźć maszynę wirtualną pasującą do interfejsu dotykowego, czy interfejs zaczepu pasujący do maszyny wirtualnej.

Carlos Konstanski
źródło
0

Adres MAC vnetXinterfejsów należy do hosta, a nie do gościa. brctl showmacs br0pokaże adresy MAC wykryte przez most, ale trzeba będzie wtedy odwołać się do numeru portu z listą interfejsów z brctl show.

mgorven
źródło
0

Dopasuj adresy IP z pamięci podręcznej Arp do maszyny wirtualnej

# vm mac address list
for vm in $(virsh list | grep running | awk '{print $2}'); do \
  echo -n "$vm "; \
  virsh dumpxml $vm| grep -oP "52:54:[\da-f:]+" ; 
done > vm_mac.list

# vm ip list
arp -i virbr0 | grep '52:' | while read addr ; do \
  ip=$(echo $addr | awk '{print $1}'); \
  mac=$(echo $addr | awk '{print $3}'); \
  vm=$(grep "$mac" vm_mac.list | awk '{print $1}'); \
  echo "$vm $ip $mac"; \
done | sort

Przykładowe dane wyjściowe:

vm66 192.168.191.112 52:54:00:ab:e8:cb
vm67 192.168.191.207 52:54:00:88:66:e7
vm67 192.168.191.241 52:54:00:88:66:e7
vm68 192.168.191.197 52:54:00:c5:e1:30
vm69 192.168.191.254 52:54:00:b6:f6:0f
vm70 192.168.191.232 52:54:00:08:7f:49
vm71 192.168.191.113 52:54:00:e7:6f:2b
phiphi
źródło
0

Na podstawie odpowiedzi @daff:

for vm in $(virsh list | grep running | awk '{print $2}'); do echo "$vm: " && virsh dumpxml $vm | grep  "vnet" | sed 's/[^'']*''\([^'']*\)''[^'']*/\t\1/g'; done

Przykład wyjścia:

vm1:
    vnet0
vm2:
    vnet1
vm3:
    vnet2
vm4:
    vnet3
    vnet4
vm5:
    vnet5
0x3333
źródło
0
for vm in $(virsh list  --state-running --name); do \
echo $vm; \
virsh domifaddr $vm; \
done

Przykładowe dane wyjściowe:

client1

Nombre     dirección MAC       Protocol     Address
------------------------------------------------------------------------------

vnet2      52:54:00:2c:7a:f0    ipv4         192.168.122.63/24
Rafael Fernandez
źródło
Przesłałem poprawkę do twoich cytatów kodu, ale powinieneś dołączyć wyjaśnienie wraz z kodem.
Cory Knutson