21. Ansible性能调优
简介
在当前配置管理工具大行其道的应用中,ansible凭借其轻量级、agentless等特性得以占据一席之地。然而其也并不是完美无缺,事实上,其最为人所诟病的就是在大规模服务器应用场景当中表现出的性能问题。所以本篇文档就来说一说如何通过一些配置优化来加速ansible的运行。
SSH Mulplexing
默认情况下,ansible基于ssh连接被控端,当ansible在运行playbook的时候,会建立很多的ssh连接来执行相应的task,而每个task都会创建一个新的ssh连接,ssh连接的建立毫无疑问需要额外tcp建立连接的开销。
openssh支持一个优化,叫做ssh mulplexing,也被称作ControlPersist。当启用了该特性,则多个连接到相同主机的ssh会话将会共享相同的tcp连接。这样就只有第一次连接的时候需要进行TCP三次握手。
当启用Mulplexing后:
开启该配置项:
#cat ansible.cfg #配置文件位置
[ssh_connection]
ssh_args = -C -o ControlMaster=auto -o ControlPersist=10m
配置项说明:
pipelining
在说明pipelining之前,需要先了解下ansible是如何执行一个task的:
上面三个步骤中,后面两个步骤会产生两个ssh会话。而在pipelinin模式下,ansible执行python脚本时并 不会复制它, 而是通过管道传递给ssh会话。这样一来,就会让原本需要的两个ssh会话减少为一个,以降低开销,节省时间。
启用pipelining:
#cat ansible.cfg
[defaults]
pipelining = True
需要注意的是,如果开启pipelining,则需要在被控端的/etc/sudoers文件中关闭requirey:
#cat /etc/sudoers.d/ansible
ansible ALL=(ALL) NOPASSWD:ALL #赋予root权限
Defaults:ansible !requiretty
并发执行
默认情况下,ansible在批量连接客户端执行play时的并发数是5个,可以通过调整该值来提高并发数:
[defaults]
forks = 20
即使提高了并发个数,playbook也可能在执行一个需要较长时间的任务时导致阻塞,针对这类任务,可以使用异步的方式来运行:
- hosts: all
tasks:
- name: Install mlocate
yum:
name: mlocate
state: installed
- name: Run updatedb
command: /usr/bin/updatedb
async:300
poll:10
当使用上面的任务控制超过forks设置的节点个数时,'install mlocate'任务会先在 forks 个节点上跑,完成后再继续下一批,这个并发数是由我们设置的 forks 选项控制的。而'Run updatedb'这个任务会一次性在所有节点上都执行,执行的超时时间为300s,然后每10s轮循一次检查它是否完成。需要说明的是,因为需要等待其执行完成,所以如果这个任务比较耗时,仍然需要等待其执行完毕后才能开始下一个任务。
但是如果该任务只是一个后台任务,比如只是在后台执行一个脚本或者启动一个服务,不需要等待其返回结果。那就不需要检查这个任务是否完成,只需要继续执行其它任务,最后再使用wait_for这个模块去检查之前的脚本或者服务是否按预期中运行了便可。这时候只需要把poll的值设置为0,便可以按上面的要求配置ansible不等待job的完成。
还有一种需求,假如一个task,它就是需要运行很长的时间,不能让它超时退出,需要一直等待这个task完成。这个时候就需要将async的值设置为0。
总结来说,大概有以下的一些场景需要使用到ansible的polling特性:
当然也有一些场景是不适合使用:
accelerate模式
Ansible官方建议在可以使用pipelining的情况下,尽量使用pipelining而不是accelerate模式。accelerate只在如下情况下有用处: