Acesso libvirt + máquinas virtuais KVM com DNS

5

Eu tenho uma máquina Ubuntu Trusty executando o KVM + Libvirt para gerenciar pequenas máquinas virtuais e usando o NetworkManager padrão para conectar redes regulares.

Eu quero poder acessar as máquinas virtuais via DNS do host.

Libvirt usa uma sub-rede privada virtual (192.168.122.0/24), NAT para acessar o resto do mundo através de uma ponte (virbr0) na minha eth0. Dnamasq priveds DHCP + DNS para esta rede virtual.

Esta é a configuração do libvirt para a rede virtual:

<network>
  <name>default</name>
  <uuid>400c59ff-c276-4154-ab73-9a8a8d1c6be3</uuid>
  <forward mode='nat'>
    <nat>
      <port start='1024' end='65535'/>
    </nat>
  </forward>
  <bridge name='virbr0' stp='on' delay='0'/>
  <mac address='52:54:00:f4:bd:37'/>
  <domain name='kvm'/>
  <dns forwardPlainNames='no'>
    <forwarder addr='127.0.1.1'/>
    <host ip='192.168.122.1'>
      <hostname>host</hostname>
      <hostname>host.kvm</hostname>
    </host>
  </dns>
  <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>

Libvirt inicia uma instância do dnsmasq ouvindo em 192.168.122.1:53 que responde a todos os pedidos de .knv e encaminha quaisquer outras solicitações para o meu host. Esta configuração do dnsmasq é gerada automaticamente pelo libvirt:

/var/lib/libvirt/dnsmasq/default.conf

##WARNING:  THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
##OVERWRITTEN AND LOST.  Changes to this configuration should be made using:
##    virsh net-edit default
## or other application using the libvirt API.
##
## dnsmasq conf file created by libvirt
strict-order
user=libvirt-dnsmasq
no-resolv
server=127.0.1.1
domain=kvm
expand-hosts
domain-needed
local=//
pid-file=/var/run/libvirt/network/default.pid
except-interface=lo
bind-dynamic
interface=virbr0
dhcp-range=192.168.122.2,192.168.122.254
dhcp-no-override
dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases
dhcp-lease-max=253
dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts

O NetworkManager tem uma instância do dnsmasq ouvindo em 127.0.1.1:53 que ele usa para todas as quieries de DNS antes de passar para qualquer servidor DNS que meu host seja designado pelo sistema DHCP externo.

Para que meu sistema Ubuntu host use o dnsmasq do libvirt, aponto o dnsmasq do NetworkManager para usar 192.168.122.1 para o domínio kvm:

/etc/NetworkManager/dnsmasq.d/libvirt.conf

server=/kvm/192.168.122.1

E isso funciona, na maior parte ...

me@host ~ $ ps aufx
...cut...
root     11010  0.2  0.0 342084  6348 ?        Ssl  10:59   0:00 NetworkManager
root     11018  0.0  0.0  10232  3732 ?        S    10:59   0:00  \_ /sbin/dhclient -d -sf /usr/lib/NetworkManager/nm-dhcp-client.action -pf /run/sendsigs.omit.d/network-manager.dhclient-eth0.pid -lf /var/lib/NetworkManager/dhclient-b8043 
nobody   11228  0.0  0.0  32252  1564 ?        S    10:59   0:00  \_ /usr/sbin/dnsmasq --no-resolv --keep-in-foreground --no-hosts --bind-interfaces --pid-file=/run/sendsigs.omit.d/network-manager.dnsmasq.pid --listen-address=127.0.1.1 --
root     11033  1.0  0.1 513356 15160 ?        Sl   10:59   0:01 /usr/sbin/libvirtd -d
libvirt+ 11085  0.0  0.0  28208   948 ?        S    10:59   0:00 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf

me@host ~ $ sudo netstat -nulpd | grep dnsmasq
udp  0  0  127.0.1.1:53      0.0.0.0:*  11228/dnsmasq   
udp  0  0  192.168.122.1:53  0.0.0.0:*  11085/dnsmasq   
udp  0  0  0.0.0.0:67        0.0.0.0:*  11085/dnsmasq  

me@host ~ $ host test.kvm
test.kvm has address 192.168.122.193
;; connection timed out; no servers could be reached
;; connection timed out; no servers could be reached

Mas cria um grande número de consultas dnsmasq AAAA, todas esperando por uma resposta.

me@host ~ $ sudo netstat -nulpd | grep dnsmasq
udp  0  0  0.0.0.0:39329  0.0.0.0:*  11228/dnsmasq   
udp  0  0  0.0.0.0:2469   0.0.0.0:*  11085/dnsmasq   
udp  0  0  0.0.0.0:14805  0.0.0.0:*  11228/dnsmasq
...cut...
udp  0  0  0.0.0.0:51569  0.0.0.0:*  11228/dnsmasq   
udp  0  0  0.0.0.0:31091  0.0.0.0:*  11085/dnsmasq   
udp  0  0  0.0.0.0:39305  0.0.0.0:*  11085/dnsmasq

me@host ~ $ sudo netstat -nulpd | grep dnsmasq | wc -l
131

E um tcpdump mostra que eles são principalmente solicitações AAAA:

me@host ~ $ sudo tcpdump -vni any udp port 53
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
11:04:49.453864 IP (tos 0x0, ttl 64, id 56217, offset 0, flags [none], proto UDP (17), length 55)
    127.0.0.1.58535 > 127.0.1.1.53: 31275+ A? mysql.kvm. (27)
11:04:49.453948 IP (tos 0x0, ttl 64, id 20062, offset 0, flags [DF], proto UDP (17), length 55)
    192.168.122.1.7098 > 192.168.122.1.53: 41491+ A? mysql.kvm. (27)
11:04:49.454013 IP (tos 0x0, ttl 64, id 20063, offset 0, flags [DF], proto UDP (17), length 71)
    192.168.122.1.53 > 192.168.122.1.7098: 41491* 1/0/0 mysql.kvm. A 192.168.122.193 (43)
11:04:49.454068 IP (tos 0x0, ttl 64, id 37088, offset 0, flags [DF], proto UDP (17), length 71)
    127.0.1.1.53 > 127.0.0.1.58535: 31275* 1/0/0 mysql.kvm. A 192.168.122.193 (43)
11:04:49.454321 IP (tos 0x0, ttl 64, id 56218, offset 0, flags [none], proto UDP (17), length 55)
    127.0.0.1.56040 > 127.0.1.1.53: 47999+ AAAA? mysql.kvm. (27)
11:04:49.454381 IP (tos 0x0, ttl 64, id 20064, offset 0, flags [DF], proto UDP (17), length 55)
    192.168.122.1.19631 > 192.168.122.1.53: 20542+ AAAA? mysql.kvm. (27)
...cut...
11:05:09.510237 IP (tos 0x0, ttl 64, id 20515, offset 0, flags [DF], proto UDP (17), length 55)
    192.168.122.1.19631 > 192.168.122.1.53: 35761+ MX? mysql.kvm. (27)
11:05:09.510237 IP (tos 0x0, ttl 64, id 56674, offset 0, flags [DF], proto UDP (17), length 55)
    127.0.0.1.46085 > 127.0.1.1.53: 53641+ AAAA? mysql.kvm. (27)
11:05:09.510315 IP (tos 0x0, ttl 64, id 56675, offset 0, flags [DF], proto UDP (17), length 55)
    127.0.0.1.46085 > 127.0.1.1.53: 26166+ MX? mysql.kvm. (27)
11:05:09.510334 IP (tos 0x0, ttl 64, id 20516, offset 0, flags [DF], proto UDP (17), length 55)
    192.168.122.1.19631 > 192.168.122.1.53: 4247+ AAAA? mysql.kvm. (27)
11:05:09.510407 IP (tos 0x0, ttl 64, id 56676, offset 0, flags [DF], proto UDP (17), length 55)
    127.0.0.1.46085 > 127.0.1.1.53: 49331+ AAAA? mysql.kvm. (27)
11:05:09.510433 IP (tos 0x0, ttl 64, id 20517, offset 0, flags [DF], proto UDP (17), length 55)
    192.168.122.1.19631 > 192.168.122.1.53: 63294+ MX? mysql.kvm. (27)
^C
934 packets captured
1857 packets received by filter
0 packets dropped by kernel

Eu tentei diminuir a prioridade dos registros AAAA em /etc/gai.conf

precedence ::ffff:0:0/96  100

Até tentamos desabilitar o IPv6 completamente /etc/sysctl.conf :

# Disable IPv6
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

Mas as solicitações AAAA ainda estão sendo enviadas e a resolução de nomes se torna insuportavelmente lenta.

Existe uma maneira de o libvirt ou o NetworkManager ignorar ou responder negativamente a essas solicitações, para que eu não precise esperar que todas as solicitações expirem antes de usar o registro A que já foi recebido?

    
por Tim Jones 06.11.2014 / 11:28

1 resposta

3

Se um encaminhador estiver configurado, o dnsmasq encaminhará todas as consultas DNS para as quais não possui dados explícitos. Isso inclui registros para clientes DHCP estáticos configurados que não possuem registros de AAAA, a menos que endereços IPv6 sejam definidos explicitamente e muito mais.

Existem várias maneiras de evitar isso:

Não configure um encaminhador

Basta omitir as entradas de entrada na definição de rede. Provavelmente não é desejável, a menos que a rede virtual esteja realmente isolada. Esta é a única possibilidade que o libvirt atualmente suporta (12/2014), AFAIK.

domínio local no dnsmasq.conf

Configure o domínio como "local" no dnsmasq:

 domain=local.net,192.168.10.0/24
 local=/local.net/
 local=/10.168.192.in-addr.arpa/

Em teoria, isso pode ser abreviado como domain=local.net,192.168.10.0/24,local , mas um O bug dnsmasq corrigido recentemente faz com que isso falhe.

O libvirt não suporta isso. Para usar esta configuração, você precisa configurar a bridge manualmente no seu sistema operacional e configurar a rede libvirt da seguinte forma:

   <network>
     <name>local</name>
     <forward mode='bridge'/>
     <bridge name='br0'/>
   </network>

Você não precisa criar uma rede virtual libvirt nesta configuração, apenas use <interface 'type=bridge'> em seus arquivos de definição de VM.

auth zone no dnsmasq.conf

O parâmetro auth-zone tem um efeito semelhante a local . No entanto, tem outras implicações que não pretendo compreender completamente. Suponho que essa configuração seria desejável se os nomes na rede virtual fossem resolvidos do lado de fora.

domain=local.net
auth-zone=local.net

Esta configuração também não é suportada pela libvirt, portanto, o mesmo procedimento para configurar a ponte deve ser aplicado como acima.

    
por 17.12.2014 / 17:52