Ansible 性能优化
在使用 Ansible 过程中,当管理的服务器数量增加,就会有一个无法避免的问题–执行效率慢。下面是一些解决方法
优化前的准备–收集数据
在做性能优化之前首先要收集一些统计数据,这样才能为后面的性能优化提供数据支持,对比优化前后结果,这里推荐一个 Ansible 任务计时插件 ansible-profile
, 安装这个插件之后, 会显示 ansible-playbook 执行每个任务话费的时间。项目地址: http://github.com/jlafon/ansible-profile 。
先在执行 ansible-playbook 既可以看到每个 tasks 的用时情况。
关闭 gathering facts
在执行 ansible-playbook 的过程中,ansible-playbook 第一步骤总是执行 gather_facts,不论你是否在 playbook 中定义这个 tasks。如果执行 playbook 不需要 fact 的数据,可以关闭 fact 数据功能,以加快 ansible-playbook 的执行速度。
关闭执行继续执行上面的 playbook,效果十分明显
SSH PIPElinING
SSH PIPElinING 是一个加速 Ansible 执行速度的简单方法。SSH PIPElinING 默认是关闭的,因为要兼容不同的 sudo 配置,主要是 requiretty 选项。如果不适用 sudo 建议开启。打开此选项可以减少 ansible 执行没有传输时 ssh 在被控机器上执行任务的连接数,如果使用 sudo,必须关闭 requiretty 选项, 修改 /etc/ansible/ansible.cfg
开启 pipelineing
ControlPersist
ControlPersist 特性需要高版本的 SSH 才支持,CentOS 6 默认是不支持的,如果需要使用,需要自行升级 openssh。ControlPersist 即持久化 socket,一次验证,多次通信。并且只需要修改 ssh 客户端就行,也就是 Ansible 机器即可。
升级 openssh 的过程这里不做介绍。这里只介绍下 ControlPersist 设置的办法。
在开启了 ControlPersist 特性后,SSH 在建立了 sockets 之后,节省了每次验证和创建的时间。在网络状况不是特别理想,尤其是跨互联网的情况下,所带来的性能提升是非常可观的。有这边需求的,试试就知道了。
ansible-playbook 技巧
获取命令行输出
在使用 ansible-playbook 中,当使用 common 或者 shell 模块执行自定义脚本,这些脚本都会有输出,用来表示执行正常或者是失败,在 ansible-playbook 中, 可以使用 register 来存储执行命令输出结果,将结果保存到变量中,在通过访问这个变量来获取输出结果。
delegate_to 任务委派
当要在 A 组服务器上执行 playbook 时,需要同时在另外一个不在 A 组的 B 服务器上执行另外操作,这里就可以使用 delegate_to 功能,用来委派任务给 B 服务器。
本地操作功能
ansible 默认只会对定义好的被控机执行命令,如果要在本地也执行操作,可以使用 delegate_to 功能,当然还有另外一种更好的方式:local_action
check 模式
使用 check 参数运行 ansible-playbook时,不会对远端主机做任何操作,并带有检测功能,报告 playbook 会对主机做出什么操作。如果 playbook 中带有执行条件,检查就会出错了。
使用 tag 来选择性执行
可能由于某些原因, 在一个大型的 playbook 中,只想执行其中的特定部分,这样就会用到 tag 功能。
如果你只想运行 playbook 中的 configuration
和 packages
,你可以这样做
错误处理
ansible 默认会检查命令和模块的返回状态,并进行相应的错误处理,默认遇到错误就会中断执行 playbook,当然这些是可以更改的
- 忽略错误
common 和 shell 模块执行的命令如果返回非零的状态码则 ansible 判断模块执行失败,通过 ignore_errors
忽略返回码
- 自定义错误判定条件
命令不依赖返回状态码来判定是否执行失败,而是要查看命令返回内容来决定,比如返回内容中包括 failed 字符串,则判定为失败。示例如下:
ansible 会自动判断模块执行状态,command、shell 及其它模块如果修改了远程主机状态则被判定为 change 状态,不过也可以自己决定达到 changed 状态的条件,示例如下:
命令返回中有“successful”字符串,则为 changed 状态,下面这个设定将永远也不会达到 changed 状态。