Existe-t-il un moyen de déterminer quelle interface virtuelle appartient à une machine virtuelle dans un hôte kvm?

10

J'utilise qemu / kvm avec un réseau ponté. Sur la machine hôte, il existe plusieurs interfaces réseau "vnetX" sans IP. Je cherche un moyen de savoir quels vnetX appartiennent à une machine virtuelle.

J'ai essayé de faire correspondre les valeurs d'adresse MAC sur ces interfaces avec les MAC sur les machines virtuelles (ou le XML qui les définit), mais ne correspond pas.

Il y a brctl show qui montre les interfaces vnet qui appartiennent à un pont, mais ce ne sont pas des informations utiles.

Existe-t-il un moyen de connaître cette relation? THX!!

théiste
la source

Réponses:

14

Que diriez-vous de cela (exemple pour vnet13):

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

Ici, nous utilisons virsh dumpxmlpour afficher les propriétés dynamiques de la machine virtuelle, qui ne sont pas disponibles dans la définition XML statique de la machine virtuelle dans /etc/libvirt/qemu/foo.xml. Quelle vnetXinterface est attachée à quelle VM est une telle propriété dynamique. Il en va de même pour les adresses MAC de la machine virtuelle.

daff
la source
4
J'utilise cette légère modification pour lister quel vm a quelle interface:for vm in $(virsh list | grep running | awk '{print $2}'); do echo -n "$vm:"; virsh dumpxml $vm| grep -oP "vnet\d+" ; done
zje
Si vous étudiez un «nœud» oVirt, vous pouvez utiliser la même commande mais virsh doit être exécuté en mode «lecture seule». Ajoutez simplement le paramètre -r à chaque appel virsh.
karlacio
6

Essayez virsh dumpxml $domain, vous verrez quelque chose comme:

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

l' alias nameest ce qui est utilisé dans la ligne de commande qemu-kvm, donc si vous exécutez ps -ef |grep qemu|grep net1de mon exemple, vous verrez la syntaxe de commande réelle utilisée pour cette interface.

Dyasny
la source
2

Chacune des solutions données ci-dessus suppose que les machines virtuelles sont gérées par libvirt. Il est tout à fait possible d'exécuter des machines virtuelles QEMU sans cela, auquel cas vous ne pouvez pas utiliser virsh ou regarder XML pour trouver la réponse.

Dans le cas de l'exécution de machines virtuelles QEMU à partir d'une ligne de commande "brute":

  1. tcpdump -i tap0 -f 'icmp' (remplacez l'interface tactile qui vous intéresse)

  2. Envoyez un ping à chaque machine virtuelle candidate jusqu'à ce que vous voyiez des paquets dans la trace. L'interface que vous tracez lorsque les paquets ICMP apparaissent est celle que vous recherchez!

Inversement, vous pouvez démarrer un ping vers une machine virtuelle particulière, puis tcpdump chaque interface tactile à tour de rôle jusqu'à ce qu'une "s'allume". Cela dépend si vous êtes intéressé à trouver la machine virtuelle qui correspond à l'interface tactile, ou l'interface tactile qui correspond à la machine virtuelle.

Carlos Konstanski
la source
0

L'adresse MAC des vnetXinterfaces appartient à l'hôte, pas à l'invité. brctl showmacs br0affichera les MAC détectés par le pont, mais vous devrez alors croiser le numéro de port avec la liste des interfaces brctl show.

mgorven
la source
0

Faire correspondre les adresses IP du cache Arp à la machine virtuelle

# 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

Exemple de sortie:

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
la source
0

Basé sur la réponse @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

Exemple de sortie:

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

Exemple de sortie:

client1

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

vnet2      52:54:00:2c:7a:f0    ipv4         192.168.122.63/24
Rafael Fernandez
la source
J'ai soumis une modification pour vos citations de code, mais vous devez inclure une explication avec votre code.
Cory Knutson