ansible通过.retry文件精准续做失败节点,结合--start-at-task跳过已成功任务,并依赖幂等模块、异步控制、预检机制实现网络闪断下的可靠重试。

Ansible 本身不支持传输层断点续传,但面对目标机网络闪断导致的半途失败,完全重跑不仅低效,还可能破坏已生效的中间状态。关键不是“恢复传输”,而是“精准续做”——利用其幂等性设计和失败标记机制,让重试只聚焦于真正未完成或失败的部分。
用.retry文件快速定位并重试失败节点
Ansible 执行失败后,会在当前目录自动生成 playbook.retry 文件,里面明确记录了哪些主机、哪些任务失败了。这不是日志,而是可直接复用的执行指令。
- 直接运行 ansible-playbook playbook.yml --limit @playbook.retry,就只会对失败主机重试,跳过所有已成功节点
- 如果失败发生在中间某个任务(比如第5个task),该命令默认从头开始重试这台机上整个play;若想更精确,可加 --start-at-task "任务名称" 跳过前面已确认成功的步骤
- 注意:.retry 文件只包含主机名,不记录具体失败任务序号,所以配合 --start-at-task 使用才最稳妥
确保每个任务都具备幂等性,避免重复操作副作用
网络闪断后重试,最怕的是“安装包又装一遍”“服务又启一次”“配置又被覆盖”。Ansible 的幂等性不是自动生效的,它依赖你选用的模块和写法是否真正支持状态判断。
- 用 apt / yum / dnf 模块时,state: present 或 latest 是幂等的;但用 command 执行 shell 命令(如 curl 下载)则不是,需自行加条件判断或改用 get_url 模块
- 部署配置文件优先用 template 或 copy 模块,并设置 backup: yes,这样即使重跑也能保留上一版供比对
- 启动服务务必用 service 或 systemd 模块,而非 command systemctl start,前者会检查服务当前状态再决定是否操作
对长耗时或易中断任务主动加异步与重试控制
像模型下载、大文件同步、数据库初始化这类任务,本身容错率低、耗时长,网络闪断极易卡住。不能只靠.retry被动补救,要提前加固。
- 用 async + poll 启动长时间任务,例如 async: 3600 poll: 10,表示最多等1小时,每10秒查一次状态,避免被SSH超时强行中断
- 对关键模块(如 uri 下载、synchronize 同步)显式设置 retries 和 delay,比如 retries: 3 delay: 10,让模块自身具备重试能力
- 大文件传输优先用 synchronize(底层是 rsync),它天然支持断点续传;避免全量 copy,尤其在不稳定链路上
部署前做轻量预检,减少中途失败概率
很多闪断问题其实暴露在更早阶段:磁盘满、内存不足、SSH连接数超限、目标端rsync未安装……这些都会让Ansible在执行中突然报错,看起来像网络问题。
- 在正式play前加一个预检play,用 setup 模块收集 facts,再用 assert 检查关键指标(如 ansible_memfree_mb > 2048, ansible_facts['mounts'] | selectattr('size_available', '>', 1073741824) | list | length > 0)
- 用 wait_for_connection 确保目标机SSH已就绪再继续,避免因重启或负载高导致连接拒绝
- 批量部署前先对 inventory 做 ping 测试:ansible all -m ping -f 20,并发20路快速筛出连通异常节点,提前剔除或修复











