当企业拥有多分支机构的场景下,如果所有的DNS请求都转发到总部的DNS服务器进行解析,由于网络延迟(VPN、SD-WAN等广域网连接)等问题势必会导致DNS解析速度变慢,影响用户的体验,同时传统的主备配置也存在以下的挑战:
- 主备DNS服务器的负载不均衡;
- 主服务器故障后,会导致客户端DNS解析时间变长(Windows系统下,新解析增加3s时间);
- 多分支采用不同的DNS地址,难于记忆;
基于此背景,Anycast技术非常适合大规模的企业DNS服务,实际上我们看到互联网的公共DNS也是采用此技术。
Anycast DNS概述
通常接入网络的设备都具有唯一的IP地址,也代表具有唯一的路径路径,网络通讯是1对1的;Anycast允许多个网络设备使用同一个IP地址,再结合OSPF/BGP的ECMP技术实现负载分担,最终实现了多个网络下使用相同的DNS服务器IP地址,也解决了我们前面提供的几个问题。
Anycast要求DNS服务器与物理交换机(3层)/路由器建立动态路由协议,以实现虚拟DNS IP地址的发布,由于涉及到路由公告、路由收敛等问题,实际生产环境部署时,一定要谨慎。
示例环境介绍
本环境采用VYOS作为企业数据中心路由器,DNS递归服务器上部署Bird2软件作为路由客户端,通过Bird2向物理网络公告DNS服务器的虚拟IP地址。
本示例只是验证Anycast DNS技术实现,不会部署多分支的架构,如果您需要多分支的架构,请咨询企业网络专家进行规划设计。
本环境采用BGP路由方式进行部署,规划如下:
设备名称 | IP地址 | AS | 用途 | 备注 |
---|---|---|---|---|
Core-Vyos | 10.208.10.254 | 65100 | 数据中心核心路由器 | |
pdns-rec01 | 10.208.0.111 | 65111 | 递归服务器 | |
pdns-rec02 | 10.208.0.112 | 65112 | 递归服务器 | |
N/A | 10.63.0.111 | N/A | 虚拟DNS IP地址1 | |
N/A | 10.63.0.112 | N/A | 虚拟DNS IP地址2 |
pdns-rec01和pdnsrec02部署bird2路由软件
Bird2是开源的Linux平台路由软件,支持OSPF、BGP、BFD等功能,
yum install epel* -y
yum install bird2
DNS递归服务器创建Loopback接口
创建loopback1接口
cat /etc/sysconfig/network-scripts/ifcfg-lo:1
DEVICE=lo:1
IPADDR=10.63.0.111
NETMASK=255.255.255.255
ONBOOT=yes
NAME=loopback1
创建loopback2接口
cat /etc/sysconfig/network-scripts/ifcfg-lo:2
DEVICE=lo:2
IPADDR=10.63.0.112
NETMASK=255.255.255.255
ONBOOT=yes
NAME=loopback2
DNS递归服务器生成Bird2配置
pdns-rec01中的bird配置,修改Route id,AS等信息。
cat /etc/bird.conf
log syslog all;
router id 10.208.0.111;
protocol device {
scan time 10; # Scan interfaces every 10 seconds
}
# Disable automatically generating direct routes to all network interfaces.
protocol direct {
disabled; # Disable by default
}
# Forbid synchronizing BIRD routing tables with the OS kernel.
protocol kernel {
ipv4 { # Connect protocol to IPv4 table by channel
import none; # Import to table, default is import all
export none; # Export to protocol. default is export none
};
}
# Static IPv4 routes.
protocol static {
ipv4;
route 10.63.0.111/32 via "eth0";
route 10.63.0.112/32 via "eth0";
}
# BGP peers
protocol bgp uplink0 {
description "BGP uplink 0";
local 10.208.0.111 as 65111;
neighbor 10.208.10.254 as 65100;
multihop;
ipv4 {
import filter {reject;};
export filter {accept;};
};
graceful restart;
}
protocol bfd {
interface "eth0" {
min rx interval 50 ms;
min tx interval 50 ms;
idle tx interval 300 ms;
multiplier 10;
};
multihop {
interval 300 ms;
multiplier 10;
};
neighbor 10.208.10.254 local 10.208.0.111 multihop;
}
pdns-rec02中的bird配置,修改Route id,AS等信息。
cat /etc/bird.conf
log syslog all;
router id 10.208.0.112;
protocol device {
scan time 10; # Scan interfaces every 10 seconds
}
# Disable automatically generating direct routes to all network interfaces.
protocol direct {
disabled; # Disable by default
}
# Forbid synchronizing BIRD routing tables with the OS kernel.
protocol kernel {
ipv4 { # Connect protocol to IPv4 table by channel
import none; # Import to table, default is import all
export none; # Export to protocol. default is export none
};
}
# Static IPv4 routes.
protocol static {
ipv4;
route 10.63.0.111/32 via "eth0";
route 10.63.0.112/32 via "eth0";
}
# BGP peers
protocol bgp uplink0 {
description "BGP uplink 0";
local 10.208.0.112 as 65112;
neighbor 10.208.10.254 as 65100;
multihop;
ipv4 {
import filter {reject;};
export filter {accept;};
};
graceful restart;
}
protocol bfd {
interface "eth0" {
min rx interval 50 ms;
min tx interval 50 ms;
idle tx interval 300 ms;
multiplier 10;
};
multihop {
interval 300 ms;
multiplier 10;
};
neighbor 10.208.10.254 local 10.208.0.112 multihop;
}
启动Bird服务
systemctl enable bird
systemctl start bird
数据中心路由器配置BGP路由和BFD支持
数据中心路由器配置,此处使用vYOS配置作为示例。
set protocols bfd peer 10.208.0.111 interval multiplier '10'
set protocols bfd peer 10.208.0.111 interval receive '300'
set protocols bfd peer 10.208.0.111 interval transmit '300'
set protocols bfd peer 10.208.0.111 multihop
set protocols bfd peer 10.208.0.111 source address '10.208.10.254'
set protocols bfd peer 10.208.0.112 interval multiplier '10'
set protocols bfd peer 10.208.0.112 interval receive '300'
set protocols bfd peer 10.208.0.112 interval transmit '300'
set protocols bfd peer 10.208.0.112 multihop
set protocols bfd peer 10.208.0.112 source address '10.208.10.254'
set protocols bgp 65100 neighbor 10.208.0.111 bfd
set protocols bgp 65100 neighbor 10.208.0.111 ebgp-multihop '10'
set protocols bgp 65100 neighbor 10.208.0.111 remote-as '65111'
set protocols bgp 65100 neighbor 10.208.0.111 timers holdtime '180'
set protocols bgp 65100 neighbor 10.208.0.111 timers keepalive '60'
set protocols bgp 65100 neighbor 10.208.0.111 update-source '10.208.10.254'
set protocols bgp 65100 neighbor 10.208.0.112 bfd
set protocols bgp 65100 neighbor 10.208.0.112 ebgp-multihop '10'
set protocols bgp 65100 neighbor 10.208.0.112 remote-as '65112'
set protocols bgp 65100 neighbor 10.208.0.112 timers holdtime '180'
set protocols bgp 65100 neighbor 10.208.0.112 timers keepalive '60'
set protocols bgp 65100 neighbor 10.208.0.112 update-source '10.208.10.254'
set protocols bgp 65100 parameters bestpath as-path multipath-relax
set protocols bgp 65100 parameters router-id '10.59.254.100'
commit
save
查看数据中心路由器中的路由表
可以看到是DNS IP地址有多个等价路径,说明路由学习和路由表生效已经正常。
> sh ip route
B>* 10.63.0.111/32 [20/0] via 10.208.0.111, eth0, 23:19:37
* via 10.208.0.112, eth0, 23:19:37
B>* 10.63.0.112/32 [20/0] via 10.208.0.111, eth0, 23:19:37
* via 10.208.0.112, eth0, 23:19:37
查看bgp路由学习情况
> sh ip bgp
*= 10.63.0.111/32 10.208.0.111 0 65111 i
*> 10.208.0.112 0 65112 i
*= 10.63.0.112/32 10.208.0.111 0 65111 i
*> 10.208.0.112 0 65112 i
基于脚本检测DNS服务运行状况
虽然现在DNS服务器已经工作正常,但当pdns-recursor服务出现问题时,Bird是无法判断的,这会导致客户端无法使用DNS服务; 所以,需要将下面的脚本通过定时任务运行检查(每1分钟),以判断DNS服务是否工作正常,如果工作异常,停止路由公告。
#!/bin/bash
DNSUP=`/usr/bin/dig @10.208.0.111 localhost. A +short`
if ["$DNSUP" != "127.0.0.1" ];
then
echo "Stop Anycast..."
systemctl stop bird
echo "Stoped:DC Anycast DNS has stoped working,BGP has already been shutdown,Please check the system right now."
else
echo "DNS is Working."
执行测试
当使用同一客户端进行测试时,基于路由的hash算法,只会总相同的路径,可以使用多台客户端访问测试。
dig -t a www.test.local @10.63.0.111
dig -t a www.vwmare.com @10.63.0.112
至此,我们实现了Anycast DNS架构的搭建,解决了文章开始提到的问题;但,Anycast DNS也增加了DNS架构的复杂度和维护复杂度,所以,大家应根据实际情况设计架构,不用一味地追求架构先进性。