昨天老毕跟我讨论dns的问题,今天想了想,其实实际在生产环境中用到的dns大体有3种:
1.内网调用DNS
 一般是每个机房一组,做ms结构,主要功能是供机房内部应用之间调用解析,减少对hosts的依赖,避免硬编码。一般ms结构就可以了,不太会做其他的高可用。
2.回源调用dns
 和内网调用dns功能差不多,不过这个是跨机房的调用,而且一般会通过view做智能dns解析。
比较常见的应用场景就是webcdn的回源dns,结构上和内部调用dns差不多。
3.外网dns
 提供各种针对外网的解析,A记录,CNAME,MX等等。。
作为用户访问的入口,其重要性也不言而喻,因此对可用性和扩展性以及性能要求会比较高。
 一般的做法是在BGP机房做一个高可用的集群做主要的解析工作,同时在双线或者单线机房做一组冷备的高可用DNS集群。
 这里讨论下用lvs做dns高可用的方案,主要借鉴了mysql高可用的方案(一般都是一个主库,后面挂多个丛库,丛库前面使用lvs+keepalived做ha,程序写入主库,读取丛库)。
具体的流程如下:
1.用户通过web前端来做dns的增删改等操作(如果是python程序的话,可以通过dnspython操作)。
2.slave通过对比zone文件的serial值来决定是否需要更新记录。
3.用户查询请求至由lvs(dr模式)+keepalived组成的前端负载均衡。
4.lvs分发请求至slave server,最后由slave server直接向用户响应请求。

由于dns一般情况是用udp协议的(关于dns使用的协议可以参考之前的blog),而大家一般都是用lvs做tcp的load balance.
在用lvs实现udp的load balance时主要注意以下几点:
1.添加realserver时选择udp,配置文件中设置 protocol UDP
2.应用的监听IP要设置为vip,在这个场景中可以更改slave dns的设置 listen-on port 53 {vip ;物理ip;};
其中vip用来实现接收lvs的转发包并返回数据给用户,物理ip用来实现master到slave的同步
3.health check需要注意,lvs提供的HTTP_GET和TCP_CHECK都是基于TCP协议的(TCP的SYNC包来检查应用)
对于udp的检查可以使用 MISC_CHECK的方式。
比如下面个设置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
virtual_server vip 53 {
      delay_loop 2
      lb_algo rr
      lb_kind DR
      protocol UDP
      real_server real_server1 53 {
      weight 100 
      MISC_CHECK {
           misc_path  "/etc/keepalived/check_named.sh real_server1"
           misc_timeout 5
         }
      }
         real_server real_server2 53 {
         weight 100
      MISC_CHECK {
           misc_path  "/etc/keepalived/check_named.sh real_server2"
           misc_timeout 5
         }
         }
}
其中/etc/keepalived/check_named.sh的内容如下:
1
2
3
4
5
6
7
8
#!/bin/bash
SERVER=$1
OK=` nslookup   www. test .com $SERVER| grep  ipxxxx`
if  "$OK"  ==  ""  ] ;  then
     exit  1;
else
     exit  0;
fi
即返回0代表dns服务正常,返回1代表服务异常,将会被lvs踢出。
高可用的dns结构图:

wKioL1L45CryaLcAAAGU1cxArMI275.jpg

最后附一个自己写的spec文件,用来实现chroot的自定义rpm包,继承到yum源中实现dns的快速部署。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
Name:           Vipshop-Bind-Chroot
Summary:        This is  for  Vipshop dns server.
Group:          System Environment /Daemons
Version:        1.0
Release:        0
License:        Copyright 2011 Vipshop Inc.
Source:         Vipshop-Bind-Chroot-1.0. tar .gz
URL:            http: //www .vipshop.com
Packager:       EricNi
Vendor:         Vipshop Inc.
Provides:       Vipshop Inc.
BuildRequires:  gcc-c++
%description
This is DNS Service pakeage , and it only distributed  in  Vipshop Servers .
%prep
test  -d  /usr/local/named  &&  rm  -rf  /usr/local/named
[ ` cat  /etc/passwd | grep  named| wc  -l` - eq  0 ] &&  useradd  named -M -s  /sbin/nologin
mkdir  -p   /usr/local/named  /usr/local/named/var/slaves   /usr/local/named/var/named  /usr/local/named/var/etc   /usr/local/named/var/log
mkdir  -p   /var/named/chroot/etc/namedb  /var/named/chroot/etc/log  /var/named/chroot/etc/run    /var/named/chroot/var/run  /var/named/chroot/dev/   /var/named/chroot/etc/namedb/slaves   /var/named/chroot/etc/namedb/acl
%setup -n %{name}-%{version}
%build
export  BIND_HOME= /usr/local/named
export  BIND_CHROOT_HOME= /var/named/chroot
. /configure  --prefix=${BIND_HOME} -- enable -threads  --sysconfdir= /etc   --disable-openssl-version-check
make
make  install
cat  > ${BIND_CHROOT_HOME} /etc/named .conf <<  "EOF"
options {
directory  "/etc/namedb" ;
version  "vipshop-cdn-dns" ;
pid- file  "/etc/run/named.pid" ;
listen-on port 53 {any;};
allow-query {any;};
recursion  yes ;
dump- file  "/etc/namedb/cache_dump.db" ;
zone-statistics  yes ;
statistics- file  "/etc/namedb/named_stats.txt" ;
};
logging {
    channel warning
    { file  "/etc/log/named.log"  versions 3 size 2048k;
    severity warning;
    print-severity  yes ;
    print-category  yes ;
    print- time  yes ;
   };
    channel query
    { file  "/etc/log/query.log"  versions 3 size 2048k;
    severity info;
    print-category  yes ;
    print-severity  yes ;
    print- time  yes ;
    };
category queries
    {
     query;
    };
category default
    {
     warning;
    };
};
zone  "."  IN {
type  hint;
file  "named.root" ;
};
zone  "localhost"  IN {
type  master;
file  "localhost.zone" ;
};
zone  "0.0.127.in-addr.arpa"  IN {
type  master;
file  "slaves/localhost.rev" ;
};
zone  "vipshop.com"  IN {
type  master;
file  "vipshop.zone" ;
notify  yes ;
also-notify {180.186.22.62;};
allow-transfer {
      180.186.22.62;
                 };
};
key  "rndc-key"  {
         algorithm hmac-md5;
         secret  "f8Na2kl/4NuCNPEZ0f2C1Q==" ;
};
controls {
         inet 127.0.0.1 port 953
                 allow { 127.0.0.1; } keys {  "rndc-key" ; };
};
EOF
cat  > ${BIND_CHROOT_HOME} /etc/rndc .conf <<  "EOF"
key  "rndc-key"  {
         algorithm hmac-md5;
         secret  "f8Na2kl/4NuCNPEZ0f2C1Q==" ;
};
options {
         default-key  "rndc-key" ;
         default-server 127.0.0.1;
         default-port 953;
};
EOF
cat  > ${BIND_CHROOT_HOME} /etc/rndc .key <<  "EOF"
key  "rndc-key"  {
         algorithm hmac-md5;
         secret  "f8Na2kl/4NuCNPEZ0f2C1Q==" ;
};
EOF
cat  /etc/rndc .conf <<  "EOF"
key  "rndc-key"  {
         algorithm hmac-md5;
         secret  "f8Na2kl/4NuCNPEZ0f2C1Q==" ;
};
options {
         default-key  "rndc-key" ;
         default-server 127.0.0.1;
         default-port 953;
};
EOF
cat  >  ${BIND_CHROOT_HOME} /etc/namedb/named .root <<  "EOF"
;       This  file  holds the information on root name servers needed to
;       initialize cache of Internet domain name servers
;       (e.g. reference this  file  in  the  "cache  .  <file>"
;       configuration  file  of BIND domain name servers).
;
;       This  file  is made available by InterNIC
;       under anonymous FTP as
;            file                 /domain/named .cache
;           on server           FTP.INTERNIC.NET
;       -OR-                    RS.INTERNIC.NET
;
;       last update:    Jan 3, 2013
;       related version of root zone:   2013010300
;
; formerly NS.INTERNIC.NET
;
.                        3600000  IN  NS    A.ROOT-SERVERS.NET.
A.ROOT-SERVERS.NET.      3600000      A     198.41.0.4
A.ROOT-SERVERS.NET.      3600000      AAAA  2001:503:BA3E::2:30
;
; FORMERLY NS1.ISI.EDU
;
.                        3600000      NS    B.ROOT-SERVERS.NET.
B.ROOT-SERVERS.NET.      3600000      A     192.228.79.201
;
; FORMERLY C.PSI.NET
;
.                        3600000      NS    C.ROOT-SERVERS.NET.
C.ROOT-SERVERS.NET.      3600000      A     192.33.4.12
;
; FORMERLY TERP.UMD.EDU
;
.                        3600000      NS    D.ROOT-SERVERS.NET.
D.ROOT-SERVERS.NET.      3600000      A     199.7.91.13
D.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2D::D
;
; FORMERLY NS.NASA.GOV
;
.                        3600000      NS    E.ROOT-SERVERS.NET.
E.ROOT-SERVERS.NET.      3600000      A     192.203.230.10
;
; FORMERLY NS.ISC.ORG
;
.                        3600000      NS    F.ROOT-SERVERS.NET.
F.ROOT-SERVERS.NET.      3600000      A     192.5.5.241
F.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:2F::F
;
; FORMERLY NS.NIC.DDN.MIL
;
.                        3600000      NS    G.ROOT-SERVERS.NET.
G.ROOT-SERVERS.NET.      3600000      A     192.112.36.4
;
; FORMERLY AOS.ARL.ARMY.MIL
;
.                        3600000      NS    H.ROOT-SERVERS.NET.
H.ROOT-SERVERS.NET.      3600000      A     128.63.2.53
H.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:1::803F:235
;
; FORMERLY NIC.NORDU.NET
;
.                        3600000      NS    I.ROOT-SERVERS.NET.
I.ROOT-SERVERS.NET.      3600000      A     192.36.148.17
I.ROOT-SERVERS.NET.      3600000      AAAA  2001:7FE::53
;
; OPERATED BY VERISIGN, INC.
;
.                        3600000      NS    J.ROOT-SERVERS.NET.
J.ROOT-SERVERS.NET.      3600000      A     192.58.128.30
J.ROOT-SERVERS.NET.      3600000      AAAA  2001:503:C27::2:30
;
; OPERATED BY RIPE NCC
;
.                        3600000      NS    K.ROOT-SERVERS.NET.
K.ROOT-SERVERS.NET.      3600000      A     193.0.14.129
K.ROOT-SERVERS.NET.      3600000      AAAA  2001:7FD::1
;
; OPERATED BY ICANN
;
.                        3600000      NS    L.ROOT-SERVERS.NET.
L.ROOT-SERVERS.NET.      3600000      A     199.7.83.42
L.ROOT-SERVERS.NET.      3600000      AAAA  2001:500:3::42
;
; OPERATED BY WIDE
;
.                        3600000      NS    M.ROOT-SERVERS.NET.
M.ROOT-SERVERS.NET.      3600000      A     202.12.27.33
M.ROOT-SERVERS.NET.      3600000      AAAA  2001:DC3::35
; End of File
EOF
cat  > ${BIND_CHROOT_HOME} /etc/namedb/localhost .zone <<  "EOF"
$TTL 86400
$ORIGIN localhost.
@ 1D IN SOA @ root (
42 ; serial (d. adams)
3H ; refresh
15M ; retry
1W ; expiry
1D ) ; minimum
1D IN NS @
1D IN A 127.0.0.1
EOF
cat  > ${BIND_CHROOT_HOME} /etc/namedb/localhost .rev <<  "EOF"
$TTL 86400
@ IN SOA localhost. root.localhost. (
1997022700 ; Serial
28800 ; Refresh
14400 ; Retry
3600000 ; Expire
86400 ) ; Minimum
IN NS localhost.
1 IN PTR localhost.
EOF
cat  > ${BIND_CHROOT_HOME} /etc/namedb/vipshop .zone <<  "EOF"
$TTL  86400
@     IN      SOA     ns1.vipshop.com.  root.vipshop.com.  (
                                         2013051501 ; Serial
                                         28800     ; Refresh
                                         14400     ; Retry
                                         3500000   ; Expire
                                         86400 )   ; Minimum
@        IN      NS      dns1
@       IN      NS      dns2
localhost       IN      A       127.0.0.1
img1            IN      A       xxxx
img3            IN      A       xxxx
img2            IN      A       xxxx
img2            IN      A       xxxx
dns1            IN      A       xxxx
dns2            IN      A       xxxx
EOF
cat  /etc/init .d /named  <<  "EOF"
#!/bin/bash
#
# named           This shell script takes care of starting and stopping
#                 named (BIND DNS server).
#
# chkconfig: - 13 87
# description: named (BIND) is a Domain Name Server (DNS) \
# that is used to resolve host names to IP addresses.
# probe: true
                 
# Source function library.
/etc/rc .d /init .d /functions
                 
# Source networking configuration.
[ -r  /etc/sysconfig/network  ] && .  /etc/sysconfig/network
                 
[ -r  /etc/sysconfig/named  ] && .  /etc/sysconfig/named
          [ -f  /usr/local/named/sbin/named   ] ||  exit  0
        #  [ -f /chroot/named/etc/named.conf ] || exit 0
         case  "$1"  in
            start)
                   # Start daemons.
                   echo  -n  "Starting named:"
                   daemon  /usr/local/named/sbin/named  -c  /etc/named .conf -u named -t  /var/named/chroot
                   echo
                   touch  /var/lock/subsys/named
                   ;;
            stop)
                   # Stop daemons.
                   echo  -n  "Shutting down named:"
                   #killproc named
           killall named
                   rm  -f  /var/lock/subsys/named
                   echo
                   ;;
            status)
           #status named
                   pid=`pidof -o %PPID -x named`
                   if  [ -z $pid ]
                   then
                         echo  "named is stopped!!!"
                   else
                         echo  "named is running: pid is $pid"
                   fi
                   exit  $?
                   ;;
            restart)
                   $0 stop
                   $0 start
                   exit  $?
                   ;;
            reload)
                   /usr/local/named/sbin/rndc  reload
                   exit  $?
                   ;;
            probe)
                   /usr/local/named/sbin/rndc  reload > /dev/null  2>&1 ||  echo  start
                   exit  0
                   ;;
            *)
                   echo  "Usage: named {start|stop|status|restart|reload}"
                   exit  1
         esac
         exit  0
EOF
chmod  755  /etc/init .d /named
mkdir  -p   /usr/local/named  /usr/local/named/var/slaves   /usr/local/named/var/named  /usr/local/named/var/etc   /usr/local/named/var/log
mkdir  -p  /var/named/chroot/usr   /var/named/chroot/etc/namedb   /var/named/chroot/var/run  /var/named/chroot/dev/   /var/named/chroot/etc/namedb/slaves  /var/named/chroot/etc/run  /var/named/chroot/etc/log  /var/named/chroot/etc/namedb/acl
chown  named:named   /var/named/chroot  -R
chown  700  /var/named/chroot
mknod  /var/named/chroot/dev/null  c  1 3
mknod  /var/named/chroot/dev/random  c  1 8
cp  /etc/localtime   /var/named/chroot/etc/
sed  -i  's/SYSLOGD_OPTIONS=\(.*\)/SYSLOGD_OPTIONS=\"-m 0 -a \/var\/named\/chroot\/dev\/log\"/g'  /etc/sysconfig/syslog
/etc/init .d /syslog  restart
%pre
if  [ ! ` grep  named  /etc/passwd ` ]; then
useradd   -M named  -s  /sbin/nologin
fi
%post
chkconfig --add named
chkconfig named on
chown  named:named   /var/named/chroot  -R
chown  named:named  /usr/local/named  -R
chown  700  /var/named/chroot
%clean
rm  -rf  /usr/local/named
rm  -rf  /var/named
%files
/etc/init .d /named
/usr/local/named/
/var/named/chroot/
%doc
%changelog
* Thu May 16 2013 Ericni <ericni@vipshop.com>.
- Create SPEC  file .