DNS实战--2

构建企业级DNS
服务压测,服务的功能测试,这些在生产中都要考虑到

1、硬件选型
dns对网卡和cpu消耗大
下面配置可以达到单台服务器每秒3万请求,0延时
CPU:12c以上配置
内存:16GB
网络:千兆

2、初始化系统
关闭selinux,iptables,调整ulimit限制

3、构建高性能,高可用dns
采用lvs-dr模式负载均衡,多idc,多套dns集群,通过master-slave技术保证dns配置的一致性
(1)、高可用
物理层:
首先确保两台lvs不在统一机柜、同一物理交换机接入;
其次确保将所有dns服务器也做到不在同一机柜、同一物理交换机接入。
同时,在不同的idc构建多套dns集群,为客户端提供可切换的配置。

服务层:
坚决摒弃lvs上端口检测这种方式,采用自定义脚本检测,为dns的健康检测单独设置一个域名,就为了lvs检测dns是否存活而设计。

脚本示例,这个脚本是部署在lvs上,做健康检测的

#!/bin/sh
timeout=5
Q="baidu.com"
host="/usr/bin/host"
if test -z "$1" ;then
    echo "You need to supply a DNS Server to check. Quitting"
    exit;
fi
SERVER=$1
ERC=`$host -s -w $timeout $Q $SERVER > /dev/null 2>&1;echo $?`
if [ $ERC -eq 0 ];then
    exit 0
else exit 1
fi

客户端层:
多idc之间的流量切换是通过客户端的健康检测cron实现的,脚本每分钟运行一次,分别检测每个dns集群虚地址的可用性。

(2)、高性能
通过lvs可以对每个集群做横向扩容,是否需要扩容的一句是对现有系统的压测结果,以及实时的监控数据。
亦或者可以在靠近应用层处,加上一层cache-only集群,但前提是你的线上环境中,没人任何系统依赖于dns负载均衡

4、压测

安装queryperf
解压bind源码: tar zxf bind-9.7.3.tar.gz
进入解压后的bind源码目录:
[root@linux-node1 tools]# wget  http://ftp.isc.org/isc/bind9/9.7.3/bind-9.7.3.tar.gz
--2017-05-19 15:38:02--  http://ftp.isc.org/isc/bind9/9.7.3/bind-9.7.3.tar.gz
Resolving ftp.isc.org... 149.20.1.49
Connecting to ftp.isc.org|149.20.1.49|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 7653584 (7.3M) [application/x-gzip]
Saving to: “bind-9.7.3.tar.gz”

100%[======================================================================>] 7,653,584   1.13M/s   in 7.9s    

2017-05-19 15:38:12 (950 KB/s) - “bind-9.7.3.tar.gz” saved [7653584/7653584]

[root@linux-node1 tools]# tar xfz bind-9.7.3.tar.gz 
[root@linux-node1 tools]# cd bind-9.7.3/contrib/queryperf/

  

配置和编译

[root@linux-node1 queryperf]# ./configure 
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables... 
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for library containing res_mkquery... no
checking for library containing __res_mkquery... -lresolv
checking for socket in -lsocket... no
checking for inet_ntoa in -lnsl... yes
checking for gethostbyname2... yes
checking for getaddrinfo... yes
checking for getnameinfo... yes
checking for socklen_t... yes
checking for sa_len... no
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
[root@linux-node1 queryperf]# make 
gcc  -DHAVE_CONFIG_H -c queryperf.c
gcc  -DHAVE_CONFIG_H  queryperf.o  -lnsl -lresolv  -lm -o queryperf
[root@linux-node1 queryperf]# 

  

会在当前目录下出现queryperf,可以将它拷贝至/usr/bin/下
[root@linux-node1 queryperf]# ls
config.h     config.log     configure     input     Makefile.in  queryperf    queryperf.o  utils
config.h.in  config.status  configure.in  Makefile  missing      queryperf.c  README
[root@linux-node1 queryperf]# cp queryperf /usr/bin/
[root@linux-node1 queryperf]# 

  

测试,可以查看解析成功率和解析时间
[root@linux-node1 queryperf]# cat test.txt 
www.baidu.com A
www.qq.com A
www.sina.com A
www.dangdang.com A
[root@linux-node1 queryperf]# queryperf -d test.txt -s 10.0.1.161

DNS Query Performance Testing Tool
Version: $Id: queryperf.c,v 1.12 2007-09-05 07:36:04 marka Exp $

[Status] Processing input data
[Status] Sending queries (beginning with 10.0.1.161)
[Status] Testing complete

Statistics:

  Parse input file:     once
  Ended due to:         reaching end of file

  Queries sent:         4 queries
  Queries completed:    4 queries
  Queries lost:         0 queries
  Queries delayed(?):   0 queries

  RTT max:         	0.172311 sec
  RTT min:              0.000703 sec
  RTT average:          0.075561 sec
  RTT std deviation:    0.063613 sec
  RTT out of range:     0 queries

  Percentage completed: 100.00%
  Percentage lost:        0.00%

  Started at:           Fri May 19 15:43:39 2017
  Finished at:          Fri May 19 15:43:39 2017
  Ran for:              0.172392 seconds

  Queries per second:   23.202933 qps

[root@linux-node1 queryperf]# 

  

5、监控

监控结合zabbix实现

系统基础性能:
使用zabbix自带模板即可。cpu、内存、主机存活、磁盘空间、主机运行时间、系统load

LOOPBACK地址绑定状态监控:
该架构中,dnsserver在集群中充当realserver的角色,在dr中,需要绑定loopback的地址方能通信,因此当loopback地址没有绑定上时,lvs健康检测通过,但是当请求到达dnsserver时,请求被拒绝,dns集群会出现异常。

DNS数据与MASTER一致性监控:
一是通过写zabbix自定义discovery,扫出dns配置中所有zone,然后分别对比slave和master每个zone的serial值,当slave与master的值持续5分钟不一致时报警
二是写脚本,每15分钟扫一遍master上所有域名解析结果,与每个slave的结果做对比,当出现结果不一致时,报警

DNS响应时间监控:
远端一组主机跑在fullnat下(提供高可用),通过dig命令监测dnsserver的响应时间。

其中Query time就是查询的时间

[root@linux-node1 ~]# dig @127.0.0.1 www.baidu.com

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.62.rc1.el6_9.2 <<>> @127.0.0.1 www.baidu.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 31992
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available

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

;; Query time: 2 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Fri May 19 17:10:27 2017
;; MSG SIZE  rcvd: 31

[root@linux-node1 ~]#
有人觉得3ms慢,有人觉得30ms慢,没特别的统一的标准

DNS每秒请求数监控:

主配置文件中,这个文件可以用于监控
[root@linux-node1 ~]# grep stats /etc/named.conf 
  Statistics-file "/var/named/chroot/var/log/named_stats";
  memstatistics-file "log/mem_stats";
[root@linux-node1 ~]# 
先执行rndc stats生成状态文件
[root@linux-node1 ~]# rndc stats
WARNING: key file (/etc/rndc.key) exists, but using default configuration file (/etc/rndc.conf)
查看状态文件
[root@linux-node1 ~]# cat /var/named/chroot/var/log/named_stats
+++ Statistics Dump +++ (1495185099)
++ Incoming Requests ++
                 393 QUERY
++ Incoming Queries ++
                  23 A
                 362 SOA
                   3 MX
                   3 AAAA
++ Outgoing Queries ++
[View: GROUP1]
                  11 A
                   3 NS
                   1 MX
                   1 AAAA
[View: GROUP2]
[View: _bind]
++ Name Server Statistics ++
                 393 IPv4 requests received
                 362 requests with EDNS(0) received
                 393 responses sent
                 362 responses with EDNS(0) sent
                  24 queries resulted in successful answer
                   6 queries resulted in authoritative answer
                 385 queries resulted in non authoritative answer
                 362 queries resulted in referral answer
                   5 queries resulted in nxrrset
                  14 queries caused recursion
++ Zone Maintenance Statistics ++
++ Resolver Statistics ++
[Common]
[View: GROUP1]
                  16 IPv4 queries sent
                  16 IPv4 responses received
                  14 queries with RTT 10-100ms
                   2 queries with RTT 100-500ms
[View: GROUP2]
[View: _bind]
++ Cache DB RRsets ++
[View: GROUP1 (Cache: GROUP1)]
                   4 A
                   1 NS
                   6 CNAME
                   1 MX
                   1 RRSIG
[View: GROUP2 (Cache: GROUP2)]
[View: _bind (Cache: _bind)]
++ Socket I/O Statistics ++
                  18 UDP/IPv4 sockets opened
                   3 TCP/IPv4 sockets opened
                  16 UDP/IPv4 sockets closed
                   2 TCP/IPv4 sockets closed
                  16 UDP/IPv4 connections established
                   3 TCP/IPv4 connections accepted
++ Per Zone Query Statistics ++
[viewlnh.com (view: GROUP1)]
                   1 queries resulted in successful answer
                   3 queries resulted in authoritative answer
                   2 queries resulted in nxrrset
[viewlnh.com (view: GROUP2)]
                   1 queries resulted in successful answer
                   3 queries resulted in authoritative answer
                   2 queries resulted in nxrrset
[version.bind (view: _bind)]
[hostname.bind (view: _bind)]
[authors.bind (view: _bind)]
[id.server (view: _bind)]
--- Statistics Dump --- (1495185099)
[root@linux-node1 ~]# 

  

在每台dns主机上,编写zabbix脚本,分析named_stats文件,获取每秒请求数
下面这个脚本比较粗略,有时间可以自己优化下,加锁,记录日志等。
#!/bin/bash
#rndc stats
STATS='/var/named/chroot/var/log/named_stats'
if [ $# -ne 1 ];then
    echo "$0 [querys]"
    exit 2
else
    which=$1
fi

if [ -f "${STATS}" ];then
    echo > ${STATS}
    rndc stats >dev/null 2>&1
else
    echo "${STATS} not found "
    exit 2
fi    

case ${which} in
querys)
    RESULT=` awk '{if ($2=="QUERY")  {print $1}}' ${STATS}`
    ;;
*)
    echo "$0 [querys]"
    exit 2
    ;;
esac

echo ${RESULT}

  

DNS可用性监控:

远端一组主机跑在fullnat下(提供高可用),通过host命令监测dnsserver的可用性,脚本与lvs健康检测脚本类似

6、自动化


saltstack安装、部署
通过定制saltstack配置,实现自动、批量安装、部署dns

配置管理自动化
业界最多的是bind-dlz,dlz是指将所有的配置都存在mysql表中,对bind做特殊配置,使得每次bind
接受的请求都去mysql中查询数据之后返回给用户

bind-dlz的优缺点
优势:将数据全部存在数据库,符合运维开发的理念。
劣势:每次解析都要select数据库,性能低下;增加了系统的耦合性,还需要保证mysql的高可用

我的方案
采用dlz的数据库部分表结构;
用thinkphp 实现对mysql的增删改查,和一些权限控制的页面,在该页面,用户可以完成对域名的增删改查操作,数据源在mysql中;
通过saltstack+py实现从mytsql中调数据,生成bind的配置文件,并检测文件格式,之后reload
改造了,提前生成dns的配置文件。这样mysql挂了没事

为什么要做成页面可以管理的呢

为什么做这些,我要将dns做成可交付,已维护的系统,交付给应用运维同学使用,我只负责dns架构的server端
https://github.com/shanks1127/dns

7、安全
时刻关注dns相关的抖动、补丁;
选用稍大些的厂商作为域名服务商,我们是万网;
对服务器的登录日志做监控分析;

8、日常运维规范
dns作为基础服务,在做好高可用,高性能,好扩容的基础上,任何时刻都不能掉以轻心
确保所有监控均处于生效状态;
所有新机器,均在saltstack上完成初始化和安装、部署操作,不能单独操作;
所有针对dns架构调整的操作,均需在流量低谷时操作;
对集群扩容操作时,务必对新加入节点做压测,同时重启服务器并检测重启后各项指标是否正常;
关注dns相关新闻,时刻根据

9、DNS发展趋势

(1)DNSMASQ
DNSmasq是一个小巧且方便地用于配置DNS和DHCP的工具,适用于小型网络,它提供了DNS功能和可选择的DHCP功能。
它服务那先只在本地使用的域名,这些域名是不会在全球的DNS服务器中出现的。
DHCP服务器和DNS服务器结合,并且允许DHCP分配的地址能在DNS中正常解析,而这些DHCP分配的地址和相关命令可以配置到每台主机中,
也可以配置到一台核心设备中(比如路由器),DNSmasq支持静态和动态两种DHCP配置方式。
有一些公司在每台服务器上都起着dnsmasq,充当本地dns缓存服务,来提高dns解析性能同时减轻dnsserver的压力。

(2)HTTPDNS
但凡使用域名来给用户提供服务的互联网企业,都或多或少无法避免在有中国特色的互联网环境中遭遇到各种域名被缓存、用户跨网访问缓慢等问题。
首先是域名缓存,不同运营商、不同节点的缓存时间设置的差别较大。这样在流量切换时,就会产生新、旧应用数据不一致的现象。
其次就是域名解析过了太多层的nat,这就导致dns获取客户端地址时很难准确定位,从而智能dns的准确度大打折扣。
最近几年httpdns出现了,用户明确的知道我在访问某厂的服务时,应该去找哪个ip要对应的域名,实现这个的前提是你可以左右用户的访问习惯,目前应用最合适的场景是app。

 参照如下链接http://www.dnsdizhi.com/post-240.html

HttpDNS的原理非常简单,主要有两步:

A、客户端直接访问HttpDNS接口,获取业务在域名配置管理系统上配置的访问延迟最优的IP。
(基于容灾考虑,还是保留次选使用运营商LocalDNS解析域名的方式)

B、客户端向获取到的IP后就向直接往此IP发送业务协议请求。以Http请求为例,通过在header中指定host字段,向HttpDNS返回的IP发送标准的Http请求即可。

(2)HttpDNS优势:
从原理上来讲,HttpDNS只是将域名解析的协议由DNS协议换成了Http协议,并不复杂。但是这一微小的转换,却带来了无数的收益:
A、根治域名解析异常:由于绕过了运营商的LocalDNS,用户解析域名的请求通过Http协议直接透传到了腾讯的HttpDNS服务器IP上,用户在客户端的域名解析请求将不会遭受到域名解析异常的困扰。

B、调度精准:HttpDNS能直接获取到用户IP,通过结合腾讯自有专利技术生成的IP地址库以及测速系统,可以保证将用户引导的访问最快的IDC节点上。
C、实现成本低廉:接入HttpDNS的业务仅需要对客户端接入层做少量改造,无需用户手机进行root或越狱;而且由于Http协议请求构造非常简单,兼容各版本的移动操作系统更不成问题;
另外HttpDNS的后端配置完全复用现有权威DNS配置,管理成本也非常低。总而言之,就是以最小的改造成本,解决了业务遭受域名解析异常的问题,并满足业务精确流量调度的需求。

D、扩展性强:HttpDNS提供可靠的域名解析服务,业务可将自有调度逻辑与HttpDNS返回结果结合,实现更精细化的流量调度。比如指定版本的客户端连接请求的IP地址,指定网络类型的用户连接指定的IP地址等。

当然各位可能会问:用户将首选的域名解析方式切换到了HttpDNS,那么HttpDNS的高可用又是如何保证的呢?另外不同运营商的用户访问到同一个HttpDNS的服务IP,用户的访问延迟如何保证?

为了保证高可用及提升用户体验,HttpDNS通过接入了腾讯公网交换平台的BGP Anycast网络,与全国多个主流运营商建立了BGP互联,保证了这些运营商的用户能够快速地访问到HttpDNS服务;
另外HttpDNS在多个数据中心进行了部署,任意一个节点发生故障时均能无缝切换到备份节点,保证用户解析正常。

原文地址:https://www.cnblogs.com/nmap/p/6880568.html