傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的生命被剥夺了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是比死亡更可怕的事。--------王小波
通常,当Ansible运行play时,它会确保所有受管主机在启动任何主机进行下一个任务之前已完成每个任务。在所有受管主机完成所有任务后,运行通知的 handles
程序。
在所有主机上运行所有任务可能会导致意外行为。例如,在更新 Web 负载均衡器,如果同时更新所有Web服务器、可能会导致所有Web服务器停眼务。
Ansible支持滚动更新-一将一大批主机分批次更新,这样的好处:
所以一般建议在更新的剧本中配置:
默认情况下,Ansible会在开始执行下一个任务之前,需要对Play中所有主机完成前一个任务。如果某一任务失败,则所有主机将只有一部分通过该任务。意味着任何主机都无法正常工作,可能会导致中断
。理想情况下,在启动下一批主机之前,需要全部成功通过Play,如果有太多主机失败,则可以中止整个Play。
在Play 中使用 serial
关键字来指定每个批处理中应当有多少个主机。
在开始下一批主机之前,Ansible 将全程通过Play处理每一批主机,如果当前批处理中的所有主机都失败,则整个Play 将中止,且 Ansible 不会启动下一批次处理。
[student@workstation task-execution]$ cat serial.yaml
---
- name: 滚动更新
hosts: all
serial: 2
tasks:
- name: update web
shell: sleep 2
[student@workstation task-execution]$ ansible-playbook serial.yaml
PLAY [滚动更新] **************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************
ok: [servera]
ok: [serverb]
TASK [update web] ********************************************************************************************
changed: [servera]
changed: [serverb]
PLAY [滚动更新] **************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************
ok: [serverd]
ok: [serverc]
TASK [update web] ********************************************************************************************
changed: [serverc]
changed: [serverd]
PLAY [滚动更新] **************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************
ok: [servere]
ok: [serverf]
TASK [update web] ********************************************************************************************
changed: [servere]
changed: [serverf]
PLAY RECAP ***************************************************************************************************
servera : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverb : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverc : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverd : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
servere : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverf : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
在上面示例中,serial 关键字指定Ansible在两个主机的批处理中处理 web_servers 主机组中的主机。如果play正常执行且没有错误,则使用新的批处理再次重复该 play。
如果play中的主机总数不能被批处理大小整除,则最后一个批处理包含的主机可能比serial 关键字的指定值更少。serial关键字中使用整数。
还可以为 serial 关键字设置为百分比:
[student@workstation task-execution]$ cat serial.yaml
---
- name: 滚动更新
hosts: all
serial: 25%
tasks:
- name: update web
shell: sleep 2
[student@workstation task-execution]$ ansible-playbook serial.yaml
PLAY [滚动更新] **************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************
ok: [servera]
TASK [update web] ********************************************************************************************
changed: [servera]
PLAY [滚动更新] **************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************
ok: [serverb]
TASK [update web] ********************************************************************************************
changed: [serverb]
PLAY [滚动更新] **************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************
ok: [serverc]
TASK [update web] ********************************************************************************************
changed: [serverc]
PLAY [滚动更新] **************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************
ok: [serverd]
TASK [update web] ********************************************************************************************
changed: [serverd]
PLAY [滚动更新] **************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************
ok: [servere]
TASK [update web] ********************************************************************************************
changed: [servere]
PLAY [滚动更新] **************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************
ok: [serverf]
TASK [update web] ********************************************************************************************
changed: [serverf]
PLAY RECAP ***************************************************************************************************
servera : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverb : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverc : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverd : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
servere : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverf : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[student@workstation task-execution]$
[student@workstation task-execution]$ cat serial.yaml
---
- name: 滚动更新
hosts: all
serial:
- 25%
- 3
- 100%
tasks:
- name: update web
shell: sleep 2
[student@workstation task-execution]$
[student@workstation task-execution]$ vim serial.yaml
[student@workstation task-execution]$ ansible-playbook serial.yaml
PLAY [滚动更新] **************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************
ok: [servera]
TASK [update web] ********************************************************************************************
changed: [servera]
PLAY [滚动更新] **************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************
ok: [serverc]
ok: [serverb]
ok: [serverd]
TASK [update web] ********************************************************************************************
changed: [serverb]
changed: [serverc]
changed: [serverd]
PLAY [滚动更新] **************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************
ok: [servere]
ok: [serverf]
TASK [update web] ********************************************************************************************
changed: [servere]
changed: [serverf]
PLAY RECAP ***************************************************************************************************
servera : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverb : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverc : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverd : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
servere : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
serverf : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
中止Play
默认情况下,Ansible尝试获取尽可能多的主机来完成play。如果某一任务对于某一主机失败,则它将从play中丢弃,但Ansible 将继续为其他主机运行play中剩余的任务。仅当所有主机都失败时,play才会停止。
但是,如果使用 serial 关键字将主机组织到批处理中,那么如果当前批处理中的所有主机都失败,则Ansible将停止所有剩余主机的 play,而不仅仅是当前批处理中剩余的主机。如果由于批处理中的所有主机失败而停止了该play的执行,则下一个批处理将不会启动。
Ansible的ansible_play_batch变量中的每个批处理保留活动服务器列表。任何有任务失败的主机都将从ansible play batch 列表中删除。Ansible会在每项任务后更新此列表。
这里可以通过 指定容错
的方式来提前终止剧本。通过将 max_fail_percentage
关键字添加到剧本 ,改变 Ansible 的失败行为
- name: 滚动更新
hosts: all
max_fail_percentage: 30%
serial:
- 25%
- 3
- 100%
tasks:
- name: update web
shell: sleep 2
上面的配置,即所有机器里 30%
的机器执行 tasks 任务失败,那个会提前终止 剧本。
《Red Hat Ansible Engine 2.8 DO447》