昨天老毕跟我讨论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的方式。
比如下面个设置:
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的内容如下:
#!/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结构图:
最后附一个自己写的spec文件,用来实现chroot的自定义rpm包,继承到yum源中实现dns的快速部署。
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 ." ; 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 . - Create SPEC file.