图解 DNS 域名解析与负载均衡

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图解 DNS 域名解析与负载均衡相关的知识,希望对你有一定的参考价值。

参考技术A 在 DNS 查询 篇中,主要是根据阮一峰老师的文章所做的学习记录。讲述了通过命令 dig 来跟踪域名的查询过程,也提到了 DNS 服务器的层级结构、DNS 记录、DNS 缓存等。整体都是文字叙述,读起来会稍微有些累。这篇会通过图示来进一步简化 DNS 的解析过程,并会提到 DNS 的另一项重要作用, 负载均衡 。

首先我们来了解一下 DNS 服务器。主要有三种类型的 DNS 服务器:

DNS 服务器的层级是树状结构,如下图所示:

假设我们需要在浏览器上访问 https://www.baidu.com 网页,浏览器识别到访问的是个域名而不是 ip 地址时,会开始发起域名解析的过程。用户电脑上运行着 DNS 应用客户端,我们把它叫做本地 DNS 解析器。

首先我们先来回顾一下域名解析的整个过程,稍后会以图示的方式展现。

本地 DNS 服务器地址会配置在本机。如果是采用 DHCP 动态获取 IP 地址的方式,那么一般会被配置为网络运营商的 DNS 服务地址;或者可以自己配置为非权威 DNS 服务器地址,比如 google 的 8.8.8.8 。

那么它如何知道根域名服务器的地址呢?很简单,根域名服务器数量少,其地址会配置在本地 DNS 服务器中。

整体流程如下图所示,其中白色箭头表示查询方向,绿色箭头表示返回方向。

DNS 的另一个作用是做负载均衡, Server Load Balance 。

最简单的一种应用情况,在 DNS 服务器上配置某个域名对应的 ip 时,可以配置多个 A 记录,即一个域名对应多个 ip。这里可以配置不同的策略。

当客户端请求域名解析时,DNS 服务器返回全部 ip 地址。客户端拿到多个 ip 后可进行轮询,或者是随机选择一个 ip,或者是按照某种算法选择一个 ip 进行请求。

假设配置了 ip1, ip2, ip3 三个地址。第一次请求返回 ip1,第二次请求返回 ip2,以此类推。

设定各个 ip 的权重,优先返回权重大的 ip。

另外一种复杂的应用情况,做全局的负载均衡,即 GSLB,Global Server Load Balance 。全局上可分为运营商和区域,在同一个运营商上进行访问肯定速度更快;同样,请求的服务器距离客户端越近,速度越快。

那全局负载均衡如何实现呢?跟添加中间层的思想差不多,经过中间层 GSLB 来控制负载均衡策略。下面介绍两种方式。

具体做法是,在权威 DNS 服务器上给目标域名配置一条 NS 记录, A → B ,即 A 对应的域名服务器地址为 B,也就是 GSLB 的地址 ,让 GSLB 来充当 权威域名服务器 。

当 DNS 解析 A 域名时,会返回设置好的 B。这样本地 DNS 服务器就会转到请求 B 也就是 GSLB 去进行域名解析, GSLB 就可按照某种策略进行负载均衡计算,比如根据本地 DNS 服务器的所属运营商和本地 DNS 服务器的位置返回合适的 ip。

假设查询的目标域名为 http://www.company.com ,设置一条 NS 记录为 http://www.company.com → http://www.companyOk.com 。那么当查询 www.company.com 时,DNS 服务器会返回 www.companyGSLB.com 。然后本地 DNS 服务器会去请求 www.companyGSLB.com DNS 服务器,让该权威域名服务器去解析 www.company.com 域名,返回合适的 ip 地址。这样,控制权就交到了 www.companyGSLB.com 手上,具体策略可以由它自己来确定。

但是这种方式只能知道本地 DNS 服务器所属的运营商和 ip 地址,而不是客户端的 ip。

流程如下图所示:

通过给域名添加别名的方式来实现,有两种不同的方式。

a. 设置别名后,再通过 http 重定向

给目标域名 A 配置别名 CNAME,也就是 GSLB 的域名。这样请求解析 A 域名时会返回 CNAME 记录,之后本地 DNS 服务器会转为请求 GSLB 的域名,最后返回 GSLB 的 ip 地址。

这样,客户端就会跟 GSLB 进行通信,GSLB 可以知道客户端的 ip 地址,进而根据一系列的策略进行调度,然后利用 http 重定向将客户端定向到合适的地址。

流程如下图所示:

b. 设置别名,通过 NS 记录转到不同的 GSLB 域名服务器

给目标域名设置别名,对别名设置 NS 记录,转到不同的 GSLB 去查询。

举个栗子:比如在 company.com 的权威服务器上给域名 test.company.com 设置别名 hello.test.comany.com。

当本地 DNS 服务器请求解析 test.company.com 时,流程如下:

流程图如下:

这里只有一层 GSLB,也可以有多层。假设第一层 GSLB 是用来区分运营商,第二层 GSLB 是区分区域。

比如本地 DNS 服务器所在运营商是移动,那么在 xx.GSLB1.com 就可返回另一个别名 yd.test.comany.com 。 yd.test.comany.com 也对应一条 NS 记录, yd.test.comany.com → xx.GSLB2.com ,这样就将 yd.test.comany.com 转到第二层 GSLB 去解析。 GSLB2 就可根据本地 DNS 服务器的位置返回距离用户较近区域的 ip。

DNS的主从,转发与负载功能

接着原来《DNS原理与应用》的文章,本章内容主要通过实现DNS的主从,转发,及基于域名解析不同的ip实现后端服务负载均衡的效果。最后再实现DNS的高级功能:类似CDN原理实现基于IP实现区域分流负载,通过以上内容更好地理解DNS的工作原理以及拓展高性能的web服务实现思路

利用DNS解析实现简单的web负载均衡

我们常说的负载均衡解决方案大多是通过nginx、lvs,haporxy等实现业务或者流程的负载,通过DNS也可以实现简单的负载功能,并且在用户请求解析的过程中就能实现负载,DNS默认会使用轮询的机制轮流将请求解析到后端不同主机:这样就可以将同一站点域名解析到不同的主机IP,让各主机提供相同的服务。在DNS中配置如下即可实现:

webserver       IN      A       192.168.214.135
webserver       IN      A       192.168.214.136
www     IN      CNAME           webserver
@       IN      A               192.168.214.135
@       IN      A               192.168.214.136

上面的配置将一个站点部署在两台主机上,通过定义别名DNS会轮询解析请求到这两台主机上

解析测试:

[[email protected] ~]# curl http://yufu.com/index.html
<html>
<title>Welcome to nginx!</title>
<h1>Welcome to nginx!</h1>
this is test page
ip:192.168.214.135
</html>
[[email protected] ~]# curl http://www.yufu.com/index.html

<html>
    <head>
<h1>Welcome to nginx!</h1>
this is test page
IP: 192.168.214.136 
   </body>
</html>

DNS负载缺点:为了降低DNS请求的次数以提高訪问效率。浏览器经常缓存了DNS查询的结果。假设一个IP处的服务失效。那么浏览器可能仍会依据DNS缓存中所记录的信息向该不可用的服务发送请求(不同的浏览器可能有不同的行为)。尽管说整个服务仅仅有一处IP所相应的服务失效了,可是从用户的角度看来该站点已经不可訪问。因此基于DNS的负载平衡方案并不能作为一个独立的负载平衡解决方式来提供高可用性的保障,而是作为其他负载平衡解决方式的补充方案来使用。

DNS主从同步

要实现DNS的主从复制,必须要在主DNS区域解析库文章中定义从服务器地址:
思路:

  1. 主DNS解析库文件中定义从服务器信息
  2. 从服务器在区域库定义文件中添加要解析的区域信息,大致与主DNS上相同,但是type是为slave;要指定master是谁,以及同步的解析库文件存放位置
  3. 关于安全考虑:在主从的named.conf文件中要添加访问控制:允许区域传送的主机-白名单(allow-transfer {})

实现上面的过程:

  • 主DNS服务器定义从服务器信息/var/named/gudaoyufu.com.zone
$TTL 1D
@       IN      SOA     ns1.yufu.com. amin.yufu.com (
                        2018051503
                        1H
                        5M
                        7D
                        1D )


        IN      NS      ns1.yufu.com.
        IN      NS      ns2.yufu.com.         #定义从DNS
        IN      MX 10   mx1
        IN      MX 20   mx2
ns1     IN      A       192.168.214.128
ns2     IN      A       192.168.214.134      #定义从DNS的IP地址
mx1     IN      A       192.168.214.189
mx2     IN      A       192.168.214.190
webserver       IN      A       192.168.214.135
webserver       IN      A       192.168.214.136
www     IN      CNAME           webserver
@       IN      A               192.168.214.135
@       IN      A               192.168.214.136
;*      IN      CNAME           webserver
  • 在从服务器中定义区域解析信息 /etc/named.rfc1912.zones
zone "yufu.com" IN {
        type slave;
        masters { 192.168.214.128; };
        file "slaves/gudaoyufu.com.zone";
};

注意:从服务器上定义的域必须要与主服务器上相同,从的type类型为:slave,必须要是指定master是谁,否则找不到同步对象,定义的同步解析库文件存放文章默认在/var/named/slaves目录下

  • 在主从的named.conf文件中添加要、区域库传送控制,以保障服务器的信息安全:这个的作用是干嘛的?用一个示列一下就看明白

不做区域传送控制前,用任意一台主机都可以获取到DNS区域解析库文件中的服务器信息

[[email protected] html]# dig -t axfr yufu.com @192.168.214.128

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.62.rc1.el6_9.5 <<>> -t axfr yufu.com @192.168.214.128
;; global options: +cmd
yufu.com.       86400   IN  SOA ns1.yufu.com. amin.yufu.com.yufu.com. 2018051504 3600 300 604800 86400
yufu.com.       86400   IN  A   192.168.214.135
yufu.com.       86400   IN  A   192.168.214.136
yufu.com.       86400   IN  NS  ns1.yufu.com.
yufu.com.       86400   IN  NS  ns2.yufu.com.
yufu.com.       86400   IN  MX  10 mx1.yufu.com.
yufu.com.       86400   IN  MX  20 mx2.yufu.com.
mx1.yufu.com.       86400   IN  A   192.168.214.189
mx2.yufu.com.       86400   IN  A   192.168.214.190
ns1.yufu.com.       86400   IN  A   192.168.214.128
ns2.yufu.com.       86400   IN  A   192.168.214.134
webserver.yufu.com. 86400   IN  A   192.168.214.135
webserver.yufu.com. 86400   IN  A   192.168.214.136
www.yufu.com.       86400   IN  CNAME   webserver.yufu.com.
yufu.com.       86400   IN  SOA ns1.yufu.com. amin.yufu.com.yufu.com. 2018051504 3600 300 604800 86400
;; Query time: 2 msec
;; SERVER: 192.168.214.128#53(192.168.214.128)
;; WHEN: Sat May 19 20:13:07 2018
;; XFR size: 15 records (messages 1, bytes 344)

添加传送控制,只允许主从间传送,定义规则:allow-transfer { 192.168.214.134; };

[[email protected] html]# dig -t axfr yufu.com @192.168.214.128

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.62.rc1.el6_9.5 <<>> -t axfr yufu.com @192.168.214.128
;; global options: +cmd
; Transfer failed.

看到区别了吧,如果不做限制,任何人可以获取到服务器的部署情况这是一个很大的安全隐患。

在主DNS服务器中只允许从服务器传送,而对于从服务器,则要拒绝任何主机进行传送
最终在/etc/named.conf中配置如下:

  • 主:allow-transfer { 192.168.214.134; };

  • 备:allow-transfer { none; };

配置好主从服务器后检查配置有没有问题,执行:** named-checkconf**

没问题后重启或重载服务器:rndc reload
如果顺利的话,在从服务器的/var/named/slaves目录中已经有了主服务器中的gudaoyufu.com.zone文件

[[email protected] ~]# ls /var/named/slaves/
1  gudaoyufu.com.zone

从服务器已经同步成功,这时可以关闭主服务器,测试解析,先将测试的客户端添加DNS地址

echo "nameserver 192.168.214.128" > /etc/resolv.conf 
echo "nameserver 192.168.214.134" > /etc/resolv.conf 

关闭主DNS服务器: systemctl stop named
在客户端请求www.yufu.com 如下:

[[email protected] ~]# curl http://www.yufu.com/index.html
<html>
<title>Welcome to nginx!</title>
<h1>Welcome to nginx!</h1>
this is test page
ip:192.168.214.135
</html>

[[email protected] ~]# curl http://www.yufu.com/index.html
<html>
    <head>
this is test page
IP: 192.168.214.136 
   </body>
</html>

DNS转发

如果客户端向DNS服务器发起的解析请求内容不在本服务器上,那么可以设置DNS转发,将解析请求转发到其他DNS服务器。DNS转发分两种情况,一种是只要本地没有解析内容的都转发到指定的DNS服务器上这种转发叫(全局转发),另一种是进行匹配转发,只要解析请求符合定义的某个域,就把该请求转发到指定的DNS服务器上这种转发叫(区域转发):

要实现上面的过程,要在两台DNS上做相应的配置:

  • 在主DNS上要定义转发规则,
  • 开启请求者做递归,否则转发请求不予进行

recursion yes;

  • 第二台DNS上要有相应的域解析库内容
  • 注意:关闭dnssec功能:

dnssec-enable no;

dnssec-validation no;

配置主DNS转发规则

(1) 全局转发: 对非本机所负责解析区域的请求,全转发给指定的服务器,在/etc/named.conf中options定义

forward first|only;
forwarders { ip;};

(2) 特定区域转发:仅转发对特定的区域的请求,比全局转发优先级高,在 /etc/named.rfc1912.zones中定义区域信息

zone "ZONE_NAME" IN {
type forward;
forward first | only;
forwarders { ip;};
};

下面分别实现这两种转发方式,先看第一种转发:全局转发

全局转发

配主DNS配置文件/etc/named.conf

forward only;
forwarders  { 192.168.214.134; };
dnssec-enable no;
dnssec-validation no;

注意:recursion yes; 主DNS必须要开启递归查询,否则解析请求转发不出去

接收转发DNS端配置:
定义区域文件信息:vim /etc/named.rfc1912.zones

zone "abc123.com" IN {
        type master;
        file "abc123.com.zone";
};

编写区域解析库文件:vim /var/named/abc123.com.zone

$TTL 1D
@       IN      SOA     ns1.abc123.com. amin.abc123.com (
                        2018051507
                        1H
                        5M
                        7D
                        1D )


          IN      NS      ns1.abc123.com.
ns1       IN      A       192.168.214.134
www       IN      A       192.168.214.133
@         IN      A      192.168.214.133

重载DNS并测试:

rndc reload

dig测试:

[[email protected] ~]# dig www.abc123.com @192.168.214.128

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.62.rc1.el6_9.5 <<>> www.abc123.com @192.168.214.128
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11968
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1

;; QUESTION SECTION:
;www.abc123.com.            IN  A

;; ANSWER SECTION:
www.abc123.com.     86268   IN  A   192.168.214.133

;; AUTHORITY SECTION:
abc123.com.     86268   IN  NS  ns1.abc123.com.

;; ADDITIONAL SECTION:
ns1.abc123.com.     86268   IN  A   192.168.214.134

;; Query time: 1 msec
;; SERVER: 192.168.214.128#53(192.168.214.128)
;; WHEN: Sun May 20 02:01:31 2018
;; MSG SIZE  rcvd: 82

访问测试

[[email protected] ~]# curl http://www.abc123.com/index.html

<html>
    <body>
www.abc123.com
IP: 192.168.214.133
    </body>
</html>

[[email protected] ~]# cat /etc/resolv.conf 
nameserver 192.168.214.128

区域转发

设置区域转发要在主DNS的named.rfc.1912.zones文件中定义区域信息:

zone "abc123.com"  IN {
        type forward;
        forward only;
        forwarders { 192.168.214.134; };

};

设置后情况一下DNS缓存再重载服务:

rndc flush
rndc reload

测试访问

[[email protected] ~]# curl http://www.abc123.com/index.html

<html>
    <body>
www.abc123.com
IP: 192.168.214.133
    </body>
</html>

智能DNS

智能DNS解析根据客户机IP地址归属地区域进行区别响应,这里根据ip地址网段实现按ip地址区域解析的过程:

  • 在DNS的主配置文件中定义ACL规则,注意,ACL规则必须定义在named.conf的最前面;
    acl是根据从上到下顺序查找匹配的,acl中ip存在包含关系,应该小范围地址段先定义,大网段在后面,如果大网段在上面会使下面有包含关系的小网段不生效
acl beijing {
        192.168.214.0/24;

};

acl jiangsu {
        172.20.110.0/24;
};

acl other {
        any;
};
  • 定义解析库文件

为每个IP地址范围定义单独的解析库文件

[[email protected] named]# cp gudaoyufu.com.zone gudaoyufu.com.zone.beijing
[[email protected] named]# cp gudaoyufu.com.zone gudaoyufu.com.zone.jiangsu

记得修改解析库文件的属组为named

  • 将acl与各区域解析库文件关联起来:使用view

注意:一旦采用view,必须把所以的区域信息放在view语句块中,所以named.conf中的这段内容移动到named.rfc1912.zones中

zone "." IN {
        type hint;
        file "named.ca";
};
  • 创建view

先创建单独区域文件,在view中要指定

[[email protected] named]# cp -p /etc/named.rfc1912.zones /etc/named.rfc1912.zones.beijing
[[email protected] named]# cp -p /etc/named.rfc1912.zones /etc/named.rfc1912.zones.jiangsu

在named.rfc1912.zones.beijing单独的文件中定义如下:


zone "yufu.com" IN {
        type master;
        file "gudaoyufu.com.zone.beijing";
};

在named.rfc1912.zones.jiangsu单独的文件中定义如下:

zone "yufu.com" IN {
        type master;
        file "gudaoyufu.com.zone.jiangsu";
};

在named.conf中定义view

view beijngview {
        match-clients   {beijing;};
        include  "/etc/named.rfc1912.zones.beijing";

};

view jiangsuview {
        match-clients   {jiangsu;};
        include  "/etc/named.rfc1912.zones.jiangsu";

};


view otherview {
        match-clients   {other;};
        include  "/etc/named.rfc1912.zones";

};

这里的other就使用默认的区域文件,
上面的view信息也可以直接将etc/named.rfc1912.zones.jiangsu中的内容直接写在view块中









以上是关于图解 DNS 域名解析与负载均衡的主要内容,如果未能解决你的问题,请参考以下文章

网络协议趣谈DNS协议域名解析和负载均衡

多活分布式数据中心如何实现DNS域名解析和负载均衡?

DNS学习笔记

浅谈智能DNS云解析

浅谈智能DNS云解析

负载均衡(摘抄)