当前位置: 首页 > news >正文

CentOS 7上搭建高可用BIND9集群指南

在 CentOS 7 上搭建一个高可用的 BIND9 集群通常涉及以下几种关键技术和策略的组合:主从复制 (Master-Slave Replication)、负载均衡 (Load Balancing) 以及可能的浮动 IP (Floating IP) 或 Anycast。

在这里插入图片描述

我们将主要关注主从复制负载均衡的实现,这是构成高可用 DNS 集群的核心。

场景假设:

  • 域名: mycluster.local
  • 主 DNS 服务器 (Master):
    • IP: 192.168.1.10
    • Hostname: dns-master.mycluster.local
  • 从 DNS 服务器 1 (Slave 1):
    • IP: 192.168.1.11
    • Hostname: dns-slave1.mycluster.local
  • 从 DNS 服务器 2 (Slave 2):
    • IP: 192.168.1.12
    • Hostname: dns-slave2.mycluster.local
  • 负载均衡器/虚拟 IP (VIP):
    • IP: 192.168.1.100 (客户端将使用此 IP 作为 DNS 服务器)

核心组件:

  1. BIND9 主从复制:
    • 主服务器 (Master) 维护权威的区域数据文件。
    • 从服务器 (Slaves) 定期从主服务器同步区域数据。
    • 当主服务器上的区域数据更新时,它会通知从服务器进行更新。
  2. 负载均衡器:
    • 将客户端的 DNS 请求分发到后端的多个 BIND 从服务器(或包括主服务器)。
    • 可以使用硬件负载均衡器 (如 F5, Citrix ADC) 或软件负载均衡器 (如 HAProxy, Nginx, LVS)。
    • 对于简单的 DNS 负载均衡,也可以使用 DNS 轮询 (Round Robin DNS),但这不提供故障检测和自动切换。
  3. (可选) Keepalived 实现 VIP 和健康检查:
    • Keepalived 可以管理一个虚拟 IP (VIP),并在主负载均衡器节点故障时将其漂移到备用节点。
    • 它可以对后端 BIND 服务器进行健康检查,如果某个 BIND 服务器故障,则将其从负载均衡池中移除。

步骤一:在所有节点上安装 BIND9

dns-master, dns-slave1, dns-slave2 上执行:

sudo yum update -y
sudo yum install -y bind bind-utils

步骤二:配置主 DNS 服务器 (dns-master)

  1. 编辑 /etc/named.conf (options 部分):

    sudo vi /etc/named.conf
    
    options {listen-on port 53 { 127.0.0.1; 192.168.1.10; }; // 监听自己的IPlisten-on-v6 port 53 { ::1; };directory       "/var/named";dump-file       "/var/named/data/cache_dump.db";statistics-file "/var/named/data/named_stats.txt";memstatistics-file "/var/named/data/named_mem_stats.txt";allow-query     { localhost; 192.168.1.0/24; }; // 允许内网查询recursion no;                                   // 作为权威服务器allow-recursion { none; };// 允许从服务器进行区域传送allow-transfer { 192.168.1.11; 192.168.1.12; };dnssec-enable yes;dnssec-validation yes; // 或 no,如果纯权威且不解析外部pid-file "/run/named/named.pid";// ... 其他默认选项 ...
    };logging {channel default_debug {file "data/named.run";severity dynamic;};
    };include "/etc/named.rfc1912.zones";
    include "/etc/named.root.key";
    
  2. 编辑 /etc/named.rfc1912.zones (定义区域):

    sudo vi /etc/named.rfc1912.zones
    

    在文件末尾添加:

    zone "mycluster.local" IN {type master;file "db.mycluster.local"; // 区域数据文件名allow-update { none; };// 主动通知从服务器有更新also-notify { 192.168.1.11; 192.168.1.12; };
    };// 示例反向区域
    zone "1.168.192.in-addr.arpa" IN {type master;file "db.192.168.1";allow-update { none; };also-notify { 192.168.1.11; 192.168.1.12; };
    };
    
  3. 创建区域文件 (例如 /var/named/db.mycluster.local):

    sudo vi /var/named/db.mycluster.local
    
    $TTL 86400
    @       IN      SOA     dns-master.mycluster.local. admin.mycluster.local. (2023072101      ; Serial (YYYYMMDDNN)3600            ; Refresh1800            ; Retry604800          ; Expire86400 )         ; Minimum TTL
    ; Name Servers for the zone (these will be the VIP or individual server IPs clients might use)
    ; For HA, clients should point to the VIP. These NS records are for delegation.
    @       IN      NS      dns-vip.mycluster.local. ; 或者直接写 VIP IP 的 PTR 记录对应的主机名
    ; @       IN      NS      dns-master.mycluster.local. ; 也可以列出所有服务器
    ; @       IN      NS      dns-slave1.mycluster.local.
    ; @       IN      NS      dns-slave2.mycluster.local.; A Records for Name Servers (actual IPs)
    dns-master      IN      A       192.168.1.10
    dns-slave1      IN      A       192.168.1.11
    dns-slave2      IN      A       192.168.1.12
    dns-vip         IN      A       192.168.1.100 ; VIP; Other records
    server1         IN      A       192.168.1.50
    web             IN      CNAME   server1.mycluster.local.
    

    重要:

    • SOA 记录中的主NS应为 dns-master.mycluster.local.
    • NS 记录应指向客户端实际用于查询的DNS服务器名称。如果使用VIP,则指向VIP对应的主机名。如果客户端可能直接查询各个节点,则列出所有节点。
    • 每次修改区域文件后,务必增加 Serial 号码
  4. 创建反向区域文件 (例如 /var/named/db.192.168.1):
    (内容类似,包含 PTR 记录,SOA 和 NS 记录与正向区域类似)

  5. 设置区域文件权限:

    sudo chown root:named /var/named/db.mycluster.local
    sudo chown root:named /var/named/db.192.168.1
    sudo chmod 640 /var/named/db.mycluster.local
    sudo chmod 640 /var/named/db.192.168.1
    
  6. 检查配置并启动服务:

    sudo named-checkconf /etc/named.conf
    sudo named-checkzone mycluster.local /var/named/db.mycluster.local
    sudo named-checkzone 1.168.192.in-addr.arpa /var/named/db.192.168.1
    sudo systemctl start named
    sudo systemctl enable named
    sudo firewall-cmd --permanent --add-service=dns
    sudo firewall-cmd --reload
    

步骤三:配置从 DNS 服务器 (dns-slave1dns-slave2)

dns-slave1dns-slave2 上执行以下操作 (配置相似,只需注意 IP 地址)。

  1. 编辑 /etc/named.conf (options 部分):

    sudo vi /etc/named.conf
    
    options {listen-on port 53 { 127.0.0.1; <slave_server_ip>; }; // 例如 192.168.1.11 for dns-slave1listen-on-v6 port 53 { ::1; };directory       "/var/named"; // BIND 会将从主服务器同步的区域文件存放在这里 (通常在 slaves/ 子目录)dump-file       "/var/named/data/cache_dump.db";statistics-file "/var/named/data/named_stats.txt";memstatistics-file "/var/named/data/named_mem_stats.txt";allow-query     { localhost; 192.168.1.0/24; };recursion no;allow-recursion { none; };// 从服务器不需要 allow-transfer,除非它也是其他从服务器的主// allow-transfer { none; };dnssec-enable yes;dnssec-validation yes; // 或 nopid-file "/run/named/named.pid";// ... 其他默认选项 ...
    };logging {channel default_debug {file "data/named.run";severity dynamic;};// 建议为从服务器添加 xfer (transfer) 日志channel xfer_log {file "data/xfer.log" versions 3 size 5m;print-time yes;severity info;};category xfer-in { xfer_log; };category xfer-out { xfer_log; };category notify { xfer_log; };
    };include "/etc/named.rfc1912.zones";
    include "/etc/named.root.key";
    
  2. 编辑 /etc/named.rfc1912.zones (定义区域为 slave):

    sudo vi /etc/named.rfc1912.zones
    

    在文件末尾添加:

    zone "mycluster.local" IN {type slave;file "slaves/db.mycluster.local"; // BIND 会自动创建此文件masters { 192.168.1.10; };      // 指定主服务器的 IP 地址// 可选:如果主服务器的 also-notify 可能被防火墙阻止,可以配置 allow-notify// allow-notify { 192.168.1.10; };
    };zone "1.168.192.in-addr.arpa" IN {type slave;file "slaves/db.192.168.1";masters { 192.168.1.10; };
    };
    

    注意: file 指令指定了从主服务器同步下来的区域数据副本的存储位置。BIND 会自动在 directory (即 /var/named/) 下创建 slaves 子目录(如果不存在)并存储这些文件。

  3. 检查配置并启动服务:

    sudo named-checkconf /etc/named.conf
    sudo systemctl start named
    sudo systemctl enable named
    sudo firewall-cmd --permanent --add-service=dns
    sudo firewall-cmd --reload
    
  4. 验证区域传送:

    • 在从服务器启动 named 后,稍等片刻。
    • 查看从服务器的日志 (sudo journalctl -u named -f 或配置的 xfer.log),应该能看到区域传送成功的消息,类似:
      zone mycluster.local/IN: transferred serial 2023072101
      transfer of 'mycluster.local/IN' from 192.168.1.10#53: Transfer completed
    • 检查 /var/named/slaves/ 目录下是否生成了对应的区域文件。

步骤四:配置负载均衡 (以 HAProxy 为例)

这里我们使用 HAProxy 作为软件负载均衡器。可以在一台独立的服务器上安装 HAProxy,或者在其中一台 DNS 服务器上安装(但不推荐用于生产环境的关键服务)。

假设 HAProxy 安装在 IP 为 192.168.1.20 的服务器上。

  1. 安装 HAProxy:

    sudo yum install -y haproxy
    
  2. 配置 HAProxy (/etc/haproxy/haproxy.cfg):

    sudo vi /etc/haproxy/haproxy.cfg
    

    添加或修改以下内容:

    globallog         /dev/log local0chroot      /var/lib/haproxypidfile     /var/run/haproxy.pidmaxconn     4000user        haproxygroup       haproxydaemonstats socket /var/lib/haproxy/statsdefaultsmode                    http # 对于DNS,通常用tcp模式,但http模式的健康检查更灵活log                     globaloption                  httplog # 如果是tcp模式,用tcplogoption                  dontlognulloption                  http-server-close # 如果是tcp模式,用clitcpka 和 srvtcpka# option                forwardfor except 127.0.0.0/8 # 如果需要传递客户端IPoption                  redispatchretries                 3timeout http-request    10stimeout queue           1mtimeout connect         10stimeout client          1mtimeout server          1mtimeout http-keep-alive 10stimeout check           10smaxconn                 3000# DNS UDP Frontend and Backend
    frontend dns_udp_frontendbind 192.168.1.100:53 proto udp # VIP 和 UDP 端口mode udpdefault_backend dns_udp_backendbackend dns_udp_backendmode udpbalance roundrobin # 或 leastconn# 健康检查对UDP比较困难,通常依赖TCP的健康检查或外部脚本# HAProxy 对 UDP 的健康检查支持有限,通常依赖于后端服务器是否响应server dns_master 192.168.1.10:53 check # 'check' 对UDP可能无效或行为不同server dns_slave1 192.168.1.11:53 checkserver dns_slave2 192.168.1.12:53 check# DNS TCP Frontend and Backend (DNS也使用TCP,例如区域传送或大型响应)
    frontend dns_tcp_frontendbind 192.168.1.100:53 proto tcp # VIP 和 TCP 端口mode tcpdefault_backend dns_tcp_backendbackend dns_tcp_backendmode tcpbalance roundrobinoption tcp-check # 使用TCP健康检查# TCP健康检查:尝试连接到服务器的53端口# 可以更复杂,例如发送一个简单的DNS查询并期望特定响应# default-server check port 53 inter 2s fall 3 rise 2server dns_master 192.168.1.10:53 check port 53 inter 2s fall 3 rise 2server dns_slave1 192.168.1.11:53 check port 53 inter 2s fall 3 rise 2server dns_slave2 192.168.1.12:53 check port 53 inter 2s fall 3 rise 2# HAProxy Stats Page (可选)
    listen statsbind *:8404mode httpstats enablestats uri /statsstats realm Haproxy\ Statisticsstats auth admin:password # 设置用户名和密码
    

    关于 HAProxy UDP 健康检查的说明:
    HAProxy 对 UDP 服务的健康检查能力有限。check 关键字在 mode udp 下的行为可能不如 TCP。更可靠的 UDP 健康检查通常需要:

    • 依赖于 TCP 端口的健康检查(如果服务同时监听 TCP)。
    • 使用外部脚本通过 option external-check 执行自定义的 UDP 健康检查。
    • 对于 DNS,一个简单的 TCP 连接检查到端口 53 通常可以作为指示。
  3. 允许 HAProxy 绑定到非本地 IP (VIP):

    sudo sysctl -w net.ipv4.ip_nonlocal_bind=1
    # 持久化
    echo "net.ipv4.ip_nonlocal_bind=1" | sudo tee /etc/sysctl.d/90-haproxy.conf
    
  4. 启动 HAProxy 并设置开机自启:

    sudo systemctl start haproxy
    sudo systemctl enable haproxy
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" port port="53" protocol="udp" accept'
    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" port port="53" protocol="tcp" accept'
    sudo firewall-cmd --permanent --add-port=8404/tcp # 如果启用了stats页面
    sudo firewall-cmd --reload
    

步骤五:配置客户端

将客户端的 DNS 服务器设置为负载均衡器的 VIP:192.168.1.100


步骤六:(可选) 使用 Keepalived 实现 VIP 高可用和负载均衡器冗余

如果 HAProxy 本身成为单点故障,可以使用 Keepalived 来管理 VIP 并在多个 HAProxy 节点之间进行故障转移。

假设你有两台 HAProxy 服务器 (haproxy1: 192.168.1.20, haproxy2: 192.168.1.21)。

  1. 在两台 HAProxy 服务器上安装 Keepalived:

    sudo yum install -y keepalived
    
  2. 配置 Keepalived (/etc/keepalived/keepalived.conf):

    • 在 haproxy1 (MASTER):

      ! Configuration File for keepalivedglobal_defs {router_id HAPROXY_DNS_01
      }# 脚本用于检查HAProxy进程是否在运行
      vrrp_script chk_haproxy {script "killall -0 haproxy"   # 检查haproxy进程是否存在interval 2                    # 每2秒检查一次weight 2                      # 如果成功,权重加2
      }vrrp_instance VI_DNS {state MASTERinterface eth0                # 根据你的网卡名称修改virtual_router_id 51          # 必须在所有Keepalived节点上相同priority 101                  # MASTER 优先级更高advert_int 1authentication {auth_type PASSauth_pass yoursecret      # 密码,所有节点相同}virtual_ipaddress {192.168.1.100/24 dev eth0 label eth0:vip1 # VIP}track_script {chk_haproxy}
      }
      
    • 在 haproxy2 (BACKUP):

      ! Configuration File for keepalivedglobal_defs {router_id HAPROXY_DNS_02
      }vrrp_script chk_haproxy {script "killall -0 haproxy"interval 2weight 2
      }vrrp_instance VI_DNS {state BACKUPinterface eth0virtual_router_id 51priority 100                  # BACKUP 优先级较低advert_int 1authentication {auth_type PASSauth_pass yoursecret}virtual_ipaddress {192.168.1.100/24 dev eth0 label eth0:vip1}track_script {chk_haproxy}
      }
      
  3. 启动 Keepalived 并设置开机自启 (在两台 HAProxy 服务器上):

    sudo systemctl start keepalived
    sudo systemctl enable keepalived
    sudo firewall-cmd --permanent --add-protocol=vrrp # 允许VRRP协议
    sudo firewall-cmd --reload
    

    现在,192.168.1.100 这个 VIP 会由 Keepalived 管理。如果 haproxy1 上的 HAProxy 进程挂掉或服务器宕机,VIP 会自动漂移到 haproxy2


测试高可用性:

  1. 主从同步测试:

    • dns-master 上修改区域文件 (例如,添加一条 A 记录),并增加 SOA 序列号
    • 执行 sudo rndc reload mycluster.local (或 sudo systemctl reload named)。
    • 在从服务器上查看日志,确认区域已成功传送新的序列号。
    • 在从服务器上使用 dig @localhost new_record.mycluster.local 查询新记录。
  2. 负载均衡和故障转移测试 (HAProxy + BIND 节点):

    • 从客户端 dig @192.168.1.100 existing_record.mycluster.local,多次查询,观察 HAProxy 是否将请求分发到不同的后端 BIND 服务器 (可以在 BIND 服务器上开启查询日志来确认)。
    • 停止其中一个从 BIND 服务器 (sudo systemctl stop named on dns-slave1)。
    • 再次从客户端查询,请求应该仍然成功,并由其他健康的 BIND 服务器响应。HAProxy 的健康检查应该会将故障节点标记为 down。
    • 恢复 dns-slave1 上的 named 服务,它应该会自动重新加入到负载均衡池中。
  3. VIP 故障转移测试 (Keepalived + HAProxy 节点):

    • 在当前持有 VIP 的 HAProxy 服务器 (MASTER Keepalived) 上停止 keepalived 服务或 haproxy 服务 (如果 track_script 配置正确)。
    • 观察 VIP (192.168.1.100) 是否成功漂移到另一台 HAProxy 服务器 (BACKUP Keepalived)。可以使用 ip addr show 查看。
    • 从客户端继续查询 dig @192.168.1.100 existing_record.mycluster.local,应该仍然成功。

注意事项和改进:

  • 安全性:
    • 严格配置防火墙,只允许必要的端口和源 IP。
    • 保护 rndc.key 文件。
    • 考虑使用 TSIG (Transaction Signatures) 来保护区域传送。
    • 定期更新 BIND 和其他系统组件。
  • 日志和监控:
    • 配置详细的日志记录,并使用集中式日志管理系统。
    • 使用监控系统 (Nagios, Zabbix, Prometheus) 监控 BIND 服务、HAProxy、Keepalived 的状态以及 DNS 解析的健康状况。
  • DNSSEC: 如果你的区域需要 DNSSEC 签名,确保主服务器正确签名区域,从服务器能够处理已签名的区域。
  • 扩展性: 可以根据需要增加更多的从服务器和 HAProxy 节点。
  • Anycast: 对于更大规模或地理分布的 DNS 集群,可以考虑使用 Anycast IP 地址,这需要网络设备的支持。
  • 配置管理: 使用 Ansible, Puppet, Chef 等工具自动化部署和管理配置。

这是一个相对完整的搭建高可用 BIND9 集群的方案。根据你的具体需求和环境,可能需要进行调整。

相关文章:

  • 将 /dev/vdb1 的空间全部合并到 /dev/mapper/centos-root(即扩展 CentOS 的根分区)
  • MyBatis 动态 SQL 标签详解教程:_set_、_trim_、_sql_、_choose_、_when_
  • 数据库外键
  • 测试W5500的第3步_使用ioLibrary库创建TCPServer
  • Flink并行数据源:ClickSource实现详解
  • RISC-V 开发板 MUSE Pi Pro USB 测试(3.0 U盘,2.0 UVC摄像头)
  • 边缘智能与量子计算双轮驱动:IVX 开启实时 AI 开发新维度
  • Runtipi - 开源个人家庭服务器管理工具
  • 通义灵码助力JavaScript开发:快速获取API与智能编码技巧
  • 【信息系统项目管理师】第12章:项目质量管理 - 26个经典题目及详解
  • 绿盟防火墙6.0.5版本—接入网监平台
  • 对冲策略加仓止损盈思路
  • Hbuilder X4.65新建vue3项目存在的问题以及解决办法
  • 贝叶斯优化+CNN+LSTM=小论文创新点
  • 【LinkedList demo 内部类讲说】
  • 【基于SpringBoot的图书购买系统】深度讲解 分页查询用户信息,分析前后端交互的原理
  • Linux(3)——基础开发工具
  • 威纶通触摸屏IP地址设定步骤及程序下载指南
  • Nginx笔记
  • 传输层协议:UDP和TCP
  • 以色列“全面接管”加沙“雷声大雨点小”:援助政策引内讧,美欧失去耐心
  • 破题“省会担当”,南京如何走好自己的路?
  • 春决火爆的背后,PEL如何做大这块电竞蛋糕
  • 马上评|去年维修竣工的鼓楼,今年就“瀑布式落瓦”
  • 国家话剧院上海演出季7月重启,《大宅门》等5部大戏来沪
  • 4名中学生同服处方药后身体不适,一心堂一药店未凭处方售药被罚1万元