失败之后走向哪里
默认行为是:某台主机的任务失败,该主机在本 play 内不再执行后续任务,其他主机照常推进。多数批量运维场景这是合适的——个别机器失败不该停住整批。但有些变更必须“要么全做要么不做”,那就需要把范围放大或收窄:按批次数控制失败比例、按整批停机、或对个别任务容忍错误继续走。
基本信息
| 默认行为 | 失败主机移出当前 play 的后续任务,其它主机继续 |
|---|---|
| 单任务容忍 | 忽略错误让该任务失败后继续,但主机仍被标记为失败状态 |
| 整批停机 | 任一主机失败即中止整次运行,用于强一致场景 |
| 比例控制 | 与滚动批次配合,单批失败比例超过阈值即停止扩散 |
| 处理器补救 | 可选地让失败时仍触发已排队的处理器,用于收敛状态 |
| 重试收敛 | 执行会生成失败主机清单,可只对它们重跑 |
典型使用场景
- 日常批量变更:个别失败不影响其它主机,事后按失败清单单独处理
- 强一致变更:数据库迁移、证书轮换要求任一失败即全停
- 灰度放量:批次失败超过阈值停止继续传播
- 可容忍步骤:可选依赖安装失败只记录不阻塞主流程
- 失败后仍需收敛:即使失败也要把已改动的服务重载到一致状态
- 重试收敛:只对失败主机重跑,避免成功部分被重复执行
策略写法
策略写法
- hosts: web
serial: 5 # 每批 5 台
max_fail_percentage: 20 # 单批失败超过两成即停止扩散
any_errors_fatal: false # 个别失败不中止整次运行
tasks:
- name: 必做步骤
ansible.builtin.package:
name: app-server
state: present
- name: 可选步骤,失败也继续(会标记为失败状态)
ansible.builtin.command: /usr/local/bin/install-optional-addon.sh
ignore_errors: true
changed_when: false
- hosts: db
any_errors_fatal: true # 强一致场景:任一主机失败立即整体停止
force_handlers: true # 失败时仍触发已排队的处理器,避免状态不一致
tasks:
- name: 迁移
ansible.builtin.command: /usr/local/bin/migrate.sh
changed_when: true
# 执行后只对失败主机重跑:
# ansible-playbook -i inventory site.yml --limit @site.retry手段与适用
| 手段 | 效果 | 代价 |
|---|---|---|
| 默认行为 | 个别失败不阻塞其它主机 | 失败主机在本 play 内被跳过,容易被忽略 |
| 忽略错误 | 单任务失败后继续 | 主机仍标记失败,后续依赖会连锁失败 |
| 整批停机 | 任一失败立即停止 | 其余主机不做任何变更,适合强一致场景 |
| 失败比例阈值 | 按批次控制扩散范围 | 需要合理设定批次大小 |
| 失败时仍触发处理器 | 把已改动部分收敛到一致状态 | 可能触发额外动作,需确认副作用 |
| 只重跑失败主机 | 快速收敛 | 跳过的成功部分与重跑部分需确认状态一致 |
“个别失败不停整批”的模式下,成败判断必须看最终统计:返回非零即代表有主机失败,而它未必出现在最后几行输出里。把执行结果统计与失败主机清单纳入流程记录,才不会漏掉失败。
忽略错误继续执行,让失败不再中断流程,但后续任务可能基于未完成的前提运行,产生难以解释的连锁故障。使用时应同时安排结果检查与显式中止,而不是让流程一路走到底。
怎么选策略
判断标准是“允许部分成功吗”:允许就保持默认行为并配合失败清单重跑;不允许部分成功就用整批停机或失败比例阈值。再叠加一条纪律:无论哪种策略,执行结束都要显式检查失败主机数量,把结果当作流程的一部分,而不是依赖人工看输出。