我有一台运行KVM + Libvirt的Ubuntu Trusty机器来pipe理小型虚拟机,并使用标准的NetworkManager连接到常规networking。
我希望能够通过DNS从主机访问虚拟机。
Libvirt使用一个虚拟专用子网(192.168.122.0/24),NAT'd通过我的eth0上的网桥(virbr0)访问世界其他地方。 Dnamasq为此虚拟networking提供DHCP + DNS。
这是虚拟networking的libvirtconfiguration:
<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启动一个侦听192.168.122.1:53的dnsmasq实例,它会回应所有的.knv请求,并将任何其他请求转发给我的主机。 这个dnsmasqconfiguration是由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实例,它在传递给我的主机由外部DHCP系统分配的任何DNS服务器之前用于所有DNS quieries。
为了让我的主机Ubuntu系统使用libvirt的dnsmasq,我将NetworkManager的dnsmasq指向域kvm使用192.168.122.1:
/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
但是创build大量的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, 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
我试着降低/etc/gai.conf中的AAAAlogging的优先级
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请求仍在发送,名称parsing变得难以忍受。
有没有一种方法让libvirt或NetworkManager忽略或回应这些请求,所以我不必等待所有请求超时才能使用已经收到的Alogging?
如果configuration了转发器,则dnsmasq将转发所有没有明确数据的DNS查询。 这包括configuration的没有活动租约的静态DHCP客户端logging,AAAAlogging,除非明确地定义了IPv6地址,等等。
有几种方法可以避免这种情况:
简单地省略networking定义中的fowarder条目。 可能是不可取的,除非虚拟networking真的是孤立的。 这是libvirt目前支持的唯一可能(2014年12月),AFAIK。
在dnsmasq中将域configuration为“本地”:
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 ,但是最近修复的dnsmasq错误会导致失败。
libvirt不支持这个。 为了使用此configuration,您需要在您的操作系统中手动设置网桥,并像这样configurationlibvirtnetworking:
<network> <name>local</name> <forward mode='bridge'/> <bridge name='br0'/> </network>
你不必在这个configuration中创build一个libvirt虚拟networking,只需在你的虚拟机定义文件中使用<interface 'type=bridge'> 。
auth-zone参数与local有相似的效果。 不过,我还没有完全理解其他含义。 如果虚拟networking中的名字应该从外部解决,我想这种configuration是可取的。
domain=local.net auth-zone=local.net
libvirt也不支持这种设置,所以必须按照上面的说明来设置桥接。