我希望能够通过DNS从主机访问虚拟机.
Libvirt使用虚拟私有子网(192.168.122.0/24),NAT’d通过我的eth0上的桥(virbr0)访问世界其他地方. Dnamasq将DHCP DNS授予此虚拟网络.
这是虚拟网络的libvirt配置:
<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启动一个dnsmasq实例,监听192.168.122.1:53,它回答所有.knv请求并将任何其他请求转发给我的主机.这个dnsmasq配置由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
NetworkManager在127.0.1.1:53上有一个dnsmasq监听实例,它用于所有DNS quieries,然后传递给我的主机由外部DHCP系统分配的任何DNS服务器.
为了让我的主机Ubuntu系统使用libvirt的dnsmasq,我指向NetworkManager的dnsmasq使用192.168.122.1作为域kvm:
/etc/NetworkManager/dnsmasq.d/libvirt.conf
server=/kvm/192.168.122.1
这在大多数情况下都有效…
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
但是创建了大量的dnsmasq AAAA查询,等待响应.
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
并且tcpdump显示它们主要是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,id 20062,flags [DF],length 55) 192.168.122.1.7098 > 192.168.122.1.53: 41491+ A? MysqL.kvm. (27) 11:04:49.454013 IP (tos 0x0,id 20063,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,id 37088,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,id 56218,length 55) 127.0.0.1.56040 > 127.0.1.1.53: 47999+ AAAA? MysqL.kvm. (27) 11:04:49.454381 IP (tos 0x0,id 20064,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,id 20515,length 55) 192.168.122.1.19631 > 192.168.122.1.53: 35761+ MX? MysqL.kvm. (27) 11:05:09.510237 IP (tos 0x0,id 56674,length 55) 127.0.0.1.46085 > 127.0.1.1.53: 53641+ AAAA? MysqL.kvm. (27) 11:05:09.510315 IP (tos 0x0,id 56675,length 55) 127.0.0.1.46085 > 127.0.1.1.53: 26166+ MX? MysqL.kvm. (27) 11:05:09.510334 IP (tos 0x0,id 20516,length 55) 192.168.122.1.19631 > 192.168.122.1.53: 4247+ AAAA? MysqL.kvm. (27) 11:05:09.510407 IP (tos 0x0,id 56676,length 55) 127.0.0.1.46085 > 127.0.1.1.53: 49331+ AAAA? MysqL.kvm. (27) 11:05:09.510433 IP (tos 0x0,id 20517,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
我尝试在/etc/gai.conf中降低AAAA记录的优先级
precedence ::ffff:0:0/96 100
甚至尝试完全禁用IPv6 /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
但AAAA请求仍在发送,名称解析变得无法忍受.
有没有办法让libvirt或NetworkManager忽略或对这些请求做出否定响应,这样我就不必等待所有请求超时才能使用已收到的A记录?
解决方法
有几种方法可以避免这种情况:
不要配置转发器
只需省略网络定义中的fowarder条目即可.可能不可取,除非虚拟网络真的是孤立的.这是libvirt目前支持的唯一可能性(12/2014),AFAIK.
dnsmasq.conf中的本地域
在dnsmasq中将域配置为“本地”:
domain=local.net,192.168.10.0/24 local=/local.net/ local=/10.168.192.in-addr.arpa/
从理论上讲,这可以缩写为domain = local.net,192.168.10.0 / 24,local,但a dnsmasq bug fixed only recently会导致失败.
libvirt不支持这个.要使用此配置,您需要在操作系统中手动设置网桥并配置libvirt网络,如下所示:
<network> <name>local</name> <forward mode='bridge'/> <bridge name='br0'/> </network>
您无需在此配置中创建libvirt虚拟网络,只需使用< interface'type = bridge'>在您的VM定义文件中.
dnsmasq.conf中的auth区域
auth-zone参数与local具有类似的效果.然而,它有其他含义,我没有声称完全理解.我想如果虚拟网络中的名称应该从外部解析,那么这种配置是可取的.
domain=local.net auth-zone=local.net