本文主要以 CoreDNS 为例,介绍 DNS 高可用常见部署形态,重点说明 Anycast(含基于 BGP 的「类 Anycast」)为何适合 DNS,以及在落地时需要注意的边界条件。
CoreDNS 本身是无状态、可水平扩展的 DNS 服务器,高可用通常不依赖「主从复制协议」,而更多依赖:多实例 + 健康检查 + 合理的流量入口(VIP / LB / Anycast)。下面先澄清地址模型,再落到 DNS 场景。
背景说明
DNS 解析路径一旦中断,业务会大面积不可用。单实例 CoreDNS 足以支撑实验室,但生产环境通常需要:
- 多副本,避免单点故障
- 客户端配置尽量简单(固定 nameserver IP)
- 故障时流量能尽快离开故障节点
- 延迟尽量低(查询就近应答)
CoreDNS 系列前文已覆盖安装、插件、Kubernetes 集成等主题,本文集中讨论「入口高可用」层面的方案选择。
地址模型:Unicast 与 Anycast
Internet 协议常见寻址方式包括:
| 模型 | 关系 | 简要说明 |
|---|---|---|
| Unicast | 一对一 | 一个地址对应一个终点 |
| Broadcast | 一对全 | 广播域内所有终点 |
| Multicast | 一对多 / 多对多 | 一组接收者 |
| Anycast | 一对「组内之一」 | 同一地址的一组终点,由路由选一条「最近」路径 |
| Geocast | 特殊组播 | 按地理位置投递 |
Anycast 的关键点:多个节点宣告相同 IP,网络按路由度量(跳数、策略等)把请求送到「其中一个」节点。某个 PoP 或机房故障时,路由收敛后流量会自然切到其他仍在宣告的节点。
IPv4 上的常见实现方式
- IPv6 在协议层面更明确地讨论 Anycast。
- 公网大量设备仍使用 IPv4。工程上常见做法是:多台主机使用相同的「逻辑服务地址」,通过 BGP 等方式向网络宣告,客户端以为自己在做 Unicast,底层却是 Anycast 选路。
需要注意的是:若会话中途发生路径切换(例如 PoP 切换),基于连接的传输可能受影响。因此:
- 与 TCP 长连接组合时要格外谨慎
- UDP 无连接特性更契合 Anycast
DNS 查询主流使用 UDP,因此 DNS 是 Anycast 的自然用例之一。
Anycast DNS 的收益
相对传统「每客户端一套不同 Unicast nameserver」或「仅依赖单机房 VIP」,Anycast DNS 常见收益包括:
- 自动分流:相同 cost 时,查询可在多个节点间分散
- 缓解针对 DNS 的 DDoS 影响:攻击流量被分散到多个宣告点,局部过载不一定拖垮全局
- 降低延迟:路由倾向选择网络距离更近的应答节点
- 提高可用性:部分节点故障后,仍宣告的节点可继续服务
- 故障切换对客户端透明:客户端仍配置同一组 nameserver IP
- 简化客户端配置:无需为每个站点维护不同 DNS 地址清单(仍建议配置多个逻辑地址做保险)
以上收益依赖正确的路由宣告、健康检查与退出宣告。没有健康检查的 Anycast 可能把流量继续送进「进程已死但路由仍在」的黑洞。
CoreDNS 高可用落地形态
下面几类可以单独使用,也可以组合。
单机房:VIP + Keepalived / LB
适用:机房内多 CoreDNS 实例,客户端使用内网 VIP。
- 多实例运行相同 Corefile 与后端(或共享可水平扩展的后端)
- VIP 由 keepalived、LVS、云 LB 等漂移或转发
- 健康检查失败时摘除后端
优点是实现简单、运维心智负担低;缺点是机房级故障时 VIP 一并失效,跨站点能力弱。
多机房:DNS 侧配置多个 Unicast 地址
客户端配置多个不同机房的 Unicast IP,解析器按顺序或并行尝试。
优点是不依赖 BGP Anycast;缺点是客户端配置与变更成本高,故障切换行为依赖各 OS stub resolver 实现。
多机房:Anycast(BGP 宣告同一服务地址)
每个站点的 CoreDNS(或其前的 LB)通过 BGP 向网络宣告同一 Anycast 地址。
落地时建议明确:
| 项 | 说明 |
|---|---|
| 宣告主体 | 主机直接跑 BGP,或经路由器 / 金属 LB 代宣告 |
| 健康检查 | 进程、端口、关键查询失败时 撤回宣告 |
| 指标 | 查询成功率、延迟、NXDOMAIN 比例、上游错误 |
| 数据面 | Corefile、插件、缓存策略、上游 DNS 是否一致 |
| 安全 | 限制递归范围、限流、管理面鉴权 |
CoreDNS 本身不负责 BGP;Anycast 是网络层能力。工程上常见组合是:CoreDNS 多副本 + 节点/主机级健康检查 + BGP 宣告 Anycast IP。
Kubernetes 集群内 DNS
集群内 CoreDNS 通常以 Deployment + Service(ClusterIP)提供服务,高可用依赖:
- 副本数 ≥ 2
- 合理的
readiness/liveness - 节点打散(anti-affinity)
- 资源与
upstream/kubernetes插件稳定性
这与「站点级 Anycast 权威/递归 DNS」是不同层次的问题,不要混为一谈。
推荐实施顺序
以「新建一套可跨机房的递归/内网 DNS」为例,建议顺序如下:
- 先单站点双实例 + VIP/LB,验证 Corefile、缓存、上游与监控
- 补齐健康检查与告警(进程、端口、合成查询)
- 第二站点复制同一数据面配置
- 再引入 Anycast/BGP,先在测试 AS 或实验室验证宣告与撤回
- 压测与故障演练:杀进程、断网、撤 BGP,观察客户端解析是否可接受
需要注意的是:没有监控与演练的 Anycast,排障难度会明显高于单机房 VIP。
注意事项
- Anycast 不能替代「配置一致性」:两地 Corefile 或上游不一致会导致「同 IP 不同答案」。
- 健康检查失败必须能 停止宣告,否则会出现黑洞路由。
- TCP DNS(如较大的响应、DoH/DoT 前置)与纯 UDP Anycast 的假设不同,需要单独设计。
- 公网宣告涉及地址权属与运营商策略,内网 Anycast 也需与网络团队对齐 OSPF/BGP 方案。
- 本文侧重方案与边界;具体 Corefile 与 BGP 配置需按现网拓扑编写,不能照搬占位符。
参考资料
- 站内 CoreDNS 系列前文(安装、插件、Kubernetes、递归与日志等)
- 任播与 BGP 基础概念可参考各厂商与 RFC 相关说明;落地以现网网络方案为准
- CoreDNS 文档