Obter lista de clientes DHCP com KVM + libvirt?

11

Eu tenho várias VMs em execução no Ubuntu 9.10 via KVM + libvirt. Quero poder descobrir o endereço IP atribuído a cada host sem abrir fisicamente um "console" físico para cada máquina e invocá-lo ifconfig.

Considerar:

rascher @ localhost: ~ $ virsh -c qemu: /// lista do sistema --todos
Conectando ao uri: qemu: /// system
 ID Nome Estado
----------------------------------
  1 máquina1 em execução
  2 machine2 em execução
  - machine3 desligado

Minha configuração de rede se parece com:

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

Então, como posso obter uma listagem que diz:

endereço IP da máquina1 = 192.168.122.16
endereço IP da máquina2 = 192.168.122.238
...

Eu brinquei com arp:

rascher @ localhost: ~ $ arp
Endereço 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
...

Mas isso não é mapeado para o ID de uma máquina virtual.

Existe alguma ferramenta (através da linha de comando virshou virt-*) que eu possa verificar essas informações? Ou preciso ter algum script sofisticado que seja executado em cada VM individual, verifique seu próprio IP e o reporte ao sistema operacional host?

rascher
fonte

Respostas:

9

Esse recurso foi solicitado há muito tempo. Agora, a libvirt o suporta fornecendo dois novos comandos: domifaddr e 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

Em um cenário 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
fonte
4

A libvirt usa o dnsmasq para fornecer DHCP aos convidados, para que você possa vasculhar /var/log/daemon.log ou vasculhar o arquivo de concessões em / var / lib / libvirt para obter um mapeamento de IP para nome de host.

James
fonte
2

Portanto, ao investigar isso, descobri que a libvirt usa o dnsmasq para fazer DHCP e DNS para sistemas operacionais convidados.

E o dnsmasq definirá o nome do host na tabela DNS dos hosts com base no nome do host que ele receber do convidado.

Portanto, de acordo com estas instruções e com muita pesquisa no Google, eu simplesmente precisava criar e adicionar isso ao /etc/dhclient.conf:

send host-name "machine1"

Agora, no meu SO host, posso ping machine1.

Alguém sabe por que eu preciso adicionar o "" final. para que a entrada DNS seja resolvida? Como posso mudar isso?

rascher
fonte
1
Sem o ponto à direita, o resolvedor de DNS anexará sua lista de domínios de pesquisa ao nome do host ao fazer uma pesquisa. Em vez disso, você pode enviar um FQDN, por exemplo, machine1.example.com e, em seguida, adicionar example.com à sua ordem de pesquisa de DNS.
James
obrigado por isso. no entanto, as notas vinculadas dizem para ir na máquina host principal e editar /etc/resolv.conf e adicionar 192.168.122.1 como o primeiro servidor de nomes (por exemplo, adicionar o libvirt dnsmasq como um NS), o que obviamente não funciona nos linux modernos, como Hoje existem várias abstrações da rede que reescrevem o /etc/resolv.conf. ainda não consegui descobrir o meu.
don brilhante
2

Como tive o mesmo problema, criei o seguinte 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

fonte
2

Lars Kellogg-Stedman criou um conjunto de scripts para automatizar parte desse processo. Ele chama isso de "virt-utils".

Ele descreve isso em sua postagem no blog aqui: http://blog.oddbit.com/2013/10/04/automatic-dns-entrie/

Ele também tem um github com alguns dos scripts que escreveu, aqui:

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

Basicamente, você pode simplesmente executar isso:

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

e você obterá uma lista de cada máquina virtual com seu "nome de domínio" no gerenciador de máquinas virtuais da libvirt. Por exemplo, na minha máquina, tenho 3 vms em execução.

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

Observe que este não é o 'nome do host' que a própria VM está usando, mas, para um grande número de casos de uso, será 'bom o suficiente' e resolve o problema de ter que 'ifconfig' de cada VM no território do dhcp.

A publicação no blog de Lars também mostra uma maneira de atualizar automaticamente seu próprio arquivo / etc / hosts quando a libvirt inicia e / ou interrompe novas VMs. Isso permite que você faça coisas como ssh myname @ fedora20vm ou ssh myname @ debian6vm sem precisar encontrar os endereços 192.168.122.x manualmente.

Eu adicionei alguns aprimoramentos muito menores, como um script para citar algumas opções ~ / .ssh / config (muito úteis para usar o github em VMs, via Agent Forwarding), aqui:

https://github.com/donbright/virt-utils (parece ter sido excluído?)

Também gostaria de observar que o método de editar o dhclient.conf para 'enviar nome do host xxxxx' funciona apenas em sistemas que realmente usam o dhclient.conf de maneira padrão. A Mageia, por exemplo, tem uma configuração incomum de como o dhclient funciona, portanto, as instruções simples não necessariamente funcionam. No entanto, com o método Lars, ele trabalha constantemente com a configuração dhcp do SO convidado, porque ele não depende da VM para enviar seu nome de host - ele está usando os 'nomes de domínio' no gerenciador de máquinas da libvirt.

não brilhante
fonte
1

Então, como posso obter uma listagem que diz:

endereço IP da máquina1 = 192.168.122.16

endereço IP da máquina2 = 192.168.122.238

pelo menos no fedora você pode obter essas informações desta maneira:

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

tem uma saída semelhante a:

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

embora isso seja um pouco mais do que você pediu

blq
fonte
0

No Ubuntu, o dnsmasq é usado para fornecer serviços DNS e DHCP às VMs. Os processos dnsmasq no host armazenam suas concessões neste arquivo:

/var/lib/misc/dnsmasq.leases

Este é um arquivo de texto normal e as linhas nele podem ser semelhantes a esta aqui:

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

Os campos de seu interesse são a terceira e a quarta coluna: o terceiro campo contém o endereço IPv4 da VM e o quarto campo contém um asterisco ou o nome do host da VM. Isso depende da resposta do DHCP enviada pelo convidado ao processo do serviço dnsmasq.

pefu
fonte
obrigado por isso. na minha máquina ubuntu, o arquivo é /var/lib/libvirt/dnsmasq/default.leases com o arquivo dhclient.conf configurado para enviar o nome do host "myvirtmachine"; como listado acima
don bright
0

Você pode alterar a defaultdefinição de rede, mapear MAC para IP dentro do 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)

Depois de iniciar um convidado, você pode listar o endereço MAC de todos os convidados via

# virsh list --all --mac

De acordo com o último byte de um endereço MAC, é possível inferir o endereço IP de um convidado.

coanor
fonte
para qual versão do virsh isso deve funcionar? virsh list --all --macnão funciona na versão 3.0.0
reox 28/09