Linux 服务器内网域名解析优化方案

缘起

这个项目的目的主要是为了解决 Linux 服务器在本地解析域名中碰到的几个问题:

  1. nameserver 中一部分有故障(包含宕机了)的问题
  2. nameserver 中一部分性能有问题的问题
  3. 有 HA,但有时候服务切换没有期望得那样准确、迅速

主要为了解决以上三个问题,于是有了内网域名解析优化的需求。

现有状况

现有情况貌似是每个机房节点有两台 DNS 二层服务器(从第一层同步数据),也许配有 HA,也许没配 HA,这两台服务器提供本机房内部的服务器的 DNS 查询请求服务。

Dnsmasq 方案

原理

Dnsmasq provides Domain Name System (DNS) forwarder, Dynamic Host Configuration Protocol (DHCP) server, router advertisement and network boot features for small computer networks, created as free software.[4][5]

Dnsmasq has low requirements for system resources,[6][7] can run on Linux, BSDs, Android and OS X, and is included in most Linux distributions. Consequently it “is present in a lot of home routers and certain Internet of Things gadgets”[4] and is included in Android.[5]

以上说明来自维基百科。

此方案中用到的主要是一个重要参数:all-servers,这个参数是干嘛用的,请看官方文档的说法:

–all-servers

By default, when dnsmasq has more than one upstream server available, it will send queries to just one server. Setting this flag forces dnsmasq to send all queries to all available servers. The reply from the server which answers first will be returned to the original requester.

仔细看,其实这一个参数就已经解决了前面提到的两个问题,他会让 dnsmasq 把收到的 DNS 查询请求同时并行发给多个上游 DNS 服务器,然后选取最快返回的结果返回给客户端。这样的话,我们只要配置上最够多的上游服务器,那么有几台挂掉,有几台性能不好,这都不是问题,只要有一个足够快返回正确的结果就行了。

当然,前提是服务器的 resolver 得指向 dnsmasq。

服务器配置

1
2
3
4
5
6
7
8
9
yum --y install dnsmasq;
chkconfig dnsmasq on;
cp /etc/resolv.conf{,.`date '+%F'`};
cat >/etc/resolv.conf<<_EOF_
search phnamedns.com
options timeout:1 attempts:1
nameserver 127.0.0.1
#nameserver x.x.x.x
_EOF_

上面的"x.x.x.x"是 Linux 服务器所在机房的二层 DNS 内网服务器的内网地址之一,注意:这个内网地址最好在所在机房的二层 DNS 服务器的内网地址之间尽量平均分配。

这里为什么要加这么一个 nameserver 纪录呢,这是用来破除 Linux 服务器本地 dnsmasq 服务单点的问题的。万一万一本地的 dnsmasq 挂掉了,那么在运维人员接到报警上来处理之前,可以通过第二个内网 dns 服务器来解析域名。

话又说回来,这个冗余相关的配置可能还是会有些问题,因为我们已将 timeout 的时间设成了最小值: 1s,而很有可能 resolver 在尝试从第一个 nameserver 解析域名超时之前,客户端程序早就已经超时了。这个时候,设置的第二条 nameserver 纪录显然就没用。

Dnsmasq 具体配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cat /etc/dhcsmaws.conf
### /etc/dnsmasq.conf
cp /etc/dnsmasq.conf{,.`date '+%F'`};
cat >/etc/dnsmasq.conf<<_EOF_
port=53
domain-needed
interface=lo
listen-address=127.0.0.1
no-dhcp-interface=lo
all-servers
bind-interfaces
no-resolv
server=10.0.0.1
server=10.0.0.2
server=10.0.1.1
server=10.0.1.2
server=10.0.2.1
server=10.0.2.2
server=10.0.3.1
server=10.0.3.2
_EOF_
/etc/init.d/dnsmasq start;

优点

  1. dnsmasq 小巧、灵活、配置简单
  2. 不用再担心上游某台 DNS 服务器故障
  3. 不用关心上游服务器性能差、网络延时大、反应迟钝

缺点

  • 本机的 dnsmasq 服务成为了新的故障点,虽然在 /etc/resolv.conf 中启用第二个 nameserver 来破除了单点,但是由于前面提到的超时原因,dnsmasq 挂还是会导致本机的好多 DNS 解析失败。

前置 LB 设备方案

已有 LB 设备

如果某个机房里已有现成的 LB 设备,如:F5、NetScaler 等等,或者是已有成熟商业 LB 产品出售的公有云,直接用现成的就好。

没有 LB 设备

如果在某个没有负载均衡设备的机房,可以考虑在前端部署一套 LVS;再或者直接用 keepalived 来跑 vrrp 协议,跑两个 VIP,让两台二层 DNS 服务器互为主备,需要解析服务的机房内部服务器,可以直接用着两个 VIP 作为 nameserver。

优点

  1. 本方案从基础设施本身入手,不用在客户端(服务器)上改太多东西
  2. 实施后本方案也能基本解决目前所碰到的那几个问题

缺点

  1. 缺点也很明显,尤其是当需要再重新搭建 LVS 的时候,步骤相对复杂

远期优化方案—解耦

从目前来看,无论是 dnsmasq 还是 LB 前置方案,都只是目前能做、可以做的,做了就能立马看到效果的优化方案。但我们还得要抬起头来走路,要看到远期,半年后、一年后、几年后…所以我这里连远期的优化改造方案思路也一并提出来,抛砖引玉。

目前,内网解析 DNS 服务器和外网解析 DNS 服务器是在一起的,或者说,数据是在一起的,这样很不对,互联网服务讲究独立、不互相依赖,这样的服务才好维护。于是,本着解耦内外网 DNS 服务的目的,我觉得远期这两个服务一定要分开!

怎么做?每个机房部署两台或多台 dnsmasq 服务(不需要单独服务器)替代现有的二层 DNS 服务器在内网解析中的角色。

现在谈谈可行性、工作量。我发现其实这个工作量其实并不大!很简单,内网 DNS 解析服务器其实是并不需要外网权威 DNS 服务器那么多的数据的。对于我司完全拥有的域名的解析工作,可以直接走公网;对于由于我司劫持的域名或其他特殊需求,直接在 dnsmasq 里转发特定域名解析请求到特定服务器就好了。

备注

  1. 本文档所有命令、软件均仅适用于 RHEL 6.* 或 CentOS 6.*,其他平台未经测试。

参考

  1. Dnsmasq 官方文档:http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html
  2. /etc/resolv.conf 的官方手册:http://man7.org/linux/man-pages/man5/resolv.conf.5.html
如果您觉得我的经验能够帮助到您,请不吝赏赐,非常感谢!