Ansible-最佳实战
- 一、ansible调试
- [二、优化 Ansible 执行速度](#二、优化 Ansible 执行速度)
-
- [2.1 设置 SSH 为长连接](#2.1 设置 SSH 为长连接)
-
- [2.1.1 设置 ansible 配置⽂件](#2.1.1 设置 ansible 配置⽂件)
- [2.1.2 建⽴⻓连接并测试](#2.1.2 建⽴⻓连接并测试)
- [2.2 开启 pipelining](#2.2 开启 pipelining)
-
- [2.2.1 在 ansible.cfg 配置⽂件中设置 pipelining 为 True](#2.2.1 在 ansible.cfg 配置⽂件中设置 pipelining 为 True)
- [2.2.2 配置被控主机的 /etc/sudoers 文件](#2.2.2 配置被控主机的 /etc/sudoers 文件)
- [2.3 设置 facts 缓存](#2.3 设置 facts 缓存)
-
- [2.3.1 配置 ansible.cfg](#2.3.1 配置 ansible.cfg)
- 三、ansible的执行策略
- 四、ansible的inventory清单目录
-
- [4.1 roles项目结构](#4.1 roles项目结构)
按顺序食用,口味更佳
( 1 ) ⾃动化运维利器Ansible-基础
( 2 ) ⾃动化运维利器 Ansible-Playbook
( 3 ) ⾃动化运维利器 Ansible-变量
( 4 ) ⾃动化运维利器AnsiblePlaybook的任务控制
( 5 ) ⾃动化运维利器 Ansible-Jinja2
( 6 ) ⾃动化运维利器 Ansible-最佳实战
一、ansible调试
在执⾏ ad-hoc 或者 playbook 的时候,在后⾯加上 -vvv 参数,就可以看到 Ansible 的详细执⾏过程,便于排错。
shell
[root@aimyon36 ~] ansible dbservers -i hosts -m ping -vvv
[root@aimyon36 ~] ansible-playbook -i hosts checkhost.yml -vvv
限制授影响的主机,指定主机或者主机组执行本次ansible命令,--limit 后⾯跟主机名或者主机组名。
shell
[root@aimyon36 ~] ansible-playbook -i hosts checkhosts.yml --limit dbservers -vvv
二、优化 Ansible 执行速度
2.1 设置 SSH 为长连接
openssh5.6 版本后才⽀持 Multiplexing。(可以使用 ssh -v 查看服务器的ssh版本)
版本不匹配的可以升级ssh客户端版本。(使用yum工具升级客户端等级 yum update openssh-clients)
2.1.1 设置 ansible 配置⽂件
powershell
vim /etc/ansible/ansible.cfg
ssh_args = -C -o
ControlMaster=auto -o
ControlPersist=10d
# ControlPersist=10d 表示保持⻓连接 10 天。
# 60s 是 60 秒
2.1.2 建⽴⻓连接并测试
设置好后,重新连接⼀次被控主机,即可让控制主机和被控主机之间建⽴⻓连接。
powershell
[root@aimyon36 ~] ansible webservers -i hosts -m ping
172.18.0.4 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python":
"/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
验证⻓连接,输出中 有 ESTAB 状态的就代表是⻓连接,同时会在主控机当前⽤户的家⽬录下的 .ansibl/cp/ ⽬录下⽣成对
应的 socket ⽂件。
shell
[root@aimyon36 ~] ss -nta | grep ESTAB
tcp ESTAB 0 0 172.18.0.2:51864 172.18.0.4:2222
2.2 开启 pipelining
道默认情况下 Ansible 执⾏过程中会把⽣成好的本地python 脚本⽂件 PUT 到 远端机器。如果我们开启了 ssh 的pipelining 特性,这个过程就会在 SSH 的会话中进⾏。
在不通过实际⽂件传输的情况下执⾏ansible模块来使⽤管道特性,可以减少执⾏远程服务器上的模块所需的⽹络操作数量。
⽐如 PUT sftp 等操作都需要建⽴⽹络连接。
2.2.1 在 ansible.cfg 配置⽂件中设置 pipelining 为 True
powershell
vim /etc/ansible/ansible.cfg
pipelining = True
2.2.2 配置被控主机的 /etc/sudoers 文件
添加内容
powershell
# Disable "ssh hostname sudo <cmd>", because it will
show the password in clear text.
# You have to run "ssh -t hostname sudo <cmd>".
#
# Defaults requiretty
2.3 设置 facts 缓存
默认情况下,Ansible 每次执⾏ playbook 时的第⼀个 Task 就是获取每台主机的 facts 信息。假如不需要可以设置 gather_facts =no 进⾏关闭,以提⾼执⾏ playbook 的效率。
假如想获取 facts 信息,同时⼜想加速这个 task 的效率,就需要设置 facts 缓存。缓存 facts 信息可以存档 JSON ⽂件中,也可以⽅式 redis 和memcached 中。
2.3.1 配置 ansible.cfg
powershell
vim /etc/ansible/ansible.cfg
gathering = smart
ansible的配置⽂件中可以修改'gathering'的值为smart、implicit 或者 explicit。
- smart --> 表示默认收集facts,但facts已有的情况下不会收集,也就是会使⽤缓存facts;
- implicit --> 表示默认收集facts,要禁⽌收集,必须使⽤gather_facts: False;
- explicit --> 则表示默认不收集,要显式收集,必须使⽤gather_facts: Ture
在playbook 中设置
powershell
---
gather_facts: yes # 显式定义收集
gather_facts: no # 显式定义不收集
配置缓存目标文件
powershell
缓存到⽂件(JSON格式的数据) 在 ansible.cfg ⽂件中配置缓存到⼀个普通⽂件中,同时还可指定搜集哪些信息,⽐如只搜集 network,virtual
shell
gathering = smart
gather_subset = network,virtual # 只搜集 ⽹络信息和虚拟化信息
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 服务
shell
yum install redis
在控制主机安装 python 的 redis 库
shell
pip install redis
在 ansible.cfg ⽂件中配置缓存到 redis
shell
gathering = smart
fact_caching = redis # 缓存到 redis
fact_caching_connection = 192.168.1.37:6379:0
fact_caching_timeout = 86400 # 缓存数据时间是⼀天
三、ansible的执行策略
默认的执⾏策略是按批并⾏处理的,假如总共 15 台主机,每次并发 5 个线程执⾏的策略如下:
powershell
h1/h2/h3/h4h5 -------> h6/h7/h8/h9/h10 ----->h11/h12/h13/h14/h15
全部执⾏完后,进⼊下⼀批 依次类推
从 asible2.0 开始,可以通过在 playbook 中设置 strategy 的值改变这策略,也可以在 ansible.cfg 配置⽂件中设置⼀个默认的策略:
bash
[defaults]
strategy = free
改变后的策略,可以前赴后继的对主机进⾏执⾏ task,执⾏模式如下:
powershell
h1/h2/h3/h4/h5 ------> h1/h2/h3/h6/h5 ------->h1/h2/h3/h6/h7 ----->...
假如 h4 主机先执⾏完,会及时的让 下⼀个排队的主机进⼊到执⾏的队列中。
strategy 默认的值的是 linear ,就是按批并⾏处理,下⾯是配置为 free 的⽅式实例:
yaml
- hosts: webservers
strategy: free
tasks:
- name: ping hosts
ping:
默认 Ansible 的执⾏队列有⼀个,就是并⾏执⾏,假如控制节点的机器有多个 CPU,并且性能较好,可以打开多个执⾏队列,就是并发。
- 在配置文件中配置多并发
[defaults] forks = 30
- 在命令行参数配置多并发
ansible-playbook -f 3 my_playbook.yml
四、ansible的inventory清单目录
bash
ansible-playbook get_logs.yml -i development -i production
上述ansible-playbook命令使用-i (inventory) 指定了两个配置文件,分别是development和production。在生产环境中,配置文件可能不止一个,因此ansible提供了更简便的方式。
通过组合⽬录下的多个清单来源和来源类型来创建清单。 这对于组合静态和动态主机并将它们作为⼀个清单进⾏管理很有⽤。
⽬录中仅⽀持如下扩展名
- yaml
- yml
- json
以下通过inventory目录(文件夹)清单结合了清单插件源,动态清单脚本和具有静态主机的⽂件。
shell
inventory/
aliyun.yml # 清单插件,获取阿⾥云的主机
dynamic-inventory.py # 使⽤动态脚本添加额外的主机
static-inventory # 添加静态主机和组
group_vars/
all.yml # 给所有的主机指定变量
使⽤命令⾏来使用这个清单⽬录:
powershell
ansible-playbook example.yml -i inventory
使用配置文件ansible.cfg来使用这个指定这个清单目录
powershell
[defaults]
inventory = /etc/ansible/inventory
清单目录中存在多个清单文件,每个清单文件都可能定义了不同的变量,因此需要注意变量覆盖。
ansible在读取目录清单时,会根据文件的字典名顺序对清单文件进行合并,如果存在与其他库存来源之间的变量冲突或组依赖关系,则控制库存来源的合并顺序可能很有用,因此通常在清单配置文件加上前缀保证合并顺序,确保变量的正确加载。
shell
inventory/
01-aliyun.yml # 清单插件,获取阿⾥云的主机
02-dynamic-inventory.py # 使⽤动态脚本添加额外的主机
03-static-inventory # 添加静态主机和组
group_vars/
all.yml # 给所有的主机指定变量
Example
inventory 清单目录:
shell
inventory
|-- 01-static.yml
|-- 02-static.yml
0 directories, 2 files
inventory/01-static.yml文件内容:
powershell
[webservers]
172.18.0.[4:10]
[allservers:children]
webservers
[allservers:vars]
name = xiguatian
inventory/02-static.yml文件内容:
powershell
[dbservers]
172.18.0.3
[allservers:children]
dbservers
[allservers:vars]
name = shark
验证文件顺序改变的变量内容:
shell
ansible all -i inventory -m debug -a "var=name"
172.18.0.4 | SUCCESS => {
"name": "shark"
}
172.18.0.5 | SUCCESS => {
"name": "shark"
}
172.18.0.6 | SUCCESS => {
"name": "shark"
}
172.18.0.7 | SUCCESS => {
"name": "shark"
}
172.18.0.8 | SUCCESS => {
"name": "shark"
}
172.18.0.9 | SUCCESS => {
"name": "shark"
}
172.18.0.10 | SUCCESS => {
"name": "shark"
}
....
4.1 roles项目结构
随着自动化运维需求的提升,Ansible playbook变得越来越复杂,需要一种更高效的方式来管理和复用代码。
因此有剧本就要有角色,ansible提供了一种roles的项目结构,规定每个角色要执行的剧本。
bash
初始化roles项目
ansible-galaxy init your_roles
Ansible Roles是一种组织和管理Ansible Playbooks的方法,允许将相关的配置和任务分组到一个可重用的单元中。Roles使得代码更加模块化和可维护。以下是Ansible Roles项目的典型结构:
- roles
- role_name (例如nginx)
- README.md:提供角色的基本描述、文档和示例。
- meta:指定角色的作者、许可证、兼容性和依赖项等信息
- files:存放ansible模块需要使用到的文件,例如copy。
- handlers:存放触发器任务。
- tasks:定义主要的任务文件。
- templates:存放模板文件,用于动态生成配置文件。
- vars:定义变量文件,用户可以自定义变量宫templates使用
- defaults:存放默认变量文件。
- hosts:
- role_name (例如nginx)
role的正确食用方式:
如果已经创建并定义好了一个role角色,那么可以创建一个Ansible Playbook文件(例如site.yml),用于调用role角色。
site.yml:
yaml
---
- hosts: webservers //
become: yes
roles:
- role: nginx //定义好的role名字
...
执行:
bash
ansible-playbook -i hosts site.yml
-i 指定服务器资产信息,site.yml中则指明了要运行的role,具体的任务设置在role:nginx中,也就是当前目录的role项目。
如果此处不使用-i指定服务器资产当前目录下存在一个名为 hosts 的文件,Ansible 会默认使用这个文件作为清单。
如果在当前目录下没有找到 hosts 文件,Ansible 会尝试加载 /etc/ansible/hosts 文件。
本章是最后一章,看完所有文章应该能够理解ansible的操作流程,虽然没有使用具体的实例介绍,但是阅读完之后也一定能够看明白ansible。
按顺序食用,口味更佳
( 1 ) ⾃动化运维利器Ansible-基础
( 2 ) ⾃动化运维利器 Ansible-Playbook
( 3 ) ⾃动化运维利器 Ansible-变量
( 4 ) ⾃动化运维利器AnsiblePlaybook的任务控制
( 5 ) ⾃动化运维利器 Ansible-Jinja2
( 6 ) ⾃动化运维利器 Ansible-最佳实战