Ansible优化
文章目录
- Ansible优化
- 一、-vvv调试,查看详细执行过程
- 二、优化Ansible的执行速度
- 1、设置SSH为长连接
- 2、开启pipelining(管道传输脚本)
- 三、设置facts缓存
- 1、在配置文件中设置
- 2、配置缓存的目标
- 四、异步和轮询(async_status模块)
- 2、Playbook中使用异步
- 3、注意事项
- 五、使用多个Inventory文件
一、-vvv调试,查看详细执行过程
在执行 ad-hoc 或者 playbook 的时候,在后面加上 -vvv 参数,就可以看到 Ansible 的详细执行过程,便于排错
ansible dbservers -i hosts -m ping -vvv
ansible-playbook -i hosts checkhost.yml -vvv
二、优化Ansible的执行速度
1、设置SSH为长连接
openssh5.6 版本后支持 Multiplexing
Multiplexing 英 [ˈmʌltɪplɛksɪŋ] 美 [ˈmʌltiˌplɛksɪŋ] 多路复用
检查控制机器的 ssh 版本
ssh -V
OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 26 Jan 2017
设置 ansible 配置文件
[root@kakaops ~]# grep sh_args /etc/ansible/ansible.cfg
ssh_args = -C -o ControlMaster=auto -o ControlPersist=10d
# ControlPersist=10d 表示保持长连接 10 天。
# 60s 是 60 秒
建立长连接并测试
设置好后重新连接一次被控主机,即可让控制主机和被控主机之间建立长连接
ansible 10.11.67.32 -i hosts -m ping
验证长连接
[root@kakaops ~]# ss -nta |grep ESTAB
输出中 有 ESTAB 状态的就代表是长连接
同时会在主控机当前用户的家目录下的
.ansibl/cp/ 目录下生成对应的 socket 文件
[root@kakaops ~]# ls -l .ansible/cp/13fe34a1c4
srw------- 1 root root 0 Apr 17 03:36 .ansible/cp/13fe34a1c4
2、开启pipelining(管道传输脚本)
pipelining 英 [ˈpaɪplaɪnɪŋ] 美 [ˈpaɪˌplaɪnɪŋ] n.管路输送
默认情况下 Ansible 执行过程中会把生成好的本地 python 脚本文件 PUT 到 远端机器。如果我们开启了 ssh 的 pipelining 特性,这个过程就会在 SSH 的会话中进行。在不通过实际文件传输的情况下执行ansible模块来使用管道特性, 可以减少执行远程服务器上的模块所需的网络操作数量。比如 PUT sftp 等操作都需要建立网络连接。
下面是关闭 Pipeline 的情况下的三步操作
<172.18.0.3> PUT /root/.ansible/tmp/ansible-local-10883q1xq1u/tmpNbePyo TO /root/.ansible/tmp/ansible-tmp-1587214813.33-212837305246708/AnsiballZ_ping.py
<172.18.0.3> SSH: EXEC sftp -b - -C -o ControlMaster=auto -o ControlPersist=600s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/553ad38749 '[172.18.0.3]'
<172.18.0.3> (0, 'sftp> put /root/.ansible/tmp/ansible-local-10883q1xq1u/tmpNbePyo /root/.ansible/tmp/ansible-tmp-1587214813.33-212837305246708/AnsiballZ_ping.py\n', '')
如果开启这个设置,将显著提高性能.。
下面的步骤是实现这个特性的步骤
ansible.cfg 配置文件中设置 pipelining 为 True
[root@kakaops ~]# grep pipelining /etc/ansible/ansible.cfg
# Enabling pipelining reduces the number of SSH operations required to
pipelining = True
三、设置facts缓存
1、在配置文件中设置
默认情况下,Ansible 每次执行 playbook 时的第一个 Task 就是获取每台主机的 facts信息。假如不需要可以设置 gather_facts = no 进行关闭,以提高执行 playbook 的效率。假如想获取 facts 信息,同时又想加速这个 task 的效率,就需要设置 facts 缓存。缓存 facts 信息可以存档 JSON 文件中,也可以方式 redis 和 memcached 中。
首先是可以在 ansible.cfg 文件中设置
grep gathering /etc/ansible/ansible.cfg
gathering = smart
gathering 的值可以设置为其中的一个: smart、implicit 或者 explicit
smart:表示默认收集facts,但facts信息已经存在的情况下不会收集,也就是会使用缓存facts
implicit:表示默认收集facts,但要禁止收集,可以在 playbook中设置gather_facts: no
explicit:则表示默认不收集,但要收集,可以在 playbook中设置 gather_facts: yes
例如:在playbook 中设置
- hosts: all
gather_facts: yes # 收集
gather_facts: no # 不收集
2、配置缓存的目标
grep -P -v '^#|^$' /etc/ansible/ansible.cfg
可以清楚查看ini风格配置文件的有用信息
缓存到文件(JSON格式的数据):
在 ansible.cfg 文件中配置缓存到一个普通文件中,保存的数据是 JSON 格式
gathering = smart
fact_caching = jsonfile # 缓存到 json 文件
fact_caching_connection = /dev/shm/ansible_fact_cache/ #保存的文件
fact_caching_timeout = 86400 # 缓存数据时间是一天
fact_caching_connection 是一个本地可写的目录路径
如果目录不存在,ansible会试图创建最后一级目录
文件名是在 Inventory 中保存的 IP 或者 hostname
缓存到Redis(数据库缓存服务器):
在任一机器或者ansible 控制主机上部署 Redis 服务
yum install redis
假如 Redis 服务不在 ansible 控制主机上,还应该设置 redis 监听地址
grep '^bind' /etc/redis.conf
bind 0.0.0.0
在控制主机 python 的 redis 库
pip install redis
在 ansible.cfg 文件中配置缓存到 redis
gathering = smart
fact_caching = redis # 缓存到 redis
fact_caching_connection = 192.168.1.37:6379:6
fact_caching_timeout = 86400 # 缓存数据时间是一天
执行一次playbook,就可以将收集到的facts变量缓存到redis的6号库
四、异步和轮询(async_status模块)
默认情况下,执行 ansible 的时候,这个命令会一直处于阻塞状态,直到在每个节点上完成任务为止, 系统才能继续执行下一条命令。这可能并不总是需要的,因为这样你的程序不能执行其他的命令。或者您运行的操作所花费的时间超过了SSH的连接超时时间, 这将导致连接中断,任务结果无法完整返回。Ansible 支持异步执行需要执行的任务,这样可以让比较耗时的任务在后台运行,以后再查看它们的状态。
1、执行临时命令的时候,使用异步
比如下示例是 执行一个任务持续运行 5 秒钟,并设置后台进程获取任务结果的超时时间 10 秒(-B 10),并且不等待任务返回结果(-P 0)。
异步轮询的-P参数的值是0
这样任务一开始执行,就会返回一个这任务的 ID,就是 ansible_job_id 的值
ansible dbservers -B 10 -P 0 -i hosts -a "sleep 5"
172.18.0.3 | CHANGED => {
"ansible_job_id": "191465439990.2210",
"changed": true,
"finished": 0,
"results_file": "/root/.ansible_async/191465439990.2210",
"started": 1
}
查看保存结果集的文件
执行结果会存放的被控节点主机的 /root/.ansible_async/191465439990.2210文件中,需要在控制机上面上用async_status模块获取结果,需要传递job id,就是返回信息中字段 ansible_job_id的值
ansible dbservers -i hosts -m async_status -a "jid=191465439990.2210"
假如 -P 的值大于 0 就会起到同步执行的效果,整个Ansible 命令还是阻塞的状态
并且 -B 的值必须大于命令实际执行消耗的时间。-B 的值最好是大一些。否则报错
2、Playbook中使用异步
下面演示一个异步任务,这个异步任务执行时长 5 秒左右,等待超时时间是 6 秒钟, 之后需把返回结果注册到变量 job 中,这样才能获取到每个被控主机的 job id。最后使用 debug 模块打印出来
- hosts: dbservers
remote_user: root
tasks:
- name: simulate long running op (5 sec), wait for up to 6 sec, poll every 0 sec
shell: /bin/sleep 5;hostname -i
async: 6
poll: 0
register: job
- name: show job id
debug:
msg: "Job id is {{ job }}"
3、注意事项
不应通过将轮询值指定为0来进行需要排他锁的操作(例如yum事务)来尝试异步运行任务。比如 YUM.其实, 安装多个包 YUM 模块本身就支持
- name: install tree vim
yum:
name: [tree, vim]
state: present
命令行中使用英文逗号隔开:
-m yum -a "name=tree,vim state=present"
五、使用多个Inventory文件
通过从命令行提供多个清单参数或通过配置多个清单参数,可以同时定位多个清单源(目录,动态清单脚本或清单插件支持的文件)
1、从命令行定义两个源
ansible-playbook get_logs.yml -i development -i production
2、使用目录汇总清单
可以通过组合目录下的多个清单来源和来源类型来创建清单。
这对于组合静态和动态主机并将它们作为一个清单进行管理很有用
目录中仅支持如下扩展名
shell
.yaml .yml .json
以下清单结合了清单插件源,动态清单脚本和具有静态主机的文件
inventory/
aliyun.yml # 清单插件,获取阿里云的主机
dynamic-inventory.py # 使用动态脚本添加额外的主机
static-inventory # 添加静态主机和组
group_vars/
all.yml # 给所有的主机指定变量
以上的组合可以去掉自己环境中不需要的
命令行里使用这个清单目录
ansible-playbook example.yml -i inventory
可以在配置文件中配置
假设这个清单目录的绝对路径是: /etc/ansible/inventory
应该这样配置:
[defaults]
inventory = /etc/ansible/inventory
要注意变量覆盖
如果存在与其他库存来源之间的变量冲突或组依赖关系
则控制库存来源的合并顺序可能很有用。
根据文件名按字母顺序合并清单,因此可以通过在文件前添加前缀来控制结果:
inventory/
01-aliyun.yml # 清单插件,获取阿里云的主机
02-dynamic-inventory.py # 使用动态脚本添加额外的主机
03-static-inventory # 添加静态主机和组
group_vars/
all.yml # 给所有的主机指定变量
重复定义变量导致变量被覆盖,是应该避免的,也可以避免的