serial控制每批执行主机数,max_fail_percentage设定单批失败容忍阈值;两者配合实现滚动部署中进度可控与故障熔断,如serial:"20%"且max_fail_percentage:30时,每批处理20%主机,任一批失败超30%即中止。

用 serial 控制批次节奏,用 max_fail_percentage 设定失败容忍线,两者配合就能在滚动部署中兼顾进度可控与故障熔断——不是等全崩了才停,而是刚超出安全阈值就中止。
serial 控制每次操作多少台机器
默认 Ansible 会一次性对所有目标主机执行任务,这在更新线上服务时风险极高。serial 让你把大批次拆成小窗口:
- 写成 serial: 3:每次只操作 3 台,等它们全部完成当前 play,再轮到下 3 台
- 写成 serial: "20%":100 台主机就分 5 批,每批 20 台
- 写成 serial: [1, 5, "50%"]:第一批 1 台,第二批 5 台,剩余的按 50% 比例分批(比如剩 94 台,就每批 47 台)
关键是它作用于整个 play,不是单个 task。一批内的所有主机必须把该 play 的全部 tasks 都跑完,才会进入下一批。
max_fail_percentage 在批次内设“熔断线”
serial 只管分批,不管这批里挂了几台。max_fail_percentage 就是补上这道防线:
- 设为 max_fail_percentage: 25:表示同一批里,只要失败主机数超过 25%,整个 playbook 立即中止,不再继续后续批次
- 注意:它是按“当前批次”算的百分比,不是全局比例。比如 batch 是 4 台,25% 就是 1 台;若第 1 台就失败,还没到 1 台阈值,继续;若前 2 台都失败(2/4 = 50% > 25%),立刻停
- 不设该参数时,Ansible 默认容忍 100% 失败——哪怕整批全挂,它也会硬着头皮试下一批
典型滚动更新 playbook 片段
以下是一个带负载均衡摘除、应用更新、健康检查、再加回的简化结构,重点体现两个参数协作:
---
- name: Rolling update for web tier
hosts: webservers
serial: "20%"
max_fail_percentage: 30
become: yes
gather_facts: false
<p>pre_tasks:</p><ul><li>name: Drain node from LB
community.aws.elb_target_group:
target_group_arn: "{{ lb_target_group_arn }}"
targets:<ul><li>id: "{{ ansible_host }}"
state: absent</li></ul></li></ul><p>tasks:</p><ul><li>name: Deploy new app package
ansible.builtin.copy:
src: ./app-v2.5.tar.gz
dest: /opt/app/current.tar.gz</li><li>name: Extract and restart service
ansible.builtin.shell: |
tar -xzf /opt/app/current.tar.gz -C /opt/app/
systemctl restart app.service
args:
executable: /bin/bash</li></ul><p>post_tasks:</p><ul><li>name: Wait for health check
ansible.builtin.uri:
url: "http://{{ ansible_host }}:8080/health"
status_code: 200
register: health
until: health.status == 200
retries: 6
delay: 10</li><li>name: Register node back to LB
community.aws.elb_target_group:
target_group_arn: "{{ lb_target_group_arn }}"
targets:<ul><li>id: "{{ ansible_host }}"
state: present
这个配置意味着:每批最多处理 20% 的服务器;若某批中超过 30% 的机器在 deploy 或 health check 阶段失败(比如 5 台里挂掉 2 台),Ansible 不会进入下一批,而是直接报错退出,避免错误扩散。
和 ignore_errors、failed_when 的区别与配合
max_fail_percentage 是宏观熔断,作用于主机维度;ignore_errors 和 failed_when 是微观控制,作用于单个 task:
- ignore_errors: yes 让某个 task 即使报错也往下走,适合非关键步骤(如清理日志)
- failed_when 可以自定义什么算失败,比如命令返回码是 0/1 不够准,你可能要判断输出是否含 “ERROR” 字符串
- 但这两者不会影响 max_fail_percentage 的统计——只要 task 最终状态是 failed,就算作该主机失败一次
- 所以常见组合是:对探活、回滚类 task 用 failed_when 精准判错;对整批稳定性用 max_fail_percentage 守住底线


















