DNS 迁移应提前降低 TTL,并保留回滚缓存窗口
DNS TTL 表示一条资源记录通常可以在缓存中保留多久,之后需要刷新。修改权威记录会改变未来回答,却不会向所有曾经存储该数据的解析器发送失效通知。因此,一次迁移既包含权威更新,也包含一段客户端可能合法发现不同地址的时期。规划服务可用性时,需要同时考虑新答案和仍然存在的旧答案,而不是只看控制台保存成功。 图示表达事件先后,并非等比例时间轴。缓存可能保留不同代际;应用缓存和已有连接还有各自的生命周期。 坏掉的样子 在修改地址的同一时刻降低 TTL,并不会缩短此前缓存回答的寿命。保存了旧长 TTL 的解析器尚未获知新短 TTL。此时立即移除旧服务,可能让那些客户端失败,即使所有权威查询都已返回新地址。问题来自服务重叠期与尚未消失的发现状态不匹配;反复检查权威端的新值正确,并不能解决使用旧缓存的客户端请求。 回滚也具有同样的不对称性。把区域改回去,不会从已经学到新地址的缓存里撤回该地址。短暂正常的新目的地,可能在回滚命令完成后继续收到请求。应让回滚目标与刚发布过的目标在相关重叠期内都可用,或者明确客户端访问任何一个时如何获得可接受结果。DNS 回滚不是立即停止新地址流量的开关。 也不要把每层缓存的原始 TTL 简单相加,作为传播时间。普通转发缓存返回剩余寿命,下游再对收到的值继续计时;不同解析器群体则可能在不同时间填充缓存。应用自有缓存、长连接、权威同步延迟以及配置的陈旧回答策略,还会让单个 TTL 无法成为端到端完成保证。应把这些行为分别调查,不能用一个“传播中”笼统覆盖。 快速验证 将脚本保存为 check-dns-move.py,准备 Docker 后执行 python3 check-dns-move.py。固定环境以 BIND 9.18.49 为权威,以 dnsmasq 2.90 为一个转发缓存,二者运行在隔离容器回环接口上。程序只修改自己的临时区域,每次递增序列号并确认权威重载完成,再观察缓存。整个过程不改变公共 DNS,也不调整系统时间: ...