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?