¿Hay alguna manera de determinar qué interfaz virtual pertenece a una máquina virtual en un host kvm?

10

Estoy usando qemu / kvm con conexión en red en puente. En la máquina host hay varias interfaces de red "vnetX" sin IP. Estoy buscando una manera de saber qué vnetX pertenece a una máquina virtual.

Intenté hacer coincidir los valores de la dirección MAC en estas interfaces con los MAC en las máquinas virtuales (o el XML que los define), pero no coincide.

Hay brctl show que muestra las interfaces vnet que pertenecen a un puente, pero esta no es información útil.

¿Hay alguna manera de conocer esa relación? ¡¡Gracias!!

teísta
fuente

Respuestas:

14

¿Qué tal esto (ejemplo para vnet13):

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

Aquí usamos virsh dumpxmlpara mostrar propiedades dinámicas sobre la VM, que no están disponibles en la definición XML estática de la VM en /etc/libvirt/qemu/foo.xml. Qué vnetXinterfaz está conectada a qué VM es una propiedad tan dinámica. Lo mismo ocurre con las direcciones MAC de la VM.

narciso
fuente
44
Utilizo esta ligera modificación para enumerar qué vm tiene qué interfaz:for vm in $(virsh list | grep running | awk '{print $2}'); do echo -n "$vm:"; virsh dumpxml $vm| grep -oP "vnet\d+" ; done
zje
Si está investigando un 'nodo' oVirt, puede usar el mismo comando, pero virsh debe ejecutarse en modo 'solo lectura'. Simplemente agregue el parámetro -r a cada llamada de virsh.
karlacio
6

Intenta virsh dumpxml $domain, verás algo como:

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

esto alias namees lo que se usa en la línea de comando qemu-kvm, por lo que si ejecuta ps -ef |grep qemu|grep net1desde mi ejemplo, verá la sintaxis de comando real utilizada para esta interfaz.

dyasny
fuente
2

Cada una de las soluciones dadas anteriormente supone que las máquinas virtuales están siendo administradas por libvirt. Es muy posible ejecutar máquinas virtuales QEMU sin eso, en cuyo caso no puede usar virsh o mirar XML para encontrar la respuesta.

En el caso de ejecutar máquinas virtuales QEMU desde una línea de comando "sin formato":

  1. tcpdump -i tap0 -f 'icmp' (sustituya la interfaz de tap que le interese)

  2. Haga ping a cada máquina virtual candidata hasta que vea paquetes en la traza. ¡La interfaz que está rastreando cuando aparecen los paquetes ICMP es la que está buscando!

Por el contrario, puede iniciar un ping a una VM en particular y luego tcpdump cada interfaz de toque a su vez hasta que uno "se enciende". Depende de si está interesado en encontrar la VM que coincida con la interfaz de tap, o la interfaz de tap que coincida con la VM.

Carlos Konstanski
fuente
0

La dirección MAC de las vnetXinterfaces pertenece al host, no al invitado. brctl showmacs br0mostrará los MAC detectados por el puente, pero luego deberá hacer una referencia cruzada del número de puerto con la lista de interfaces de brctl show.

mgorven
fuente
0

Haga coincidir las direcciones IP de la caché Arp con la VM

# 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

Salida de muestra:

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
Phi Phi
fuente
0

Según la respuesta de @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

Ejemplo de salida:

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

Salida de ejemplo:

client1

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

vnet2      52:54:00:2c:7a:f0    ipv4         192.168.122.63/24
Rafael Fernández
fuente
Envié una edición para sus cotizaciones de código, pero debe incluir una explicación junto con su código.
Cory Knutson el