ansible 优化
ansible 好用是真的好用,但慢也是真的慢,最近一个新的需求,需要在节点上移除 10 个文件夹,再创建 10 个文件夹。可以通过 file 模块指定 state 为 absent 或 directory 来实现,但是速度是真的慢,从系统本身执行来说,创建文件夹不需要花费多少时间,就有了调优的想法。
下面用到了一个计时的 ansible 插件:ansible-profile。就一个 python 文件,使用方法就是将 callback_plugins 置于 playbook 文件所在的目录下即可。
测试用的 playbook 很简单,就是对集群节点机器(20台)创建 13 个目录,再移除 13个目录。
# test.yml
---
- hosts: all
remote_user: test
gather_facts: True
tasks:
- name: create temp
file:
path: /root/tmp/
state: directory
with_items:
- "01"
- "02"
- "03"
- "04"
- "05"
- "06"
- "07"
- "08"
- "09"
- "10"
- "11"
- "12"
- "13"
- name: remove temp
file:
path: /root/tmp/
state: absent
with_items:
- "01"
- "02"
- "03"
- "04"
- "05"
- "06"
- "07"
- "08"
- "09"
- "10"
- "11"
- "12"
- "13"
下面的调优主要会对两个文件进行更改,下面是这两个文件的原始状态。
# ~/.ssh/config
# ~/deploy/ansible.cfg
[defaults]
deprecation_warnings=False
remote_user = firefly
host_key_checking = False
private_key_file = ssh_keys/id_rsa_common
ansible_python_interpreter=/usr/bin/python3
vault_password_file = ./vault.pass
[ssh_connection]
scp_if_ssh = True
control_path = ./ssh_keys
开始默认速度测试
什么都不更改的情况下进行测试。
create temp ----- 287.01s
remove temp ----- 285.97s
Gathering Facts ----- 33.01s
更改 ssh 相关配置
SSH pipelining
SSH pipelining 是一个加速 Ansible 执行速度的简单方法。ssh pipelining 默认是关闭,之所以默认关闭是为了兼容不同的 sudo 配置,主要是 requiretty 选项。如果不使用 sudo,建议开启。打开此选项可以减少 ansible 执行没有传输时 ssh 在被控机器上执行任务的连接数。不过,如果使用 sudo,必须关闭 requiretty 选项。修改 ansible.cfg 文件可以开启 pipelining。
# ~/deploy/ansible.cfg
[defaults]
deprecation_warnings=False
remote_user = firefly
host_key_checking = False
private_key_file = ssh_keys/id_rsa_common
ansible_python_interpreter=/usr/bin/python3
vault_password_file = ./vault.pass
[ssh_connection]
scp_if_ssh = True
control_path = ./ssh_keys
pipelining = True
create temp ----- 54.42s
remove temp ----- 53.46s
Gathering Facts ----- 15.94s
优化 ssh 配置里的 ControlPersist
ControlPersist 特性需要高版本的 SSH 才支持,CentOS 6 默认是不支持的,如果需要使用,需要自行升级 openssh。ControlPersist 即持久化 socket,一次验证,多次通信。并且只需要修改 ssh 客户端就行,也就是 Ansible 机器即可。
设置 ControlPersist 为 20 分钟。
# ~/.ssh/config
Host *
Compression yes
ServerAliveInterval 60
ServerAliveCountMax 5
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 20m
remove temp -------- 288.49s
create temp -------- 286.35s
Gathering Facts ----- 33.20s
使用 Mitogen Plugin
这个插件在这次测试中给了我惊喜。
它通过高效的远程过程调用来取代ansible默认的嵌入式与纯python shell调用,它不会优化模块本身的执行效率,只会尽可能快的②去执行模块获取返回(执行模块前也是有一系列连接,发送数据,传输渲染脚本等操作的)来提高整体的效率)。安装方式和配置也比较简单,可以参考:Mitogen for Ansible。
# mitogen_linear
Gathering Facts ----- 10.60s
create temp ----- 1.97s
remove temp ----- 1.76s
# mitogen_free
Gathering Facts --- 0.78s
create temp --- 0.68s
remove temp --- 0.68s
# mitogen_host_pinned
Gathering Facts --- 0.48s
create temp --- 0.53s
remove temp --- 0.43s
在这个测试中,没有牵扯到大量数据的传输,所以 SSH ControlPersist 的优化没有体现得出。目前使用这三个优化方案足以。再加上执行 playbook 过程中通过 -f num
指定 fork 数提升性能。
# -f 30
Gathering Facts ----- 2.26s
remove temp ----- 0.42s
create temp ----- 0.12s
至此,优化了 261818 %。如果在复杂的情况下能优化 1000 % 以上就很满足了。