简介
BIND(Berkeley Internet Name Domain),是现今互联网上最常使用的DNS软件,使用BIND作为服务器软件的DNS服务器约占所有DNS服务器的九成。BIND现在由互联网系统协会(Internet Systems Consortium)负责开发与维护。
主从的作用:
1、共同解析域名——如master与slave任何一端dns服务断掉,也可以通过从另外一端来解析域名。
2、自动更新——如果master修改完成信息后,slave也会自动更新。
系统及部署环境
获取操作系统命令
- uname -sr
- cat /etc/redhat-release
获取bind版本命令
- named -v
主机 | 主备 | 操作系统 | bind版本 |
---|---|---|---|
fnc05 10.154.5.163 | 主机master | CentOS Linux release 7.9.2009 (Core) / Linux 3.10.0-1160.11.1.el7.x86_64 | BIND 9.16.17 (Stable Release) |
fnc04 10.154.5.162 | 从机slave | CentOS Linux release 7.8.2003 (Core) / Linux 3.10.0-1127.18.2.el7.x86_64 | BIND 9.16.16 (Stable Release) |
fnc03 10.154.5.214 | 从机slave | BigCloud Enterprise Linux For LDK release 7.6.1906 (Core) / Linux 4.19.25-200.1.el7.bclinux.x86_64 | BIND 9.16.17 (Stable Release) |
上述主备机仍需注意如下配置:
确保防火墙的规则不会拦截Bind的监听端口,默认为53。
- systemctl status firewalld
1
2
3
4
5
6
7
8
9
10
11
12
13getenforce
- cat /etc/selinux/config
- SELINUX=disabled
- SELINUX=enforcing
- 需要重启机器
或者
setenforce 0
0 :转成 permissive 宽容模式;
1 :转成 Enforcing 强制模式
不需要重启机器
确保主从服务器的时钟一致。
date
1
2
3
4
5yum install -y ntpdate
ntpdate time.nist.gov
hwclock -w
date
hwclock
确保named用户拥有操作相关目录的权限(默认安装后就有了)
曾尝试9.11版本的主机,与9.16版本的从机,也能和谐运行。
bind部署架构
主从架构:
- 每个机器,无论主从,都部署独立的bind服务。
- 主机可读写,能够进行zone文件的维护管理(增删改)。
- 从机只读,从主机同步读取zone数据后,只可提供查询服务。
- 从机其实是从主机同步的是.zone文件,但具体是哪些.zone文件呢?这由named.conf中所配置的zone参数决定,每个需要同步的zone文件都会在named.conf中配置如下参数:
1 | zone "abc.com" IN { |
因此主机每对zone进行增删时,都要维护slave备机的named.conf文件。详见Catalog zones章节,可采用手段自动维护。
rndc主从分布
rndc(Remote Name Domain Controllerr)是一个远程管理bind的工具,通过这个工具可以在本地或者远程了解当前服务器的运行状况,也可以对服务器进行关闭、重载、刷新缓存、增加删除zone等操作。
rndc面对bind服务的主从配置,只有一个原则,即rndc的独立与否与bind主从没有必然联系。是故,可以做任意选择:
- 第一种:两类机器都有自己独立的rndc配置。相互之间没有什么关系。各自的rndc控制自己的dns bind服务。
- 第二种:主机拥有rndc,从机只作为主机的客户端,远程控制主机的rndc。适用于从机不需要rndc更新任何dns数据,只需要主机rndc的情况。
但是,从机为了能够独立的管理从机(对自己重启之类的),建议采用第一种各自的rndc控制自己的dns bind服务。
本文涉及到的常用命令:
- rndc reload:重新装入配置文件 + 全部zone。如修改了named.conf
- rndc reconfig:仅重新装入配置文件 + 新zone。如修改了named.conf,或在named.conf新增加了一个叫test.com 的zone,就用rndc reconfig来让更改生效。
- rndc reload zone:重新装入指定某个zone。如仅修改了具体的某个zone文件,在test.com里面增加一个www.test.com的a记录,所以用rndc reload test.com来更新。
比如,修改了named.conf
文件中的also-notify { 10.154.5.162; 10.154.5.214; };
,因为仅修改了配置文件,没有涉及到zone。采用rndc reload和rndc reconfig均可。
rndc status: 显示bind服务器的工作状态
rndc sync zone:zone文件修改后,一般改动的信息被储存在*.jnl文件(二进制文件不宜修改)中。一般情况下在15分钟内,Bind会将jnl文件转储到区域文件中。此时添加进入的DNS记录是能够正常提供服务的。但如果想要需要实时更新到区域文件中,需要使用rndc sync且需要注意区域文件的文件权限。
参考
自动同步zone配置
背景
在主机master定义了一个zone,然后必须到所有备机slave都新增相应zone的配置,才能实现主从同步。因此,主备配置的核心在于,如何维护备机的zone配置列表(maintaining slave zone lists)。
如,主机的named.conf文件中增加了zone的配置
1 | zone "abc.com" IN { |
则,从机也需要在named.conf文件中增加zone的配置
1 | zone "abc.com" IN { |
目前,已知向从机named.conf文件中增加zone配置的方案,总共可以归结为3类:
- 传统方式,手动配置。不适合rndc动态添加的zone。
- 用户编写脚本(linux监听变动脚本或者python脚本),实现自动维护从机的zone配置。
- catalog zone目录区域,主从一次性配置,后续自动同步zone。
本文详细介绍catalog zone目录区域的配置。
方案-传统手动方式
主机
1 | 主机手动添加到named.rfc1912.zones(最终include到named.conf): |
从机
1 | 从机手动添加到named.rfc1912.zones(最终include到named.conf): |
方案-用户编写脚本
Left to the user to create a script or process for maintaining slave zone lists
用户编写脚本运行示意图:
bind官网9.11的升级文档指出,用户脚本较为麻烦:
参考
- Jan-Piet Mens :: Automatic provisioning of slave DNS servers (jpmens.net)
- Automatically sync all zones between BIND 9 - Server Fault
方案-Catalog zone【重点】
简介
Catalog zone本质上还是master上的一个zone文件,但具有一些特点:
- 特殊的格式。in a special new format
- 内容是一系列的待同步zones列表,称为“成员区域”。(”member zones”.)。contains a list of zones (the CatZ)
用途:Catalog zone(目录区域)是一项新的 BIND 功能(BIND 9.11 (2018) ),无论多少从机,都可以轻松地将zone配置到从机。
当Catalog zone加载或传输到支持此功能的从机时,从机会自动创建member zones。
更新Catalog zone时(例如,添加、删除member zones,或更改其配置参数),这些更改会立即生效。
因为Catalog zone是一个普通的 DNS 区域,所以可以使用标准的 AXFR/IXFR 区域传输机制来传播这些配置更改。
Catalog zone使用条件:
- 要求主、从服务器都采用 BIND。
- 要求BIND 9.11+版本。
实践配置简介
Catalog zone配置过程如下:
- 主机,创建一个Catalog zone(catZ)文件。这个文件用来维护需要同步的zones列表。
- 主机,named.conf中配置catZ。
- 从机,named.conf中配置catZ。
- 一旦catZ建立,从机自动获取主机的zone Catalog,自动获取zone Catalog中的zones列表变化,从而实现同步。
- zone Catalog可以有多个!
主从配置
作用:完成catalog目录的配置。
主机
- 打开目录
/var/opt/isc/isc-bind/named/data
,新建catalog目录文件(后缀名可以为.db或者.zone)
1 | catalog.default.zone |
1 | 修改权限 |
- 将catalog目录文件引入到named.conf中
1 | options { |
从机
named.conf配置catalog目录,与主机建立关联。
1 | options { |
验证
至此完成catalog目录的配置。
1 | 主机、从机都重启 |
主从机同步演示
后续只需要在主机上对zone进行操作(增删改等),从机会自动实现同步了。如下示例:
新增zone
- 按传统方式,在主机通过rndc动态添加一个zone。
1 | vim luxia.com.zone |
验证
1 | dig +short soa luxia.com @10.154.5.163 // 主机可以dig |
- 而后,利用
nsupdate
命令将luxia.com加到catalog zone,从而实现把luxia.com自动同步到从机。
1 | cat << __EOF | nsupdate |
验证一下
1 | dig +short soa luxia.com @10.154.5.162 // 发现从机可以dig |
且从机出现如下文件:
1 | __catz___default_catalog.example_luxia.com.db |
其中,产出SHA1 的方式有两种:
第一种是shell命令行:
1 | printf '\7luxia\3com\0' | openssl sha1 |
第二种是python脚本catz-add.py
1 | #使用 |
1 | #!/usr/bin/env python |
最后,上述主机操作过程,可以总结为如下python语句自动执行:
调用
1 | python ./catz-add.py luxia.com |
书写catz-add.py文件,使用了isc.rndc
和 dnspython
两个核心模块:
1 | #!/usr/bin/python |
删除zone
与新增类似,仍然借助nsupdate,先把catalog目录列表中的域名删除。
1 | cat << __EOF | nsupdate |
再rndc方式动态删除域名。
1 | rndc delzone luxia.com |
验证发现,发现从机的__catz___default_catalog.example_luxia.com.db
文件消失,且dig不通。
更改serial,实现记录更新同步
上述新增zone和删除zone的过程演示了对zone配置的自动维护(主机zone配置同步到了从机zone配置)。当有zone有更新时,可以自动同步了!
现在我们仍然借助nsupdate进行更新zone记录演示。
1 | cat << __EOF | nsupdate |
而后
1 | rndc sync luxia.com // 写入磁盘文件,可以cat luxia.com.zone看到修改 |
验证,发现已经修改。
1 | cat luxia.com.zone |
参考
notify
主从同步消息机制
- 主机修改后重启服务,会主动传送notify。
- 如果从机没有收到notify,则Refresh。
- 如果从机Refresh 不成功,则Retry。
- 如果从机Retry 一直不成功, 则Expire。
- 如果Expire也不成功,则选择放弃zone transfer。
一个zone文件示例:
1 | TTL 1D #缓存时间 |
notify主动发送消息的全过程
- 主机主动发送变更通知。
- 从机接收到通知,去查询主机zone文件的SOA记录。
- 主机告知从机SOA记录。
- 从机将主机拿到的SOA记录与自己本来就同步过的SOA记录进行对比,比较SOA中的serial no是否递增更新。
- 如果递增更新,从机向主机发起zone transfer请求,要求zone文件传输。
- 主机传输zone数据给从机更新。
从图中可看到,涉及到的配置如下:
notify yes;
# 【开启主动通知】also-notify { 10.154.5.162; };
# 【被通知的从机ip】allow-notify { 10.154.5.163; }
#从机是否接收来着该主机ip的通知,因为默认接收主机ip,所以省略了。allow-transfer { 10.154.5.162; 10.154.5.163; };
#【允许zone传输的机器列表】设定允许哪台主机和本地服务器进行zone传输。
下面一一介绍上述配置参数。
notify与 also-notify
作用于主机。notify 结合 also-notify通过三种配置方式实现不同范围的通知:
notify yes;
- sends notify to all name servers in RR (except itself and SOA master)
- notifies are sent to all servers appearing in the NS RRset (except the server identified in the MNAME field of the SOA record)
- will send notifications to all of the published NS records for the domain。
- The messages are sent to the servers listed in the zone’s name server records。
- besides those in your zone’s NS records docstore.mik.ua/orelly/networking_2ndEd/dns/ch10_03.htm
- 使用notify指令會自動通知所有這個域的所有在ns記錄上的機器,also-notify指令可以用來通知所有不在ns記錄上的dns伺服器。
還是好好看文件吧,裡面還有很多有趣的功能呢。 - 默认值。默认情况下,master 不必明确配置 slave ips,会自动向zone的每个 NS 记录发送NOTIFY。
notify yes; also-notify { x.x.x.x; y.y.y.y; };
- sends notify to x.x.x.x, y.y.y.y and all name servers in RR (except itself and SOA master).
notify explicit; also-notify { x.x.x.x; y.y.y.y; };
- sends notify to just x.x.x.x, y.y.y.y => 仅向also-notify列出的ips发送通知
NS记录
其中,NS记录是指zone文件中指定的ns解析记录(不包括SOA主机名部分,如下不包括ns1.test.com部分),如下示例中包括ns1和ns2部分。如果想要包括soa部分,可以设置为notify-to-soa yes
。
1 | TTL 1D #缓存时间 |
但存在问题:
新建域名时候,域名无法同步到从机(因为这个zone的NS记录还没有定)。
此时对域名进行ns记录操作,主机会派发notify消息,但从机则报错如下:
1 | received notify for zone 'wei01.com': not authoritative |
分析原因,可能因为这个zone在从机没有(因为NS地址还不知道,域名没有同步到从机),虽然接收到了更新消息但是没法更新zone.
目前尚未找到解决办法,只能仍然采用also-notify固定从机ip地址的方式。
注意修改,also-notify { 10.154.5.162; 10.154.5.214; }; 增改ip列表之后,采用rndc reload 或者 rndc reconfig重启服务即可。
尝试失败1:
创建域名时生成既定 NS记录 ns1.example.com,
且主机配置ns1.example.com 的hosts。
发现主机根本不会发送任何notify,从机也不会接收任何notify。
也就是在zone的NS记录已经定下来,且ns记录可通过hosts解析的情况下,域名仍然没有同步到从机。
1 | qing.com.zone |
1 | vim /etc/hosts |
1 | grep qing.com notify.log #啥也没有 |
尝试失败2:
也就是在zone的NS记录已经定下来,且ns记录配置了A地址的情况下,域名仍然没有同步到从机。
1 | qing.com.zone |
1 | example.com.zone |
1 | grep qing.com notify.log #啥也没有 |
also-notify【目前采用】
also-notify
,可设置扩展的名字服务器IP列表,无论何时只要有更新的内容加载,都会向这个表中的IP发出NOTIFY消息。有助于zone同步到隐藏的备机服务器。also-notify 在 bind 9.9.0+ 也可支持密钥形式。
1 | also-notify [port gp-num] [dscp gd-num] { (masters-list|IP-address )[port p-num] [dscp d-num] |
1 | key trusted-key { |
参考:Understanding views in BIND 9 (isc.org)
allow-notify
作用于从机。
- 默认接收来自主机的notify消息
- 也可以手动配置来确定从机接受哪些ip地址的notify
allow-transfer
简介
allow-transfer 设定哪台主机允许和本地服务器进行域传输,可以设置在 zone 语句或catalog中。有两种使用方式:
通过主机IP来限制访问—— allow-transfer : {address_list | none}。这种方式需要写死从机ip地址。不方便从机扩缩。
通过事务签名:只允许带有密钥认证的DNS服务器同步数据配置文件。这种方式不需要从机ip地址,方便从机扩缩。
其中,对于事务签名:
- 通过密钥对数据加密。如,TSIG利用密码编码来保护区域信息的传输(Zone Transfer)
- 可分为两类:
- TSIG:对称方式(常用)。
- SIGO:非对称方式。
最终,如果要实现从机的热插拔,应采用TSIG事务签名的方式,设置允许带有密钥认证的DNS服务器同步数据配置文件。
操作过程以及主从机分别负责的工作:
主备 | 负责工作 |
---|---|
主机 | 生成DNS服务密钥(公钥+私钥),复制生成私钥文件中的key值,到一个新建文件如tansfer.key中 |
主机 | named.conf中include引入tansfer.key文件,设置allow-transfer { key 私钥key名; }; |
主机 | 重启named服务。 |
– | 至此发现从机不能同步数据 |
从机 | 复制主机的tansfer.key到从机 |
从机 | named.conf中include引入tansfer.key文件,设置 server 主机ip地址 { keys {私钥key名; }; |
– | 至此发现从机可以同步数据 |
主机生成密钥
dnssec-keygen命令用于生成安全的DNS服务密钥,其格式为“dnssec-keygen [参数]”
- -a : 加密算法,包括RSAMD5(RSA)、RSASHA1、DSA、NSEC3RSASHA1、NSEC3DSA等
- -b : 密钥长度,HMAC-MD5的密钥长度在1~512位之间
- -n : 密钥类型,可以选择ZONE或者HOST,HOST表示与主机相关
- dnssec-transfer:密钥名称自定义
1 | 生成一个主机名称为dnssec-transfer的128位HMAC-MD5算法的密钥文件(公钥+私钥) |
将私钥key放到一个新的文件中,并将这个文件引入到named.conf中
1 | cd /etc/opt/isc/isc-bind/ 或 cd /etc/ #密钥验证文件在/etc目录(与named.conf同一个目录下) |
1 | systemctl restart named |
从机引用密钥
1 | scp /etc/transfer.key root@从机ip地址:/etc/opt/isc/isc-bind/transfer.key |
named.conf文件:
1 | include "/etc/opt/isc/isc-bind/transfer.key"; |
重启从服务器的Bind服务
1 | systemctl restart isc-bind-named |
发现已经同步过来了。
参考
- 5. Advanced DNS Features — BIND 9 documentation
- BIND9 named.conf Zone Transfer and Update statements (zytrax.com)
bind9.16安装配置
9.16安装
不同版本centos系统的yum源包含了不同版本的bind,各版本略有差异。
1 | 安装yum自带bind版本,直接执行命令即可 |
但如果想要忽略centos版本,直接安装最新的bind,需要做如下操作:
1 | cd /etc/yum.repos.d/ |
安装过程可能确实某些安装包,可以自行安装:
1 | wget http://mirror.centos.org/centos/7/os/x86_64/Packages/scl-utils-20130529-19.el7.x86_64.rpm |
安装包下载网站
- Iso-codes Download (APK, DEB, EOPKG, RPM, TGZ, TXZ, XZ, ZST) (pkgs.org)
- scl-utils-20130529-19.el7.x86_64.rpm CentOS 7 Download (pkgs.org)
- RPM resource telnet (rpmfind.net)
9.16配置
1 | 在物理机/etc/profile.d/⽬录下创建isc-bind-named.sh⽂件。并输⼊以下内容,保存。 |
主机
1 | secret和algorithm等,配置到python程序中 |
1 | named-checkconf 验证配置 |
注意controls配置:
1 | 监听网卡(inet) |
从机
1 | key "rndc-key" { |
从机配置同步数据所在目录slaves
1 | cd /var/opt/isc/isc-bind/named/data |
参考
- ftp方式(源码安装)下载地址:BIND-9.16.16 (linuxfromscratch.org)
日志
简介
BIND默认把日志写到/var/log/messages
。如果需要更详细的日志,需要自行配置named.conf的logging模块。
参数及说明
在日志配置中主要有channel(通道)、category(类别)二种定义:
- channel,通道指定了应该向哪里发送日志数据——是发送给syslog,还是写在一个文件里,或是发送给named的标准错误输出,还是发送到位存储桶(bit bucket)。
- severity,系统会记录包括该级别以及比该级别更严重的级别的所有消息。比如定义级别为error,则会记录critical和error 两个级别的信息。一般情况下,我们记录到info级别就可以了
- print-time是设定在日志中是否需要写入【时间】
- print-severity是设定在日志中是否需要写入【消息级别】
- print-category是设定在日志中是否需要写入【日志类别】。
- category,类别规定了哪些数据需要记录
- default :【所有categories的默认目标】default类别匹配所有未明确指定通道的类别,但是不匹配不属于任何类别的消息。这些不属于任何类别的消息属于下面列出的这些类别。
- general 包括所有未明确分类的BIND消息。
- client 处理客户端请求。
- config 配置文件分析和处理。
- database 同BIND内部数据库相关的消息,用来存储区数据和缓存记录。
- dnssec 处理DNSSEC签名的响应。
- lame-servers 发现错误授权。
- network 网络操作
- notify 异步区变动通知。
- queries 查询日志
- resolver 名字解析,包括对来自解析器的递归查询的处理。
- security 认可/非认可的请求。
- update 动态更新事件。
- xfer-in 从远程名字服务器到本地名字服务器的区传送。
- xfer-out 从本地名字服务器到远程名字服务器的区传送。
1 | named.conf |
1 | named.conf |
一个常用参考
1 | logging { |
上述参考中把日志按照category类别进行了详细的分类,分不到/var/opt/isc/isc-bind/log/目录下不同的日志文件中。可采用如下脚本进行生成:
1 | vim namelist.txt |
bash createlog.sh
1 | !/bin/bash |
参考
- BIND Logging - some basic recommendations (isc.org)
- DNS BIND9 logging Clause (zytrax.com)
- How to enable named/bind/DNS full logging? - Stack Overflow
keepalived
DNS BIND主从结构虽然能够实现DNS的主备,但是无法使用统一的IP对外服务。
因此,引入LVS进行负载均衡,多台DNS服务器都配置统一的VIP作为业务IP,统一对外服务。
使用VIP可以让用户不知道实际DNS的情况下进行解析,同时DNS服务器可以增加到2台以上做一个更大的群组,提高可靠性。
问题1:vip转移抢占与非抢占
1 | 抢占:通常如果master服务死掉后backup会变成master,但是当master服务又好了的时候,master此时会抢占VIP(因为master优先级高,会抢回来) |
state | nopreempt | priority | |
---|---|---|---|
主机 | backup | 设置 | 100 |
从机 | backup | 不设置 | 95 |
修改M,B服务器的 state BACKUP 都为【备】类型,同时设置 nopreempt 设置为不抢夺VIP,然后先启动M服务器,M服务器会成为【主】。然后启动B服务器,由于M的优先级高【priority 100】 所以B不会抢夺VIP,这时M宕机,B成为【主】,接着M恢复正常,由于设置了nopreempt 所以M不会抢夺VIP,B继续为【主】而M为【备】。
此时即使B又故障了,M也不会抢夺回来。
问题1:
1 | protocol TCP |
结论:同时使用。
只用UDP的,大部分中文博客
Lvs+Keepalived+Bind+web构建高可用负载均衡系统 - Fatt - 博客园 (cnblogs.com)
1 | 如果UDP,则只能使用rr算法 |
MISC_CHECK主要根据检查脚本返回值来判断。
1) 当脚本返回值为0,表示真实服务器正常。
2) 当脚本返回值为1,表示真实服务器故障。
3) 当脚本返回值为2-255,表示当故障时将真实服务器权重改为返回值减2。
注意当脚本返回值为2-255时需添加misc_dynamic属性才生效。
只用TCP的
增加了notify_down和notify_up对lvs进行手动检测
Load balancing DNS with keepalived | Bill Boebel (bb.co)
1 | virtual_server 192.168.254.100 80 { |
同时都用的
lvs-dns - keepalived - linux [Knowledge Base] (xbits.net)
DNS服务器LVS方式负载均衡部署与测试 - 百度文库 (baidu.com)
1 | virtual_server 192.168.130.111 53 { |
基础概念:
- 负载均衡:多台服务器同时、分摊工作。nginx。
- 高可用:主机一力承担工作。当主机故障时,从机接替工作。keepalived。
两个方案的选择:
- 仅高可用:自建DNS常用在公司内部平台之间的调用,所以负载均衡的意义并不是太大,高可用有必要。
- keepalived (keepalived 的高可用是通过
VRRP(virtual route redundancy protocol)
实现的)
- keepalived (keepalived 的高可用是通过
- 负载均衡+高可用:
- keepalived + (LVS 、HAProxy 、Nginx等负载均衡方案)
Protocol transport(维基百科Domain Name System - Wikipedia):
DNS primarily uses the User Datagram Protocol (UDP) on port number 53 to serve requests.
DNS queries consist of a single UDP request from the client followed by a single UDP reply from the server.
The Transmission Control Protocol (TCP) is used when the response data size exceeds 512 bytes, or for tasks such as zone transfers. Some resolver implementations use TCP for all queries.
DNS 通常在 UDP 端口 53 和 TCP 端口 53 上侦听查询。
DNS占用53号端口,同时使用TCP和UDP协议,关键区分在于数据包大小,如果数据包小到一定程度,UDP 协议绝对最佳的选择,但是当数据包逐渐增大直到突破 512 字节以及 MTU 1500 字节的限制时,我们也只能选择使用更可靠的 TCP 协议来传输 DNS 查询和相应。
- TCP:DNS在区域传输的时候使用TCP协议
- 因为数据传输传送的数据量比一个请求应答的数据量要多得多
- TCP是一种可靠连接,保证了数据的准确性——DNS 查询由于 DNSSEC 和 IPv6 的引入迅速膨胀,需要依靠更加可靠的 TCP 协议完成数据的传输
- 随着 DNS 查询中包含的数据不断增加,TCP 协议头以及三次握手带来的额外开销比例逐渐降低,不再是占据总传输数据大小的主要部分
- UDP:非区域传输时都使用UDP协议
- DNS 查询的数据包较小、机制简单——客户端向DNS服务器查询域名(域名解析),一般返回的内容都不超过512字节,用UDP传输即可。
- UDP 协议的额外开销小、有着更好的性能表现——UDP不用经过三次握手,这样DNS服务器负载更低,响应更快。理论上说,客户端也可以指定向DNS服务器查询时用TCP,但事实上,很多DNS服务器进行配置的时候,仅支持UDP查询包。
LVS 可以简单地在一组 DNS 服务器之间对 UDP 端口 53 和 TCP 端口 53 进行负载均衡,而无需设置任何持久性选项。
Keepalived 本质上是 LVS的包装器, LVS 支持 TCP 和 UDP 流量的负载平衡。 (keepalived 还包括 VRRP 和 Healthchecks,但这是题外话)幸运的是,除了 UDP 之外,DNS 服务器碰巧还侦听 TCP 连接。他们这样做是为了处理大于 512 字节的旧 RFC 限制的查询。
配置 keepalived 以负载平衡 TCP 端口 53,就像您对任何其他 TCP 端口(例如 http 或 smtp)进行负载平衡一样。然后使用keepalived的notify_up/notify_down脚本调用功能手动配置LVS,对对应的UDP端口进行负载均衡。
keepalived 高可用示意图(Keepalived 作为 LVS 的有效补充可以构建一个高可用的 LB 前端):
2台服务器做LVS+keepalived。其中,
- master和一台real_server在一台服务器
- backup和一台real_server在一台机器上
按理来说,keepalive+lvs应该部署在独立的机器上。
节点类型 | 主机名 | IP地址 | 网络类型 | bind主从 |
---|---|---|---|---|
realserver | fnc03 | 10.154.5.214 | 从 | |
realserver | fnc04 | 10.154.5.162 | 从 | |
VIP | ||||
keepalive+lvs MASTER,VIP占用 | fnc04 | 10.154.5.162 | ||
keepalive+lvs BACKUP | fnc03 | 10.154.5.214 | ||
fnc05 | 10.154.5.163 | 主机 |
LVS+keepalived访问网页特别慢,求解。 - 集群和高可用-Chinaunix
实现过程:
- 当 Master 与 Slave 均运作正常时, Master负责服务,Slave负责Standby;
- 当 Master 挂掉,Slave 正常时, Slave接管服务;
- 当 Master 恢复正常,恢复Master身份
- 然后依次循环。需要注意的是修改数据只能在Master修改。
安装
在线安装
1 | 下载 |
如果下载失败,且是yum源的问题,如下可以更改yum源为aliyun。
如果只是临时使用aliyun,记得还原。
1 | 安装base reop源 |
离线安装
前提依赖
1 | !/bin/bash |
1 | chmod 777 wget_pkg.sh |
1 | 获取源码 |
参考
- keeplived离线安装openssl-devel依赖包_afreon-CSDN博客
- Welcome to the BCLinux Open Source Mirror. /bclinux/dcos/ldk/v7.6/os/x86_64/Packages/
常用命令
1 | 1. systemctl start keepalived.service #启动服务 |
配置
cd /etc/keepalived/
主机
vrrp_script 一定要放在vrrp_instance之前
1 | ! Configuration File for keepalived |
1 | misc_path "/usr/bin/dig catalog.default soa @10.154.5.162 +time=1 +tries=3 +fail >/dev/null" |
- +time=T :为查询设置超时时间为 T 秒。缺省是 5 秒。如果将 T 设置为小于 1 的数,则以 1 秒作为查询超时时间。
- +tries=A :设置向服务器发送 UDP 查询请求的重试次数为 A,代替缺省的 3 次。如果把 A 小于或等于 0,则采用 1 为重试次数。
- +fail:如果您收到 SERVFAIL,请不要尝试下一个服务器。默认是不尝试下一个服务器。
查看bind服务是否有问题,如果有则设置为vip漂移。
(此处无法用grep 端口号或者named,因为很多干扰字符串)
1 | vim /etc/keepalived/chk_dns.sh |
1 | chmod +x /etc/keepalived/chk_dns.sh |
测试vip漂移
1 | rndc stop |
另外,如果MISC_CHECK监测脚本(当检测UDP ip 53端口成功时,会返回一个”succeeded”字段)
1 | #使用示例 |
1 | udp_check53.sh |
1 | chmod +x /etc/keepalived/udp_chekc53.sh |
53端口,tcp和udp的策略要开启。
1 | iptables -I INPUT 4 -p tcp--dport 53 -j ACCEPT |
查看调度规则
1 | ipvsadm |
停掉和启用一台DNS服务,观察调度器
1 | systemctl stop isc-bind-named |
DNS+keepalived+lvs实现高可用负载均衡集群_6638225的技术博客_51CTO博客
1 | ! Configuration File for keepalived |
1 | 检测bind53端口是否可用,从而来证明服务可用性 |
给5个脚本都加上可执行权限:
1 | chmod +x /etc/keepalived/scripts/*.sh |
启动keepalived
1 | systemctl restart keepalived |
验证
1 | netstat -ntpl |grep 53 |
模拟master挂掉(关闭master服务),查看vip的漂移情况。
1 | ip addr show eth0 |
主从机器的named.conf都需要增加VIP,确保主从named.conf配置文件中的监听网卡和端口覆盖了本机IP和VIP。
1 | listen-on port 53 { 127.0.0.1; 10.154.5.163; VIP; }; #增加VIP |
备机
与主机基本一致,除了以下参数
1 | state BACKUP |
####
1 | ! Configuration File for keepalived |
tcpdump
1 | tcpdump udp port 53 |
tcpdump抓包命令详解 - 知乎 (zhihu.com)
ipvsadm
CentOS 7已经包含LVS内核,只要安装LVS控制器ipvsadm.
ipvsadm可以查看lvs规则是否建立
1 | -L|-l(–list):显示内核虚拟服务器表 |
1 | Forward 转发方式,当前是路由转发 |
1 | wget http://mirror.centos.org/centos/7/os/x86_64/Packages/ipvsadm-1.27-8.el7.x86_64.rpm |
1 | 查看调度情况 |
1 | ipvsadm |
查看VIP是否已经成功映射到两台real服务器
1 | ipvsadm -L -n |
ipvsadm默认超时时间
1 | ipvsadm -L --timeout |
900 120 300这三个数值分别是TCP TCPFIN UDP的时间.也就是说一条tcp的连接经过lvs后,lvs会把这台记录保存15分钟,就是因为这个时间过长,所以很多人都会发现做好LVS DR之后轮询现象并没有发生,实践中将此数值调整很小小,使用以下命令调整:
1 | ipvsadm --set 1 2 1 |
Clear the LVS settings first because it is controled by Keepalived.
1 | ipvsadm -C |
telnet
查看是否安装
1 | rpm -qa | grep xinetd |
1 | wget http://mirror.centos.org/centos/7/os/x86_64/Packages/xinetd-2.3.15-14.el7.x86_64.rpm |
telnet-server服务启动依赖xinetd服务,需要首先安装,如果telnet-server服务在xinetd之前安装了,要先删除telnet-server,再安装xinetd。
安装顺序:xinetd–>telnet–>telnet-server。
1 | rpm -ivh xinetd-2.3.15-14.el7.x86_64.rpm |
再次查看发现已经安装了。
1 | 安装完成后,将xinetd服务加入开机自启动: |
测试vip
1 | telnet 10.154.5.2 53 |
用户程序
用户访问时,访问的是VIP
1 |
参考
- BIND + LVS + Keepalived 搭建内网DNS集群-分区域响应结果,可做智能解析 | 码农家园 (codenong.com)
- keepalived 仅高可用 Centos下高可用主从同步DNS服务部署_亮公子的技术博客_51CTO博客
- keepalived 仅高可用 How to Setup IP Failover with KeepAlived on Ubuntu & Debian - TecAdmin
- LVS + keepalived Ubuntu 16.04 LTS : LVS + Keepalived : Server World (server-world.info)
- LVS+Keepalived Build DNS HA LB Cluser (more higher HA) (atomicgain.com)
- DNS + LVS Building Scalable DNS Cluster using LVS - LVSKB (linuxvirtualserver.org)
- keepalived+lvs+负载均衡的windows实现_夏的博客-CSDN博客
- DNS系列之bind篇01-Bind+Keepalived安装高可用DNS集群 - TinyChen’s Studio
- How ClusterControl Configures Virtual IP and What to Expect During Failover | Severalnines
- How To Set Up Highly Available HAProxy Servers with Keepalived and Floating IPs on Ubuntu 14.04 | DigitalOcean
- ck :: Unbound DNS server behind a VIP - solving reply from unexpected source (claudiokuenzler.com)
性能监控
Bind基本配置
用于获取监控数据
vim /etc/opt/isc/isc-bind/named.conf
1 | statistics-channels { |
打开浏览器访问10.154.5.162:8889
注意端口号8889
bind_exporter
用于图形化展现。
bind_exporter基于statistics-channels记录的统计数据,并对数据统计分析并输出到Prometheus
下载
查看linux版本
1 | # cat /proc/version |
根据版本下载
https://github.com/prometheus-community/bind_exporter/releases
如上图,linux是86_64,则下载版本
bind_exporter-0.4.0.linux-amd64.tar.gz
配置
解压到/usr/local/bin/
1 |
|
创建⼀个systemd配置⽂件以运⾏bind_exporter
- –web.listen-address为对外暴露的metric地址和端⼝,Prometheus从此处抓取bind_exporter的metrics;即对外提供数据的端口。
- – bind.stats-url为本地bind服务绑定的地址和IP。即获取bind数据的地址。
注意此处的⽤⼾和组可以使⽤与named程序相同的⽤⼾和组“named”,也可 以使⽤root。
1 | vim /etc/systemd/system/bind_exporter.service |
注意端口号9154
加载并启动bind_export
1 | systemctl daemon-reload |
Prometheus Server
Prometheus基于Go编写,编译后的软件包,不依赖于任何的第三⽅依赖。只需要下载对应平台的⼆进制包,解压并且添加基本 的配置即可正常启Prometheus Server。
Prometheus Server负责定时在目标上抓取Metrics数据,每个抓取目标都需要暴露一个HTTP服务接口用于Prometheus定时抓取。
这种调用被监控对象获取监控数据的方式被称为Pull。Pull方式体现了Prometheus独特的设计哲学与大多数采用了Push方式的监控系统不同。
但某些现有系统是通过push方式实现的,为了接入这个系统,Prometheus提供对PushGateway的支持,这些系统主动推送metrics到PushGateway,而Prometheus只是定时去Gateway上抓取数据。
AlertManager是独立于Prometheus的一个组件,在触发了预先设置在Prometheus中的高级规则后,Prometheus便会推送告警信息到AlertManager。
根据版本下载:
1 | tar -xf prometheus-2.27.1.linux-amd64.tar.gz |
创建Prometheus的⽤⼾(此处用户prometheus)及数据存储⽬录(/data/prometheus)
1 | # useradd -s /sbin/nologin -M prometheus |
配置/usr/local/prometheus/promethes.yml
1 | cp prometheus.yml prometheus.yml-default #备份一下默认配置 |
1 | my global config |
默认启动后的端口为9090。
启动方式1
1 | cd /usr/local/prometheus |
启动方式2
1 | vim /etc/systemd/system/prometheus.service |
如此可以用命令启动服务
1 | systemctl daemon-reload |
浏览器访问http://10.154.5.162:9090/targets
Grafana
一个数据分析统计可视化报表,⽤来展⽰ prometheus收集到的数据
Grafana+Prometheus的详解以及使用 - 知乎 (zhihu.com)
下载
1 | wget https://dl.grafana.com/oss/release/grafana-7.5.7.linux-amd64.tar.gz |
1 | tar -xzvf grafana-7.5.7.linux-amd64.tar.gz |
创建grafana⽤⼾及数据存放⽬录
1 | useradd -s /sbin/nologin -M grafana |
修改目录
1 | cd /usr/local/grafana/conf/ |
新增 grafana-server.service ⽂件,使⽤systemd来管理grafana服务
1 | vim /etc/systemd/system/grafana-server.service |
1 | systemctl start grafana-server |
打开浏览器访问
http://10.154.5.162:3000/login
默认的账号密码 admin/admin
把grafana和prometheus关联起来,也就是在 grafana中添加添加数据源——
在配置⻚⾯点击添加数据源,然后选择prometheus,输⼊prometheus服务的参数即可。
Grafana三种方式导入Dashboard
参考:
Node Exporter
https://prometheus.io/download/
采集主机的运⾏指标如CPU,内存,磁盘等信息。可以使⽤Node Exporter
1 | wget https://github.com/prometheus/node_exporter/releases/download/v1.1.2/node_exporter-1.1.2.linux-amd64.tar.gz |
1 | ln -s node_exporter-1.1.2.linux-amd64/ node_exporter |
开机启动
1 | nohup /usr/local/prometheus_exporter/node_exporter/node_exporter >/dev/null 2>&1 & |
加入prometheus
编辑prometheus.yml⽂件,增加后⾯4⾏.
1 | scrape_configs: |
重启
1 | systemctl restart prometheus.service |
存疑
dns bind Catalog zone notify yes 无法主动同步新建域名的zone(主机没有主动发送新建zone的消息,导致zone更新解析记录等时虽然发消息但从机同步失败)
其他概念
IXFR与AXFR
- 增量区传送(Incremental Zone Transfer,IXFR):
- zone很大的话,zone传送需要一定的时间,IXFR是为了解决这个问题,它允许辅名字服务器告诉主名字服务器当前使用的区的版本,并仅仅请求传送它使用的版本和当前版本之间改动过的部分。这样就大大减少了区传送的大小和所需的时间。
- 但是存在的问题比较多,如果最大限度的利用IXFR,最好动态更新修改区而不是手工编辑区数据文件。
- 通过IXFR区域传输时,区域的复制版本和源区域之间的差异必须首先确定。如果该区域复制源DNS服务器的序号与申请同步复制的DNS服务器该区域的序列号所指示的版本相同,则不进行任何传送;如果复制源DNS服务器的序列号比申请同步复制的DNS服务器对应区域的序列号大,则传送的内容仅由区域中每个递增版本的资源记录的改动组成。
- 全量区传送(Full Zone Transfer,AXFR):默认,完全区域传输查询来完全传送整个区域数据。
PowerDNS
notify-to-soa
Normally a NOTIFY message is not sent to the SOA MNAME (SOA ORIGIN) as it is supposed to contain the name of the ultimate master.
1 | cat /etc/named.conf |
view
mastert利用view进行分界,针对不同查询来源IP,返回不同DNS答案。
主从机介绍 Chapter 4 DNS Configuration Types (zytrax.com)
- 假设您想将主服务器隐藏,那么至少一个从服务器将位于防火墙或类似配置的公共端,提供外围防御(defence)
- 为了提供弹性(resilience),您需要两个或更多这样的公共slave(第二个slave可以从master获取数据,也可以从另一个slave(称为’boss’ slave)中)
- 这种类型的配置将略微增加更新第二个从站上的区域的延迟 - 但这可能会被增加的隐蔽性抵消。
- 在 DNSSEC 环境中,master 可能会拥有各种与保持密钥安全有关的配置。而 DNSSEC 从站只是简单地发送区域文件中的数据来响应查询,并且没有安全密钥维护的要求。在这种环境中,隐藏的主配置将越来越成为常态。