¿Obtener una lista de clientes DHCP con KVM + libvirt?

11

Tengo varias máquinas virtuales ejecutándose en Ubuntu 9.10 a través de KVM + libvirt. Quiero poder averiguar la dirección IP que se ha asignado a cada host sin abrir físicamente una "consola" física para cada máquina e invocar ifconfig.

Considerar:

rascher @ localhost: ~ $ virsh -c qemu: /// lista del sistema --todos
Conexión a uri: qemu: /// system
 Id Nombre Estado
----------------------------------
  1 máquina1 corriendo
  2 machine2 funcionando
  - máquina3 apagada

Mi configuración de red se ve así:

<network>
  <name>default</name>
  <uuid>1be...</uuid>
  <forward mode='route' dev="eth0"/>
  <bridge name='virbr0' stp='on' forwardDelay='0' />
  <ip address='192.168.122.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.122.2' end='192.168.122.254' />
    </dhcp>
  </ip>
</network>

Entonces, ¿cómo puedo obtener una lista que diga:

máquina1 dirección IP = 192.168.122.16
dirección IP de machine2 = 192.168.122.238
...

Jugué con arp:

rascher @ localhost: ~ $ arp
Dirección HWtype HWaddress Flags Mask Iface
192.168.122.238 éter 00: 16: 36: 00: 61: b0 C virbr0
192.168.122.16 éter 00: 16: 36: 52: e8: 9c C virbr0
...

Pero esto no se asigna a la identificación de una máquina virtual.

¿Hay alguna herramienta (a través de la línea de comando virsho virt-*) que pueda determinar esta información? ¿O necesito tener un script sofisticado que se ejecute en cada VM individual, verifique su propia IP e informe al sistema operativo host?

rascher
fuente

Respuestas:

10

Esta característica fue solicitada hace mucho tiempo. Ahora libvirt lo admite al proporcionar dos nuevos comandos: domifaddr y net-dhcp-leases

 Usage: domifaddr <domain> [interface] [--full] [--source lease|agent]

 Example outputs:
 virsh # domifaddr f20 --source agent
 Name       MAC address          Protocol     Address
 -------------------------------------------------------------------------------
 lo         00:00:00:00:00:00    ipv4         127.0.0.1/8
 -          -                    ipv6         ::1/128
 eth0       52:54:00:2e:45:ce    ipv4         10.1.33.188/24
 -          -                    ipv6         2001:db8:0:f101::2/64
 -          -                    ipv6         fe80::5054:ff:fe2e:45ce/64
 eth1       52:54:00:b1:70:19    ipv4         192.168.105.201/16
 -          -                    ipv4         192.168.201.195/16
 -          -                    ipv6         2001:db8:ca2:2:1::bd/128
 eth2       52:54:00:36:2a:e5    N/A          N/A
 eth3       52:54:00:20:70:3d    ipv4         192.168.105.240/16
 -          -                    ipv6         fe80::5054:ff:fe20:703d/64

 virsh # domifaddr f20 --full
 Name       MAC address          Protocol     Address
 -------------------------------------------------------------------------------
 vnet0      52:54:00:2e:45:ce    ipv6         2001:db8:0:f101::2/64
 vnet1      52:54:00:b1:70:19    ipv4         192.168.105.201/16
 vnet1      52:54:00:b1:70:19    ipv6         2001:db8:ca2:2:1::bd/128
 vnet3      52:54:00:20:70:3d    ipv4         192.168.105.240/16

 virsh # domifaddr f20 eth0 --source agent --full
 Name       MAC address          Protocol     Address
 -------------------------------------------------------------------------------
 eth0       52:54:00:2e:45:ce    ipv4         10.1.33.188/24
 eth0       52:54:00:2e:45:ce    ipv6         2001:db8:0:f101::2/128
 eth0       52:54:00:2e:45:ce    ipv6         fe80::5054:ff:fe2e:45ce/64

For eth0, ipv6 is managed by libvirt, but ipv4 is not.
For eth1, the second IP is created using ip aliasing.
For eth2, there is no IP configured as of yet.
For eth3, only ipv4 has been configured.
fd00::/8 are private ipv6 ranges. Hence not visible through --source lease

En un escenario diferente:

 Example Usage: net-dhcp-leases <network> [mac]

 virsh # net-dhcp-leases --network default6
 Expiry Time          MAC address        Protocol  IP address                Hostname        Client ID or DUID
 -------------------------------------------------------------------------------------------------------------------
 2014-06-16 03:40:14  52:54:00:85:90:e2  ipv4      192.168.150.231/24        fedora20-test   01:52:54:00:85:90:e2
 2014-06-16 03:40:17  52:54:00:85:90:e2  ipv6      2001:db8:ca2:2:1::c0/64   fedora20-test   00:04:b1:d8:86:42:e1:6a:aa:cf:d5:86:94:23:6f:94:04:cd
 2014-06-16 03:34:42  52:54:00:e8:73:eb  ipv4      192.168.150.181/24        ubuntu14-vm     -
 2014-06-16 03:34:46  52:54:00:e8:73:eb  ipv6      2001:db8:ca2:2:1::5b/64   -               00:01:00:01:1b:30:c6:aa:52:54:00:e8:73:eb
Nehal J Wani
fuente
4

libvirt usa dnsmasq para proporcionar DHCP a los invitados, por lo que puede rastrear /var/log/daemon.log o explorar el archivo de arrendamientos en / var / lib / libvirt para obtener una asignación de IP a nombre de host.

James
fuente
2

Entonces, al investigar esto, descubrí que libvirt usa dnsmasq para hacer DHCP y DNS para sistemas operativos invitados.

Y dnsmasq establecerá el nombre de host en la tabla DNS de los hosts según el nombre de host que reciba del invitado.

Entonces, de acuerdo con estas instrucciones y mucho googlear, simplemente necesitaba crear y agregar esto a /etc/dhclient.conf:

send host-name "machine1"

Ahora, desde mi sistema operativo host, puedo ping machine1.

¿Alguien sabe por qué necesito agregar el "" final? para que se resuelva la entrada DNS? ¿Cómo puedo cambiar esto?

rascher
fuente
1
Sin el punto final, su solucionador de DNS agregará su lista de dominios de búsqueda al nombre de host cuando realice una búsqueda. En su lugar, puede enviar un FQDN, por ejemplo, machine1.example.com y luego agregar example.com a su orden de búsqueda de DNS.
James
gracias por esto. sin embargo, las notas vinculadas dicen ir a la máquina principal y editar /etc/resolv.conf y agregar 192.168.122.1 como el primer servidor de nombres (es decir, agregar el libvirt dnsmasq como NS), que por supuesto no funciona en la mayoría de los linuxes modernos como Hay múltiples abstracciones hoy en día de la red que reescriben /etc/resolv.conf. Todavía no he descubierto el mío.
Don brillante
2

Tuve el mismo problema, así que creé el siguiente script:

#!/bin/bash



function showMAC(){
    virsh dumpxml ${1}|grep "mac address"|sed "s/.*'\(.*\)'.*/\1/g"
}

function showIP(){
    for mac in $($0 -m $1); do
        grep $mac /var/log/daemon.log | tail -n 1 | awk '{print $7}'
    done
}

if test -z "${1}"; then
    echo "Usage: ${0} [-i | -m] <domain>"
    echo "  -i   Show IP address (the default)."
    echo "  -m   Show MAC address."
    exit
fi

addr_type="-i"

if test ${1} = "-i" || test ${1} = "-m"; then
    addr_type=${1}
    shift
fi

domain=${1}

test $addr_type = "-i" && showIP $domain || showMAC $domain

fuente
2

Lars Kellogg-Stedman ha creado un conjunto de scripts para automatizar parte de este proceso. Lo llama 'virt-utils'.

Lo describe en su publicación de blog aquí: http://blog.oddbit.com/2013/10/04/automatic-dns-entrie/

También tiene un github con algunos de los guiones que escribió, aquí:

https://github.com/larsks/virt-utils

Básicamente puedes ejecutar esto:

git clone https://github.com/larsks/virt-utils 
cd virt-utils 
sudo make install 
virt-hosts

y obtendrá una lista de cada máquina virtual por su "nombre de dominio" dentro del administrador de máquina virtual de libvirt. Por ejemplo, en mi máquina tengo 3 vms en ejecución.

don@serebryanya:~/src/virt-utils$ virt-hosts
192.168.122.23  mageia4.x64-net0.default.virt mageia4.x64.default.virt
192.168.122.197 debian7amd64-net0.default.virt debian7amd64.default.virt
192.168.122.15  freebsd10_amd64-net0.default.virt freebsd10_amd64.default.virt

Tenga en cuenta que este no es el 'nombre de host' que la VM está utilizando, pero para una gran cantidad de casos de uso, será 'lo suficientemente bueno' y resuelve el problema de tener que 'ifconfig' desde dentro de cada VM en dhcp land.

La publicación en el blog de Lars también muestra una forma de 'actualizar automáticamente' su propio archivo / etc / hosts a medida que libvirt inicia y / o detiene las nuevas máquinas virtuales. Esto le permite hacer cosas como ssh myname @ fedora20vm o ssh myname @ debian6vm sin tener que encontrar las direcciones 192.168.122.x a mano.

He agregado algunas mejoras muy pequeñas, como un script para escupir algunas opciones de ~ / .ssh / config (muy muy útil para usar github en máquinas virtuales, a través del reenvío de agentes), aquí:

https://github.com/donbright/virt-utils (¿parece estar eliminado?)

También me gustaría señalar que el método de edición de dhclient.conf para 'enviar nombre de host xxxxx' solo funciona en sistemas que realmente usan dhclient.conf de manera estándar. Mageia, por ejemplo, tiene una configuración inusual de cómo funciona su cliente, por lo que las instrucciones simples no necesariamente funcionan. Sin embargo, con el método de Lars, funciona independientemente de la configuración dhcp del sistema operativo invitado, porque no confía en la VM para enviar su nombre de host; está usando los 'nombres de dominio' dentro del administrador de máquina de libvirt.

don brillante
fuente
1

Entonces, ¿cómo puedo obtener una lista que diga:

máquina1 dirección IP = 192.168.122.16

dirección IP de machine2 = 192.168.122.238

al menos en fedora puedes obtener esa información de esta manera:

cat /var/lib/libvirt/dnsmasq/default.leases

tiene una salida similar a:

1412006226 52:54:00:fe:b3:c0 192.168.122.117 coreos0 01:52:54:00:fe:b3:c0

aunque eso es un poco más de lo que pediste

blq
fuente
0

En Ubuntu, dnsmasq se usa para proporcionar servicios de DNS y DHCP a las máquinas virtuales. Los procesos de dnsmasq en el host almacenan sus arrendamientos en este archivo:

/var/lib/misc/dnsmasq.leases

Este es un archivo de texto normal y las líneas pueden ser similares a las siguientes:

1362729847 52:54:de:ad:be:ef 192.168.122.254 vm-win7 01:52:54:de:ad:be:ef

Los campos de interés para usted son la tercera y la cuarta columna: el tercer campo contiene la dirección IPv4 de la VM y el cuarto campo contiene un asterisco o el nombre de host de la VM. Esto depende de la respuesta de DHCP enviada por el invitado al proceso del servicio dnsmasq.

pefu
fuente
gracias por esto. en mi máquina ubuntu el archivo es /var/lib/libvirt/dnsmasq/default.leases con el archivo dhclient.conf configurado para enviar el nombre de host "myvirtmachine"; como se menciona arriba
don brillante
0

Puede cambiar la defaultdefinición de red, asignar MAC a IP dentro del xml:

# virsh net-edit default
...
<range start='192.168.122.2' end='192.168.122.254' />
<host mac='52:54:00:6c:3c:02' ip='192.168.122.2' />
<host mac='52:54:00:6c:3c:03' ip='192.168.122.3' />
...
<host mac='52:54:00:6c:3c:fe' ip='192.168.122.254' />

# /etc/init.d/libvirtd restart (restart libvirt service)
# virsh net-destroy default    (remove old settings)
# virsh net-start default      (make changes working)

Una vez que inicie un invitado, puede enumerar la dirección MAC de todos los invitados a través de

# virsh list --all --mac

Según el último byte de una dirección MAC, puede inferir la dirección IP de un invitado.

coanor
fuente
¿para qué versión de virsh debería funcionar esto? virsh list --all --macno funciona en la versión 3.0.0
reox