Ansible自动化(十四) 分析Ansible任务执行的顺序
1 | 作者:李晓辉 |
角色任务优先
在 play 中,Ansible 总是先执行你在 roles 部分定义的任务,然后才会执行 tasks 部分中的任务。比如,以下这个 playbook,它既有 roles 部分,也有 tasks 部分。
1 |
|
运行这个 playbook 时,Ansible 会先执行 common 角色中的任务,然后才会执行 Open the firewall 这个任务,尽管 tasks 部分在 roles 部分之前定义。
为了让 playbook 看起来更有条理,最好把 tasks 部分放在 roles 部分之后,这样就能保证任务的顺序和执行顺序一致,既清晰又容易理解。
include 或 import 角色
include_role使⽤ 可以动态添加⻆⾊,使⽤ import_role 模块可静态导⼊⻆⾊
include_role和import_role是用于加载角色的两种方式,它们的主要区别在于加载的方式和执行的灵活性:
include_role(动态加载角色):角色是动态加载的,在任务运行时解析。
支持条件加载(如配合
when语句使用),可以根据不同条件选择性加载角色。每次执行时都重新解析,灵活性更强。
import_role(静态导入角色):角色是静态加载的,在Playbook解析时即完成导入。
不支持条件加载,所有导入的任务会始终运行。
执行效率略高,因为它在运行前已经完全解析。
1 |
|
Playbook解释如下:
任务的定义和顺序:
- 任务按照定义顺序依次执行。首先运行普通任务,然后动态加载
role2中的任务,最后再执行另一个普通任务。
- 任务按照定义顺序依次执行。首先运行普通任务,然后动态加载
动态包含角色:
- 使用
include_role将role2动态加载到Playbook执行中。这样,role2中的所有任务都会按照角色内部定义的顺序运行。
- 使用
结合普通任务运行:
- 动态加载的角色可以与普通任务无缝组合,使Playbook更灵活、模块化。
定义前期和后期任务
在Ansible的Playbook中,pre_tasks和post_tasks是用来定义在主任务(Tasks)运行之前或之后执行的任务的特殊部分:
pre_tasks(预任务):用于在正常任务(Tasks)执行之前运行的一组任务。
通常用于准备工作,如验证条件、设置变量、检查依赖等。
是Playbook中最先运行的部分,优先级高于普通任务。
post_tasks(后任务):用于在所有正常任务执行完之后运行的一组任务。
通常用于清理、日志记录或其他收尾操作。
是Playbook中最后运行的部分,在所有任务和处理器(Handlers)完成后才执行。
举例如下:
1 |
|
以上代码的解释如下:
pre_tasks(预任务):
首先执行pre_tasks部分的任务,用于在主任务执行前进行准备工作。在这里,它会执行:- 禁用Nagios的监控,避免在更新服务时触发错误报警。
roles(角色):
接下来,会运行roles部分中定义的角色任务。在这个Playbook中是deploy-content角色,该角色的任务按其内部逻辑依次执行。tasks(主任务):
完成角色任务后,进入主任务部分(tasks)。具体如下:重启memcached服务:触发
notify,通知处理程序。验证部署是否成功:通过访问应用的健康检查接口,确保新版本正常运行。
handlers(处理程序):
如果某些任务触发了处理程序(如notify指定的处理程序),在这里:- 通知支持团队,告知memcached服务已重启。
post_tasks(后任务):
在所有普通任务执行完毕后,post_tasks部分的任务会运行。这包括:- 重新启用Nagios监控,恢复对该主机的服务状态监控。
总结:任务按照pre_tasks → handlers(pre_tasks) → roles → tasks → handlers(role & tasks) → post_tasks → handlers(post_tasks)的顺序依次执行
最终的执⾏顺序
Ansible 按照以下顺序运⾏ play 的不同部分:
pre_tasks
pre_tasks 部分中通知的处理程序
roles
tasks
roles 和 tasks 部分中通知的处理程序
post_tasks
post_tasks 部分中通知的处理程序
Ansible 始终按照 play 的 handlers 部分中列出的顺序,⽽不是按照通知的顺序运⾏已通知的处理程序。
若要⽴即运⾏由 play 中特定任务通知的任何处理程序,可以添加⼀个使⽤ meta 模块及flush_handlers 参数的任务。
1 |
|
侦听处理程序
同时触发多个处理程序的唯⼀⽅式是每个处理程序都订阅相同的通知名称
下面的任务会通知 My handlers 处理程序,以及在 listen 指令中列出 My handlers 的任何处理程序
1 |
|
控制主机执⾏顺序
Ansible 会根据 play 中的 hosts 指令来确定要管理的主机。默认情况下,它会按照清单中列出的顺序依次为主机运行 play。但如果你想控制执行顺序,可以使用 order 指令来调整每个 play 的执行顺序。
以下 playbook 在运⾏任务前,按字⺟顺序对 web_servers 组中的主机进⾏排序:
1 |
|
order 指令接受以下值:
inventory
清单顺序。 此为默认值。reverse_inventory
清单的反序。sorted
按字⺟顺序排列主机。 数字排在字⺟之前。reverse_sorted
按字⺟倒序排列主机。shuffle
每次运⾏ play 时对主机列表随机排序。
