SmartDNS集群部署方案:主从架构实现高可用
【免费下载链接】smartdns A local DNS server to obtain the fastest website IP for the best Internet experience, support DoT, DoH. 一个本地DNS服务器,获取最快的网站IP,获得最佳上网体验,支持DoH,DoT。
项目地址: https://gitcode.com/GitHub_Trending/smar/smartdns
1. 痛点与解决方案概述
在企业级DNS服务部署中,单点故障导致的服务中断可能造成全网瘫痪。根据SRE实践统计,DNS服务不可用平均每小时造成约30万美元损失,而传统单节点部署的故障恢复时间(MTTR)通常超过15分钟。本文将通过主从架构实现SmartDNS的高可用集群,解决以下核心痛点:
- 单点失效风险:采用主从热备架构,实现故障自动切换
- 配置一致性:通过文件同步与事件触发机制保持节点配置统一
- 流量负载均衡:基于权重的请求分发策略,避免单点压力过载
- 健康状态监控:内置+外部双重健康检查机制,确保服务可用性
读完本文你将获得:
- 主从节点的详细配置模板(含Docker部署方案)
- 3种自动故障切换实现方式的对比与选型
- 集群监控面板的搭建指南
- 配置同步与版本控制最佳实践
- 压力测试与故障注入验证方法
2. 架构设计与原理
2.1 主从架构拓扑

核心组件说明:
- 虚拟IP(VIP):通过Keepalived管理的浮动IP,客户端统一接入点
- 主从节点:运行SmartDNS服务的双节点,配置保持一致
- 配置同步:基于rsync+inotify的实时配置文件同步
- 健康监控:Prometheus采集指标,Grafana可视化告警
2.2 故障切换流程

关键指标:
- 故障检测延迟:≤1秒(可配置)
- 切换完成时间:≤2秒(含ARP缓存更新)
- 数据一致性:RPO=0(配置实时同步)
- 服务可用性:99.99%(每年允许 downtime ≤52.56分钟)
3. 环境准备与部署规划
3.1 服务器规格要求
| 配置项 | 最低配置 | 推荐配置 | 说明 |
|---|
| CPU | 1核 | 2核 | 处理并发查询,推荐2核以上 |
| 内存 | 512MB | 1GB | 缓存DNS记录,降低上游查询频率 |
| 存储 | 10GB SSD | 20GB SSD | 日志与配置文件存储 |
| 网络 | 100Mbps | 1Gbps | 低延迟网络环境,支持多线路冗余 |
| 操作系统 | Linux kernel ≥3.10 | Linux kernel ≥5.4 | 支持namespaces和tc模块 |
3.2 网络规划
| 网络对象 | IP地址 | 端口 | 用途 |
|---|
| Master节点 | 192.168.1.10 | 53/udp, 53/tcp | DNS服务端口 |
| Slave节点 | 192.168.1.11 | 53/udp, 53/tcp | DNS服务端口 |
| 虚拟IP(VIP) | 192.168.1.254 | - | 客户端接入地址 |
| 管理端口 | 6080/tcp | WebUI管理界面 |
| 监控端口 | 9253/tcp | Prometheus指标暴露 |
3.3 软件版本规划
| 组件 | 版本要求 | 作用 |
|---|
| SmartDNS | ≥1.2023.09 | 核心DNS服务 |
| Keepalived | ≥2.2.7 | 实现VRRP协议与故障切换 |
| rsync | ≥3.2.7 | 配置文件同步 |
| inotify-tools | ≥3.22.6 | 监控配置文件变更 |
| Prometheus | ≥2.45.0 | 指标采集 |
| Grafana | ≥10.1.0 | 可视化监控面板 |
4. 主从节点部署步骤
4.1 基础环境准备(所有节点)
# 安装依赖包
apt update && apt install -y build-essential libssl-dev pkg-config \
rsync inotify-tools keepalived prometheus-node-exporter
# 克隆代码仓库
git clone https://gitcode.com/GitHub_Trending/smar/smartdns
cd smartdns
# 编译安装SmartDNS
make -j$(nproc) && make install
4.2 主节点配置
4.2.1 SmartDNS核心配置(/etc/smartdns/smartdns.conf)
# 基础配置
server-name smartdns-master
bind 0.0.0.0:53
bind-tcp 0.0.0.0:53
cache-size 65536
log-level info
log-file /var/log/smartdns/smartdns.log
# 上游服务器配置(区分国内外域名)
server 223.5.5.5 -group default -check-edns
server 119.29.29.29 -group default
server tls://dns.google -group overseas -exclude-default-group
server https://dns.example.com/dns-query -group overseas -exclude-default-group
# 域名分流规则
nameserver /cn/ -group default
nameserver /com/ -group overseas
nameserver /google.com/ -group overseas
# 高可用配置
serve-expired yes
serve-expired-ttl 86400
max-query-limit 10000
# WebUI配置(用于监控)
plugin smartdns_ui.so
smartdns-ui.ip http://0.0.0.0:6080
smartdns-ui.enable-cors yes
4.2.2 Keepalived配置(/etc/keepalived/keepalived.conf)
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass SmartDNS@Cluster2025
}
virtual_ipaddress {
192.168.1.254/24
}
track_script {
check_smartdns
}
notify_master "/usr/local/bin/smartdns_master.sh"
notify_backup "/usr/local/bin/smartdns_backup.sh"
}
vrrp_script check_smartdns {
script "/usr/local/bin/check_smartdns.sh"
interval 1
weight -50
fall 3
rise 2
}
4.3 从节点配置
4.3.1 SmartDNS配置(与主节点差异部分)
# 从节点标识
server-name smartdns-slave
# 禁用自动更新(由主节点同步)
cache-persist no
# 健康检查增强(从节点额外检查主节点状态)
domain-rules /_smartdns_health_check_/ -nameserver master-check
server 192.168.1.10:53 -group master-check -fallback
4.3.2 Keepalived配置(从节点)
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100 # 低于主节点
advert_int 1
authentication {
auth_type PASS
auth_pass SmartDNS@Cluster2025
}
virtual_ipaddress {
192.168.1.254/24
}
track_script {
check_smartdns
check_master_node
}
}
vrrp_script check_master_node {
script "/usr/local/bin/check_master_node.sh"
interval 1
weight 50
}
4.4 配置同步机制
4.4.1 主节点同步服务(/etc/systemd/system/smartdns-sync.service)
[Unit]
Description=SmartDNS Config Sync Service
After=network.target
[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/smartdns_sync.sh
Restart=always
RestartSec=2
[Install]
WantedBy=multi-user.target
4.4.2 同步脚本实现(/usr/local/bin/smartdns_sync.sh)
#!/bin/bash
SYNC_DIR="/etc/smartdns"
REMOTE_NODE="192.168.1.11"
SYNC_USER="syncuser"
inotifywait -m -r -e modify,create,delete "$SYNC_DIR" | while read -r directory events filename; do
rsync -avz --delete "$SYNC_DIR/" "${SYNC_USER}@${REMOTE_NODE}:${SYNC_DIR}/"
ssh "${SYNC_USER}@${REMOTE_NODE}" "systemctl reload smartdns"
logger -t "smartdns-sync" "Config synchronized to ${REMOTE_NODE}: $events $filename"
done
5. 健康检查与故障处理
5.1 多层次健康检查实现
| 检查类型 | 实现方式 | 检查内容 | 故障阈值 | 恢复阈值 |
|---|
| 进程检查 | systemd | 服务运行状态 | 1次失败 | 2次成功 |
| 端口检查 | netcat | 53端口监听状态 | 2次失败 | 1次成功 |
| 功能检查 | dig命令 | 解析特定域名耗时 | >500ms持续3次 | <200ms持续2次 |
| 主节点检查 | curl | 主节点WebUI状态 | 3次超时 | 1次成功 |
5.1.1 核心检查脚本(check_smartdns.sh)
#!/bin/bash
# 1. 检查进程状态
if ! systemctl is-active --quiet smartdns; then
exit 1
fi
# 2. 检查端口监听
if ! nc -z 127.0.0.1 53; then
exit 1
fi
# 3. 检查解析功能
RESOLVE_TIME=$(dig @127.0.0.1 www.example.com +time=1 +tries=1 +short | wc -l)
if [ $RESOLVE_TIME -eq 0 ]; then
exit 1
fi
exit 0
5.2 故障自动恢复流程

6. 监控与运维
6.1 Prometheus监控配置
scrape_configs:
- job_name: 'smartdns'
static_configs:
- targets: ['192.168.1.10:9253', '192.168.1.11:9253']
metrics_path: '/metrics'
scrape_interval: 5s
- job_name: 'keepalived'
static_configs:
- targets: ['192.168.1.10:9650', '192.168.1.11:9650']
6.2 关键监控指标
| 指标名称 | 说明 | 告警阈值 |
|---|
| smartdns_query_total | 总查询量 | 单节点>1000QPS |
| smartdns_query_failed | 失败查询数 | >1%总查询量 |
| smartdns_upstream_latency | 上游查询延迟 | P95>500ms |
| smartdns_cache_hit_ratio | 缓存命中率 | <70% |
| node_load1 | 系统负载 | >CPU核心数*0.7 |
6.3 日常运维工具
6.3.1 集群状态查看工具
#!/bin/bash
# /usr/local/bin/smartdns_cluster_status.sh
echo "=== SmartDNS Cluster Status ==="
echo "VIP Status: $(ip addr show eth0 | grep 192.168.1.254 && echo "MASTER" || echo "BACKUP")"
echo "Service Status: $(systemctl is-active smartdns)"
echo "Sync Status: $(grep "rsync" /var/log/smartdns-sync.log | tail -n1 | awk '{print $5" "$6" "$7}')"
echo "Query Stats: $(curl -s http://localhost:6080/api/stats | jq '.query_total') queries"
6.3.2 配置版本控制脚本
#!/bin/bash
# /usr/local/bin/smartdns_config_commit.sh
cd /etc/smartdns
git add .
git commit -m "Auto-commit: $(date +%Y-%m-%d_%H:%M:%S)"
git push origin main
7. 性能优化与最佳实践
7.1 配置优化参数
| 参数 | 推荐值 | 作用 |
|---|
| cache-size | 65536 | 缓存记录数,根据内存调整 |
| tcp-idle-time | 30 | TCP连接超时时间 |
| max-query-limit | 10000 | 每秒查询限制,防止DoS |
| speed-check-mode | ping,tcp:80,tcp:443 | 多维度测速提高准确性 |
| dualstack-ip-selection | yes | 双栈IP智能选择 |
7.2 高并发场景优化
- 内核参数调优:
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.udp_mem = 8388608 12582912 16777216
net.ipv4.tcp_mem = 8388608 12582912 16777216
net.ipv4.ip_local_port_range = 1024 65535
- CPU亲和性配置:
# 将SmartDNS进程绑定到CPU 0和1
taskset -c 0,1 -p $(pidof smartdns)
7.3 安全加固措施
- 文件权限控制:
chmod 600 /etc/smartdns/smartdns.conf
chown root:root /etc/smartdns -R
- 限制客户端查询:
# 在配置文件中添加
client-rule 192.168.1.0/24 -group internal
client-rule 0.0.0.0/0 -nameserver -
- TLS加密传输:
bind-tls [::]:853
bind-cert-file /etc/smartdns/certs/server.crt
bind-cert-key-file /etc/smartdns/certs/server.key
server-tls 8.8.8.8 -spki-pin "sha256/abcdef..."
8. 部署验证与压力测试
8.1 功能验证 checklist
| 验证项 | 测试方法 | 预期结果 |
|---|
| VIP漂移 | 关闭主节点keepalived | VIP在10秒内切换到从节点 |
| 配置同步 | 修改主节点规则文件 | 从节点5秒内应用新配置 |
| 故障恢复 | 恢复主节点服务 | 自动切回主节点(可选配置) |
| 负载均衡 | 查看两边查询日志 | 请求按权重分发(主60%/从40%) |
| 缓存同步 | 主节点解析新域名 | 从节点无需查询上游直接返回结果 |
8.2 压力测试方案
# 使用dnsperf进行压力测试
dnsperf -d queryfile.txt -s 192.168.1.254 -p 53 -l 300 -c 100 -Q 5000
# queryfile.txt格式示例
www.example.com A
www.example.org A
www.example.net AAAA
测试指标参考值:
- 单节点QPS:≥5000(2核4G配置)
- 95%查询延迟:<20ms
- 缓存命中率:>85%
- 故障切换期间丢包率:<5%(理论值)
8.3 故障注入测试
- 主节点网络中断:
# 使用tc命令模拟网络故障
tc qdisc add dev eth0 root netem loss 100%
#
【免费下载链接】smartdns A local DNS server to obtain the fastest website IP for the best Internet experience, support DoT, DoH. 一个本地DNS服务器,获取最快的网站IP,获得最佳上网体验,支持DoH,DoT。
项目地址: https://gitcode.com/GitHub_Trending/smar/smartdns