自建DNS系列——gdnsd (支持状态监控、负载均衡的GeoDNS )

一.介绍

之前看兽兽在V2上介绍了gdnsd的文章,马上点了一波收藏,因为CentOS没有现成的包,所以一直放在那懒得折腾。最近遇到CloudXNS这件事之后开始寻思着拿出来折腾下,在折腾了好几天PowerDNS后终于可以腾出手来搞这货了。

这个还是很有特色的,因为它有个插件系统,功能还是挺强大的,因为实现了自带的状态监控(http以及tcp),并且能够通过多个插件配合实现宕机切换,很有意思,还能通过外部命令来进行自定义的检测。此外,和PowerDNS不同的是这个由于使用了libmaxminddb库,支持GeoIP2格式数据库。

二.安装

比起PowerDNS不如的是这个连个spec都不给,我去网上翻来翻去,结合Github历史Commit中的spec撸了个出来,试了下没报错,感动,至于init脚本,其实不用也行,因为gdnsd自带控制,不过为了方便自启我还是找了个,别人写的,试了下还行就懒得自己动手了,已经打包到rpm文件中——>传送门 

官方的依赖有ragel,而且只支持6.x版本(貌似是因为7.0出来的比较晚或者说官方更新的不勤,最后更新还是16年的了),这就带来了一个问题,6没这个包,7又只有7.x的,于是我只能顺便打个ragel的包了,然后因为这个依赖colm,于是……还好主要就这俩,其他的rpmforge以及epel源里都有,当然,为了更好的使用我把libmaxminddb也打包了个最新版本。

总而言之,6的应该是能直接用我的包了,7的同学可以自己研究下_(:з」∠)_如果我哪天换7了也许会做一份……如果想自己编译的同学请参考官方安装指导——>传送门

另外为了方便请下载release版本,直接git的会比较麻烦,因为需要autoreconf然后对automake autoconf以及libtool都要求较高的版本,可能源里的不能满足要求。

6 快捷通道

yum install http://down.senra.me/Senra-Build/colm/colm-0.13.0.4-2.el6.x86_64.rpm -y
yum install http://down.senra.me/Senra-Build/ragel/ragel-6.10-1.el6.x86_64.rpm -y
yum install http://down.senra.me/Senra-Build/libmaxminddb/libmaxminddb-1.2.0-4.el6.x86_64.rpm -y
yum install http://down.senra.me/Senra-Build/gdnsd/gdnsd-2.2.4-1.el6.x86_64.rpm -y

在这个过程中可能安装其他依赖,如果出问题请添加rpmforge以及epel源。

这部分参考了一些东西,列举一下

  1. CentOS 6 / RHCE 6 gdnsd ( geo dns ) latest from source
  2. gdnsd的GitHub历史Commit
  3. Fedora上某个移植的Review

三.配置

rpm打包的时候我就把需要的各个配置目录以及运行用户全写进去了,所以不用额外处理,唯一需要在意的是如果要使用geoip功能请创建/etc//geoip 目录并把数据库丢这个文件夹里,下面演示的时候也会提到,这部分流程参考了兽兽的教程——>传送门

不过说在前头,这玩意我还没玩明白,很多玩法请参照man以及GitHub上的wiki——>传送门

简易GeoDNS配置,参照烧饼博客

 

cat >/etc/gdnsd/config<<'EOF' options => {
  listen => any ;监听所有interface,如果指定ip的话可以带上端口
  dns_port => 53 ;对于没有指定端口的ip就监听53端口
  chaos_response => "SenraDNS" ;返回信息
}
service_types => {
  example_monitor => { ;一个http检测插件
    plugin => http_status
    ok_codes => [200, 301, 302, 403, 404] ;认为这些返回码代表网站正常,可以自己选择
    vhost => example.org ;指定检测时使用的Host,因为只能检测ip,不带上Host会串网站
    url_path => / ;检测的url路径
  }
}
plugins => {
  geoip => { ;geoip插件
    maps => {
      china_map => {
        geoip_db => GeoLiteCity.dat ;指定数据库
        datacenters => [default-dc, cn-dc] ;类似meta插件指定的地址标签,按照官方说明geoip几乎包括了meta插件的全部代码,是它的超集,所以搞不懂可以去看看meta插件说明
        map => {
          AS => {CN => [cn-dc, default-dc]} ;指定大陆为AS(亚洲),国家为CN(中国)的返回cn-dc对应记录,不然就返回后一个default-dc,有多个大陆或者国家会全部匹配过去
        }
      }
    }
    resources => {
      example_org => {
        map => china_map ;使用的map映射
        service_types => example_monitor ;使用的检测服务
        dcmap => {
          cn-dc => {
          addrs_v4 => 192.0.2.4
          addrs_v6 => 2001:DB8::4
          },
          default-dc => {
          addrs_v4 => 192.0.2.5
          addrs_v6 => 2001:DB8::5
          },
        }
      }
    }
  }
}
EOF
 
cat >/etc/gdnsd/zones/example.com<<'EOF'
$TTL    86400
 
@   IN  SOA ns1.example.com.    hostmaster.example.com. (
    1      ; serial
    7200   ; refresh
    900    ; retry
    1209600     ; expire
    10800    ; ncache
)
 
@       NS      ns1.example.com.
@       NS      ns2.example.com.
 
ns1     A   192.0.2.2
ns2     A   192.0.2.3
 
ns1     AAAA    2001:DB8::2
ns2     AAAA    2001:DB8::3
EOF
 
cat >/etc/gdnsd/zones/example.org<<'EOF'
$TTL    3600
 
@   IN  SOA ns1.example.com.    hostmaster.example.com. (
    1      ; serial
    7200   ; refresh
    900    ; retry
    1209600     ; expire
    10800    ; ncache
)
 
@       NS      ns1.example.com.
@       NS      ns2.example.com.
 
@       DYNA    geoip!example_org ;使用配置中的geoip插件来实现动态A(DYA)记录
 
www     CNAME   example.org.
EOF
 
mkdir /etc/gdnsd/geoip
cd /etc/gdnsd/geoip
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz && gzip -df GeoLiteCity.dat.gz
 
#检测配置是否正确
service gdnsd checkconf
#检测gdnsd状态
service gdnsd status

插件介绍

#记录类
GdnsdPluginSimplefo 用于切换主备记录,可配合状态检测实现宕机切换,仅支持A(AAAA)记录
GdnsdPluginMultifo 类似上面的,但是这是多IP轮询状态下切换IP组,仅支持A(AAAA)记录
GdnsdPluginWeighted 带权重的负载均衡式,支持A(AAAA)记录以及CNAME记录
GdnsdPluginMetafo 这个是给记录或者记录组加标签,然后可以在其他插件中调用,支持A(AAAA)记录以及CNAME记录
GdnsdPluginGeoip 使用MaxMind的GeoIP或者GeoIP2格式数据库来进行基于地理位置的负载均衡GSLB,当然也可以用于实现GeoDNS(其实一个意思),仅支持A(AAAA)记录
#检测类
GdnsdPluginHttpStatus 可以通过http方式检测网站的状态码,如果在设置的正常状态码列表中即为正常,反之触发宕机切换,可指定端口
GdnsdPluginTcpConnect 类似上面的,但是是通过TCP检测端口是否为开放状态,可指定端口
GdnsdPluginExtmon 通过调用shell命令来进行检测,判断状态依靠返回码
GdnsdPluginExtfile 通过读取文件中的内容来判断状态,文件内容可以为其他监控生成数据,但是要依据格式
#特殊类
GdnsdPluginStatic 直接返回固定的解析结果,支持A(AAAA)记录以及CNAME记录,基本上只用于测试
GdnsdPluginReflect 用于在线调试的插件,可以根据配置返回请求解析的IP以及请求信息中的edns的IP
GdnsdPluginNull 额,这个……真的是null,ipv4返回0.0.0.0,ipv6返回::,CNAME返回invalid,别问我是拿来干嘛的,我也不知道

四.

这部分其实的话……跟PowerDNS差不多,rsync的可以参考烧饼博客的最后一部分,btsync和syncthing的看我博客历史文章吧,左边搜索一下就有,至于文件同步后重载配置,gdnsd也有和pdns_control reload类似的命令,是gdnsd reload-zones,使用了我的rpm包的建议前面加个service来通过init脚本重载

如果你的内核版本够高,比如是4.x的那么gdnsd有内置的inotify,会自动检测配置文件改动,如果是自带的2.63内核,那么请参照我PowerDNS的文章丢个zone_watcher脚本上去吧,改改zone文件位置就行,当然这里是文件夹类型的,建议如下,加上-r参数是递归检测文件夹内文件

echo "nohup zone_watcher 2>&1 >>/tmp/watcher.log &" >>/etc/rc.local
cat >/usr/bin/zone_watcher<<'EOF'
#!/bin/sh
cleanlog=`echo -n "" > /tmp/gdnsd-zone.log`
zonefile="/etc/gdnsd"
while inotifywait -qr -e modify,move_self $zonefile >/dev/null; do
 echo -e "`date "+%Y-%m-%d %H:%M:%S"` Zone Changed, Reload: [ `sleep 2 & pdns_control reload || echo -n "Failed"` ]" >>/tmp/pdns-zone.log
done
EOF
 
chmod +x /usr/bin/zone_watcher
nohup zone_watcher 2>&1 >>/tmp/watcher.log &

这样应该就差不多了,我还得继续研究下这蛋疼的配置

Senraの小窝原创文章,转载请注明来自:自建DNS系列——gdnsd (支持状态监控、负载均衡的GeoDNS )

发表评论