DO447管理任务执行–控制任务执行
RHCSA专栏:戏说 RHCSA 认证
RHCE专栏:戏说 RHCE 认证
此文章(第三章 管理任务执行–控制任务执行 )收录在RHCA专栏:RHCA 回忆录
📜2.1 执行的控制次序
在一个play中,Ansible总是在你在tasks部分下定义的任务之前,从角色中运行任务(由角色调用)。下面的剧本包含一个角色和一个任务部分。
当运行这个剧本时,Ansible会在打开防火墙任务之前执行角色中的任务,即使任务部分是先定义的:
为了便于阅读,在角色部分之后编写任务部分是一种很好的做法,这样剧本的顺序就会与执行的顺序相匹配。
💡注意:这个顺序来自于这样一个事实:剧本中列出的每个剧本都是一个键-值对的YAML字典。因此,顶级指令(名称、主机、任务、角色等)的顺序实际上是任意的,但Ansible在解析和运行play时以标准化的顺序处理它们。
从剧名开始以一致的顺序写剧本是一种最佳实践,但Ansible实际上并不要求这样做。然而,背离这种惯例会使你更难阅读剧本,因此不推荐。
📑任务中使用角色导入或包含
Ansible的最新版本允许将角色作为任务包含或导入,而不是使用play的角色部分。这种方法的优点是,您可以轻松地运行一组任务、导入或包含角色,然后运行更多任务。一个潜在的缺点是,在没有仔细检查的情况下,你可能不太清楚你的剧本使用的是哪些角色。
使用include_role模块动态地包含角色,使用import_role模块静态地导入角色。
使用import_role, ansible-playbook命令首先解析并在开始执行之前将角色插入到剧本中。Ansible会立即检测并报告语法错误,并且不会启动playbook的执行。
然而,使用include_role, Ansible在play执行期间,当角色到达include_role任务时,解析并将角色插入到play中。如果Ansible检测到角色中的语法错误,则剧本的执行将中止。
然而,when指令的行为有所不同。对于include_role任务,如果when指令中的条件为false, Ansible不会解析该角色。
📑定义前期和后期任务
您可能想要在您的角色之前运行一些任务和它们通知的处理程序。您可能还想在运行正常任务和处理程序后在play中运行任务。有两个指令可以代替task来完成这个任务:
-
pre_tasks是在roles部分之前运行的tasks部分。
-
post_tasks是一个在tasks部分和tasks通知的任何处理程序之后运行的任务部分。
下面的剧本提供了一个带有pre_tasks、roles、tasks、post_tasks和handlers部分的示例。一个剧本包含所有这些部分是不寻常的。
📑复审执行顺序
Ansible按以下顺序运行play部分:
-
pre_tasks
-
pre_tasks部分中通知的处理程序
-
角色
-
任务
-
角色和任务部分中通知的处理程序
-
post_tasks
-
post_tasks部分中通知的处理程序
如上所述,剧本中这些章节的顺序并不会改变执行的顺序。例如,如果你把tasks部分写在roles部分之前,Ansible仍然在tasks部分的tasks之前执行角色。不过,为了提高可读性,最好按照执行顺序组织剧本:pre_tasks、roles、tasks和post_tasks。处理程序通常在最后。
在运行过程中,Ansible会在以下几个点执行并刷新被通知的处理程序:在pre_tasks节之后,在roles和tasks节之后,以及在post_tasks节之后。这意味着如果在多个区段中得到通知,处理器可以在剧本执行期间的不同时间运行不止一次。
要立即运行在play中被特定任务通知的任何处理程序,添加一个使用带有flush_handlers参数的元模块的任务。这允许您在所有被通知的处理程序运行时定义任务执行期间的特定点。
在下面的示例中,如果收到通知,play将在部署新配置文件之后和使用应用程序api之前执行Restart api服务器处理程序。如果没有对元模块的调用,play只会在运行所有任务后调用处理程序。如果在最后一个使用APl的任务执行之前没有运行处理程序,那么该任务可能会失败,因为配置文件已经更新,但应用程序还没有重新读取新的配置。
记住,在play中,处理程序具有全局作用域。play可以通知在role中定义的处理程序。一个角色可以通知另一个角色或play定义的处理程序。
Ansible总是按照在handler部分列出的顺序运行被通知的处理程序,而不是按照它们被通知的顺序。
📜2.2 侦听处理程序
除了由任务发出通知外,处理程序还可以“订阅”特定通知,并在该通知被分成三部分时运行。这允许一个通知触发多个处理程序。
默认情况下,当通知字符串与处理程序名匹配时,处理程序就会执行。但是,由于每个处理程序必须有一个惟一的名称,因此同时触发多个处理程序的唯一方法是每个处理程序订阅相同的通知名称。
下面的例子展示了一个任务,当它发生变化时通知My handlers,也就是当它运行时,因为它已经设置了changed_when: true。任何名为My handlers的处理器,或者在listen指令中列出My handlers,都会被通知。
💡注意:在前面的剧本中,如果两个处理程序都有唯一的名称(不是My handlers)并使用listen: My handlers会更好,因为剧本更容易阅读。
listen指令在与角色一起使用时特别有用。角色使用通知来触发它们的处理程序。角色可以记录当事件发生时它将通知某个处理程序。其他角色或剧本可以使用此通知来运行在角色之外定义的其他处理程序。
例如,当服务需要重新启动时,角色可以通知其处理程序之一。在您的剧本中,您可以定义一个处理程序来监听该通知,并在Ansible重新启动服务时执行额外的任务,例如向监视工具发送消息,或重新启动依赖的服务。
例如,您可以创建一个角色,该角色检查给定SSL证书的有效性,并在证书过期时通知处理程序更新证书。在剧本中,您可以调用此角色来检查您的Apache HTTP服务器证书的有效性,并创建一个处理程序,如果该角色更新了证书,该处理程序将侦听该通知以重新启动httpd服务。
📑处理程序通知的方法
总之,一个任务至少可以通过两种方式通知多个处理程序:
-
它可以按名称单独通知一组处理程序。
-
它可以通知一个被配置为侦听的多个处理程序的名称。
哪种方法更好?如果处理程序被多个任务作为一个集合重用,那么配置剧本的最简单方法是使用第二种方法和listen指令。然后,您只需要更改处理程序来标记它们是否包含在集合中,并确保它们以正确的顺序列出。
当一个任务需要通知许多处理程序时,这种方法非常有用。任务只发送一个通知,而不是通过名称通知每个处理程序。Ansible触发所有监听该通知的处理程序。这样,您就可以在不更新任务的情况下添加或删除处理程序。
在第一种方法中,您必须找到并编辑每个受影响的任务,以便向列表中添加处理程序。您还必须确保处理程序在处理程序部分中以正确的顺序列出。
📜2.3 控制主机执行的顺序
Ansible根据剧本的hosts指令确定要管理哪个主机。默认情况下,Ansible 2.4及以后版本会按照主机在清单中列出的顺序运行。您可以使用order指令在详细情况下更改该订单。
下面的剧本在运行任务之前按字母顺序对web_servers组中的主机进行排序:
order指令接受以下值:
-
inventory:清单order。这是默认值。
-
reverse_inventory:清单orde的倒序。
-
sorted:主机按字母顺序排列。数字排在字母之前。
-
reverse_sorted:主机按字母顺序倒序排列。
-
shuffle:每次运行play时都是随机顺序。
💡注意:由于Ansible通常在多个主机上并行运行每个任务,因此Ansible -playbook命令的输出可能不会反映预期的顺序;输出显示的是任务完成顺序,而不是执行顺序。
📜2.4 课本练习
[student@workstation ~]$ lab task-execution start
📑按要求编写任务执行顺序
[student@workstation ~]$ cd ~/DO447/labs/task-execution
[student@workstation task-execution]$ cat deploy_haproxy.yml
- name: Ensure HAProxy is deployed
hosts: lb_servers
force_handlers: True
roles:
# The "haproxy" role has a dependency on the "firewall" role.
# The "firewall" role requires a "firewall_rules" variable be defined.
- role: haproxy
[student@workstation task-execution]$ vim deploy_haproxy.yml
- name: Ensure HAProxy is deployed
hosts: lb_servers
force_handlers: True
pre_tasks:
- name: Setting the maintenance message
copy:
dest: /etc/motd.d/maintenance
content: "Maintenance in progress\n"
roles:
# The "haproxy" role has a dependency on the "firewall" role.
# The "firewall" role requires a "firewall_rules" variable be defined.
- role: haproxy
post_tasks:
- name: Removing the maintenance message
file:
path: /etc/motd.d/maintenance
state: absent
📑明确处理程序并进行编写
[student@workstation task-execution]$ cat roles/haproxy/handlers/main.yml
---
# handlers file for haproxy
- name: restart haproxy
service:
name: haproxy
state: restarted
- name: reload haproxy
service:
name: haproxy
state: reloaded
[student@workstation task-execution]$ vim deploy_haproxy.yml
…………
post_tasks:
- name: Removing the maintenance message
file:
path: /etc/motd.d/maintenance
state: absent
handlers:
- name: Sending an email to student
mail:
subject: "HAProxy reloaded on {
{ inventory_hostname }}"
to: student@workstation.lab.example.com
delegate_to: localhost
become: false
listen: reload haproxy
- name: Logging a message to syslog
syslogger:
msg: "HAProxy reloaded on {
{ inventory_hostname }}"
delegate_to: localhost
become: false
listen: reload haproxy
📑执行并验证
[student@workstation task-execution]$ ansible-playbook deploy_haproxy.yml
[student@workstation task-execution]$ mail
Heirloom Mail version 12.5 7/5/10. Type ? for help.
"/var/spool/mail/student": 1 message 1 new
>N 1 root@workstation.lab Tue Apr 20 17:53 27/1102 "HAProxy reloaded on servera.lab.example.com"
[student@workstation task-execution]$ sudo grep "HAProxy reloaded" /var/log/messages
[sudo] password for student:
Apr 20 17:53:41 workstation platform-python[15805]: ansible-mail Invoked with subject=HAProxy reloaded on servera.lab.example.com to= host=localhost port=25 sender=root cc=[] bcc=[] attach=[] headers=[] charset=utf-8 subtype=plain secure=try timeout=20 username=None password=NOT_LOGGING_PARAMETER body=None
Apr 20 17:53:41 workstation platform-python[15827]: ansible-syslogger Invoked with msg=HAProxy reloaded on servera.lab.example.com priority=info facility=daemon log_pid=False
Apr 20 17:53:41 workstation ansible_syslogger[15827]: HAProxy reloaded on servera.lab.example.com
📑清除实验
[student@workstation task-execution]$ lab task-execution finish
💡总结
RHCA认证需要经历5门的学习与考试,还是需要花不少时间去学习与备考的,好好加油,可以噶🤪。
以上就是【金鱼哥】对 第三章 管理任务执行–控制任务执行 的简述和讲解。希望能对看到此文章的小伙伴有所帮助。
如果这篇【文章】有帮助到你,希望可以给【金鱼哥】点个赞👍,创作不易,相比官方的陈述,我更喜欢用【通俗易懂】的文笔去讲解每一个知识点,如果有对【运维技术】感兴趣,也欢迎关注❤️❤️❤️ 【金鱼哥】❤️❤️❤️,我将会给你带来巨大的【收获与惊喜】💕💕!