ansible lineinfile 模块可安全收紧全网 dns 配置:精准锚定目标行、backrefs 保留格式、分三步清理/注入/验证,并通过灰度发布与健康探测保障业务连续性。

在 DNS 场景下,用 Ansible lineinfile 模块对全网主机的 DNS 配置(如 /etc/resolv.conf 或网络接口配置文件)做“收紧”——即统一替换为指定可信 DNS 服务器(如 10.10.10.10、10.10.10.11),同时保证不停机、不中断业务、不重复写入、不破坏原有注释与格式——关键在于**精准锚定、幂等替换、容错保留、分步验证**。
明确目标行结构,避免模糊匹配
DNS 配置常分散在不同路径:/etc/resolv.conf、/etc/sysconfig/network-scripts/ifcfg-*、/etc/netplan/*.yaml(取决于发行版)。不能用 ^nameserver.*$ 这类宽泛正则,否则可能误删注释行或匹配到被注释掉的旧配置。
- 针对
/etc/resolv.conf:用^nameservers+S+匹配有效 nameserver 行,确保只改启用项 - 针对 RHEL/CentOS 的 ifcfg 文件:匹配
^DNS[0-9]*=,例如^DNS1=或^DNS2=,避免碰PEERDNS=yes等控制参数 - 始终加
^和s+锚点,排除缩进、空格干扰;对点号、斜杠等字符转义(如10.10.10.10)
用 backrefs 保留原始格式,实现无损替换
直接用 line: 全量覆盖会丢失原有缩进、空格或注释上下文。启用 backrefs: true,配合捕获组,可复用原格式特征:
- 示例:将任意
nameserver行替换成新地址,但保留原有前导空格和语法结构regexp: '^(\s*)nameserver\s+\S+'line: 'nameserver 10.10.10.10'backrefs: true - 这样即使原行是
nameserver 8.8.8.8,也会变成nameserver 10.10.10.10,格式零扰动
分阶段执行:先清理冗余,再注入主DNS,最后验证生效
“收紧”不是简单覆盖,而是有逻辑的三步收敛:
-
清理阶段:用
state: absent删除所有非白名单 DNS 行(如regexp: '^nameservers+(8.8.8.8|114.114.114.114)'),排除公网 DNS -
注入阶段:确保两条主 DNS 存在且顺序正确(如 DNS1 主、DNS2 备),用
insertafter定位到^# Generated by.*或 EOF,避免插到中间破坏逻辑 -
兜底保障:对
/etc/resolv.conf设置create: true,防止文件意外缺失;同时加backup: true,每台机器自动留一份.bak
验证与灰度:抽样检查 + 健康探测 + 分批滚动
全网批量操作必须带验证闭环,否则“看似成功实则失效”:
- 任务末尾加
command: grep -q '10.10.10.10' /etc/resolv.conf && nslookup -timeout=2 google.com 10.10.10.10 | grep 'Server:',失败则报错中断 - 首次执行时用
--limit @dns-tighten-preview限定 5 台测试节点;确认无误后,再用--limit 'all:!backup-servers'排除关键备份节点 - 结合
serial: 5控制并发数,避免 DNS 切换瞬间引发大量解析抖动;对核心集群可设serial: 1逐台操作











