Ansible割接剧本中ip_route模块实现无损路由更新的核心是“先增后删”三步协同:预检下一跳连通性、原子化添加高metric新路由、延时清理旧路由,同时需配合状态判断、分组变量和幂等性设计。

在 Ansible 割接剧本中用 ip_route 模块更新全国各区域节点的静态路由,核心是“幂等性”和“无损”——即重复执行不引发冲突、切换时不中断业务流量。关键不在命令是否执行,而在路由状态是否真正收敛、旧路由是否被精准清理、新路由是否按需生效。
明确 ip_route 模块的行为边界
ip_route 是 Ansible 内置模块(Ansible 2.10+),直接调用系统 ip route 命令,但只管理“当前命名空间下”的路由条目。它本身不感知 VRRP 状态、不等待接口就绪、也不自动处理多路径或策略路由冲突。因此不能单独依赖它完成“割接”,必须配合状态判断与前置条件。
- 支持
state: present(添加/替换)和state: absent(删除),两者均具备幂等性:目标路由已存在且参数一致时,changed: false;目标不存在时才执行变更 - 不支持批量操作,每条路由需独立 task;若需批量,可用
loop或with_items,但要注意单条失败不影响整体(加ignore_errors: true并后续校验) - 必须指定
device(出接口)或via(下一跳),二者不可同时为空;若使用table或metric等高级参数,需确保内核支持且目标系统已启用对应功能
按区域分组定义路由策略并绑定主机变量
全国节点通常按地域(如华北、华东、华南)划分 inventory 组,每个组应有明确的骨干出口、备用下一跳、BFD 或健康探测机制。路由配置不应硬编码在 playbook 中,而应从 host_vars 或 group_vars 动态加载:
当代理已经知道网站路由或内容URL,并且在启动前需要有效的sitemap XML、sitemap索引或robots.txt引用时,请使用sitemap。这是一个发布构件技能,而不是爬虫或SEO平台。
- 在
group_vars/north_china.yml中定义:routes:- dest: 10.20.0.0/16via: 192.168.100.1device: bond0metric: 10- dest: 172.16.5.0/24via: 192.168.100.2device: bond0metric: 20 - playbook 中用
loop: "{{ routes | default([]) }}"遍历,每条生成一个ip_routetask - 对关键路由(如核心网段),可加
condition: ansible_facts['default_ipv4']['address'] != '192.168.100.254'避免在 VIP 所在节点误配
实现无损更新的三步协同逻辑
单纯 add/delete 不等于无损。真实割接需“先增后删”,并验证下一跳可达性,避免黑洞:
-
Step 1:预检下一跳连通性
用wait_for模块探测所有via地址的 ICMP 或 TCP 端口(如 SSH 22),超时设为 30s,失败则整个 play 中断或跳过该区域 -
Step 2:原子化添加新路由
对每条待更新路由,执行ip_route: state=present,并设置metric高于原路由(例如原为 10,新设为 5),使新路由优先生效;不立即删除旧路由 -
Step 3:延时清理旧路由
等待 60 秒(确保 FIB 同步、ECMP 收敛),再用ip_route: state=absent删除旧条目;也可用shell模块执行ip route flush cache加速内核路由表刷新
规避常见陷阱的实操要点
跨区域大规模更新易因网络抖动、设备响应延迟或内核版本差异导致失败,需针对性加固:
- 禁用
gather_facts: true(尤其对老旧网络设备),改用setup模块按需获取default_ipv4和interfaces,减少初始化开销 - 对不支持
ip route的系统(如部分 CentOS 6 或定制嵌入式 Linux),fallback 到shell模块 +command,并用register捕获输出做failed_when判断 - 所有路由操作加
become: true,且确保目标节点/etc/sudoers允许ip route无密码执行(如%wheel ALL=(ALL) NOPASSWD: /sbin/ip route) - 割接窗口内禁止并发执行——用
serial: 1或按区域分批次(serial: "north_china,east_china,south_china")控制节奏


















