五、实施任务控制 161
1.循环(迭代)--- loop --item
1.利用loop----item循环迭代任务 with_*
通过循环管理员不需要编写多个使用同一模块的任务。例:他们不需要编写五个任务来确保存在五个用 户,而是只需要编写一个任务来对含有五个用户的列表迭代,从而确保他们都在。
ansible支持loop关键字对一组项目迭代任务,可以配置循环以利用各个项目、列表中各个文件的内容、 生成数字序列化或更为复杂的结构来重复任务。
1.2 item---loop循环案例
loop关键字添加到任务中,将应对其迭代任务的项目列表取为值。 循环item保存每个迭代过程中使用的 值。
2.when条件任务语法
when语句用于有条件运行任务。它取要测试的条件为值。如果条件满足,则运行任务。如果条件不满足 则跳过任务。
2.1 when条件测试案例
2.2 when条件表达语法
2.3 多条件表达and or语法
2.4 组合循环和有条件判断任务
对某类任务结合使用when和loop时,将对每项检查when语句
3.实施处理程序
3.1Handlers和notify触发条件
1. notify (通知)此action可用于每个play最后被触发这样避免多次发生改变时都执行指定操作,仅 在所有变化发生完成后一次性的执行操作。在notify中列出的操作作为handler及notify中调用 handlers中定义的操作。(notify判断是否有发生改变一旦发生改变触发handlers执行指定操作)
2. handlers (操作者)是task列表这些task和前述的task没有本质区别,用于当关注资源发生变化时 才会采取一定的操作。
3.2 tags标签定义
tags标签: 通过此标签来指定playbook文件执行哪条命令
4.处理任务失败
4.1 ignore_errors 忽略错误继续任务
默认情况下任务失败时play会终止。可以通过ingnore乎略失败,其他任务可以继续执行。
4.2 force_handlers: yes
如果任务失败并且play在该主机上终止,则收到play中早前任务通知的处理程序将不会运行。 force_handlers: yes 关键字,即使play因为后续任务失败而中止也会调用被通知的处理程序。
4.3 failed_when failed_when其实是ansible的一种错误处理机制,是由fail模块使用了when条件语句的组合效果。
4.4 change_when 满足条件输出change状态
当我们控制一些远程主机执行某些任务时,当任务在远程主机上成功执行,状态发生更改时,会返 回changed状态响应,状态未发生更改时,会返回OK状态响应,当任务被跳过时,会返回skipped状态 响应。我们可以通过changed_when来手动更改changed响应状态。
示例如下:
4.5 block、rescue、always块和错误处理
通过块,也可结合rescue和always语句来处理错误,如果块中的任何任务失败,则执行其rescue块中的 任务来进行恢复。在block子句中的任务以及rescue子句中的任务(如果出现故障)运行之后,always 子句中的任务运行。
总结:
block: 定义要运行的主要的任务。
rescue: 定义要在block子句中定义的任务失败时运行的任务。
always:定义始终都独立运行的任务,不论block和rescue子句中定义的任务是否成功还是失败。
例: 在playbook中实施块即使block子句中定义的任务失败,rescue和always子句中定义的任务也会执 行。
六、使用jinja2模板部署自定义文件
1.jinja2
在jinja2中,存在三种语法:
控制结构 {% %}
变量取值 {{ }}
注释{# #}
2.jinja2构建文件模板
文本文件,嵌套有脚本(使用模板编写语言编写)
管理文件的一种更强大的方法是为其构建模板。通过此方法,您可以使用ansible变量和事实便捷一个 模板配置文件,在部署该文件时自动为受管主机自定义此模板配置文件。这样更容易控制,也更不易出 错。
使用分隔符
变量和逻辑表达式至于标记或分隔符之间。例如,jinja2模板将{% EXPR %}用于表达式或逻辑(如循 环),而{{ EXPR }} 则用于向最终用户输出表达式或变量的结果。后一标记在呈现时将被替换为一个或 多个值,最终用户可见。使用 {# COMMENT #}语法括起来不应出现在最终文件中的注释。
在下例中第一行中含有不会包含于最终文件中的注释。第二行中引用的变量被替换为所引用的系统事实 的值。
2.1 template
template模块
template使用了Jinjia2格式作为文件模版,进行文档内变量的替换的模块。
模板文件结构
示例:制作hosts模板文件
七:项目管理
1.并行处理forks seria
1.1 Aniable运行play机制---forks
1)当Ansible处理playbook时,会按顺序运行每个play。确定play的主机列表之后,Ansible将按顺序运 行每个任务
2)通常,所有主机必须在任何主机在play中启动下一个任务之前成功完成任务
3) 注意: 理论上,Ansible可以同时连接到play中的所有主机以执行每项任务。这非常适用于小型主机列表。但 如果该play以数百台主机为目标,则可能会给控制节点带来沉重负担
4) Ansible所进行的最大同时连接数由Ansible配置文件中的forks参数控制,默认情况下设为 5(forks:分叉) 通过以下方式之一来验证:[root@localhost ~]# grep forks /etc/ansible/ansible.cfg #forks = 5
5) 例如,假设Ansible控制节点配置了5个forks的默认值,并且play具有10个受管主机。 Ansible将在前5个受管主机上执行play中的第一个任务,然后在其他5个受管主机上对第一个任务执行第 二轮。 在所有受管主机上执行第一个任务后,Ansible将继续一次在5受管主机的组中的所有受管主机上执行下 一个任务。Ansible将依次对每个任务执行此操作,直到play结束。
6)forks的默认值设置得非常保守。如果你的控制节点正在管理Linux主机,则大多数任务将在受管主机 上运行,并且控制节点的负载较少。在这种情况下,通常可以将forks的值设置得更高,可能接近100, 然后性能就会提高
7)如果playbook在控制节点上运行很多代码,则应明智地提高forks限值。如果使用Ansible管理网络路 由器和交换机,则大多数模块在控制节点上运行而不是在网络设备上运行。 由于这会增加控制节点上的负载,因此其支持forks数量增加的能力将显著低于仅管理Linux主机的控制 节点
8)可以从命令行覆盖Ansible配置文件中forks的默认设置。ansible和ansible-playbook命令均提供-f或- -forks选项以指定要使用的forks数量
1.2 serial--Ansible运行滚动机制
1)通常,当Ansible运行play时,匹配到的所有受管主机同时执行任务从上往下依次执行。
2)但是,在所有主机上运行所有任务可能会导致意外行为。 例如,如果play更新负载均衡Web服务器集群,则可能需要在进行更新时让每个Web服务器停止服务。 如果所有服务器都在同一个play中更新,则它们可能全部同时停止服务
3)避免此问题的一种方法是使用serial关键字,通过play批量运行主机。在下一批次启动之前,每批主 机将在整个play中运行。
4)演示实例:
在上面的示例中,Ansible一次在两个受管主机上执行play,直至所有受管主机都已更新
5)更新机制:
Ansible首先在前两个受管主机上执行play中的任务。如果这两个主机中的任何一个或两个都通知 了处理程序,则Ansible将根据这两个主机的需要运行处理程序。
在这两个受管主机上执行完play时,Ansible会在接下来的两个受管主机上重复该过程。Ansible继 续以这种方式运行play,直到所有受管主机都已更新
6)假设上一示例中的webservers组包含5个Web服务器,它们位于负载均衡器后面。将serial参数设置 为2后,play一次将运行两台Web服务器。因此,5台Web服务器中的大多数服务器将始终可用
相反,如果不使用serial关键字,将同时在5台Web服务器上执行play和生成的处理程序。这可能会 导致服务中断,因为Web服务将在所有Web服务器上同时重新启动
7)重要:
在设置了serial: 2 的上一个场景中,如果出现问题并且处理的前2个主机的play失败,则playbook将中 止,其余3个主机将不会通过play运行。这是一个有用的功能,因为只有一部分服务器不可用,使服务降级 而不是中断
2.playbook的文件导入
2.1管理大型的playbook
1)如果playbook很长或很复杂,我们可以将其分成较小的文件以便于管理
2)可采用模块化方式将多个playbook组合为一个主要playbook,或者将文件中的任务列表插入play import_playbook
2.2包含或导入任务文件
import_playbook示例
import_tasks
import_tasks(Static)方法会在playbooks解析阶段将父task变量和子task变量全部读取并加载 include_tasks(Dynamic)方法则是在执行play之前才会加载自己变量
import_tasks 调用的子任务文件名称也就不可以使用变量,但是 include_tasks 调用的子任务名称 则可以加变量。
import_tasks 会调用子任务中的所有 tags,使用 –list-tags 参数时也能看到,但是 include_tasks 调用的子任务中如果定义了tag,则不会生效。
八:利用角色简化playbook
1.Roles介绍
ansible自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动 装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用roles指令引入即可。角色 一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。主要使用场景代码复用 度较高的情况下。
默认情况下,ansible在ansible playbook所在目录的roles子目录中查找角色;如果默认路径下没有会按 照ansible.cfg文件中roles_path所指定的目录中查找。
1.ansible角色结构
2.创建并使用角色
3.使用本地系统角色
4.ansible-galaxy
使用ansible galaxy部署角色
1.介绍ansible galaxy
这个网站 Ansible Galaxy,是一个免费的用于查找,下载,评论各种社区开发的 Ansible 角色,在你的 自动化项目中引入一些角色也是不错的。Ansible Galaxy https://galaxy.ansible.com是一个Ansible内 容公共资源库,这些内容由许许多多Ansible管理员和用户编写。它包含数千个Ansible角色,具有可搜 索的数据库,可帮助Ansible用户确定或许有助于他们完成管理任务的角色。Ansible Galaxy含有面向新 的Ansible用户和角色开发人员的文档和视频链接。
此外,用于从Ansible Galaxy获取和管理角色的ansible-galaxy命令也可用于为您的项目获取和管理自有 的git存储库中的角色。
2 . Ansible Galaxy命令行工具,用户可以使用–author、–platforms和–galaxy-tags选项来缩小搜索结果 的范围。搜索到的都是可以用的。