自动化运维-ansible中对于大项目的管理
自动化运维-ansible中对于大项目的管理
一、引用主机清单
在Playbook中引用主机时,hosts
字段指定的目标必须与Ansible主机清单中定义的标识符完全匹配。如果清单中配置的是主机名,则在Playbook中使用IP地址或其他别名将无法匹配,导致任务被跳过
错误示例:
inventory
中配置
playbook
中配置
发现报错,直接跳过该任务
主机清单引用方式大全:
方式 | 示例 | 说明 |
---|---|---|
单台主机 | hosts: node1 | 指定清单中的具体主机名 |
hosts: node1.example.com | 使用FQDN(前提是清单里如此定义) | |
hosts: 172.16.30.10 | 使用IP地址(前提是清单里如此定义) | |
所有主机 | hosts: all | 定位到清单中的所有主机 |
hosts: '*' | 通配符,同样代表所有主机 | |
主机组 | hosts: net | 定位到net 组中的所有主机 |
模式匹配 | hosts: '*.example.com' | 匹配所有以.example.com 结尾的主机 |
hosts: '172.16.30.*' | 匹配172.16.30.0/24 网段的所有主机 | |
hosts: 'web*' | 匹配所有名称以web 开头的主机 | |
hosts: node[ 1-5 ] | 匹配node1 , node2 , …, node5 | |
hosts: node[ a-d ] | 匹配nodea , nodeb , nodec , noded | |
集合操作 | hosts: net:webserver | 并集:属于net 组或webserver 组的主机 |
hosts: net:&webserver | 交集:同时属于net 组和webserver 组的主机 | |
hosts: net:!node1 | 差集:属于net 组但排除node1 主机 |
二、配置并行执行
1. 使用 forks
控制并发连接数
Ansible默认同时只能处理5台主机(由ansible.cfg
中的forks
参数控制)
流程如下:
- 一个Play中如果有10台主机,
forks=5
- Ansible会先在前5台主机上执行完所有任务
- 然后再在剩下的5台主机上执行所有任务
对不同的受控主机:
- Linux受控主机:任务主要在受控端运行,控制节点负载较轻,可适当增加
forks
值以加速执行 - 网络设备:模块多在控制节点运行,负载较高,不宜设置过高的
forks
值
2. 使用 serial
进行并行执行
默认情况下,一个Play中所有主机必须全部完成一个任务,才会进入下一个任务。如果中间某台主机任务失败,整个Play会中止,导致已成功主机的Handlers也无法触发
执行流程:
- 在最先的2台主机(设定 serial=2)上执行Play,安装httpd,成功后触发handler重启服务
- 这2台处理完毕后,再在接下来的2台主机上执行相同的Play
- 依此类推,直到所有批次完成
- 即使某一批次失败,也只影响该批次,已成功的批次已正常执行了Handler
serial
也可以指定百分比(如 serial: "20%"
) 或列表(如 serial: [1, 5, 10]
,表示第一批1台,第二批5台,剩余全部10台一批)
示例:
[student@master ansible] vim b.yml
# playbook内容如下
---
- name: test2hosts: node1,node2,node3,node4serial: 2tasks:- name: test21debug:msg: wil
三、包含与导入
为了提升Playbook的模块化和可重用性,可以将任务或整个Playbook分解到不同文件中
1. 导入(import_*
) - 静态预处理
在解析Playbook时,Ansible会将导入的文件内容直接复制到当前位置。适用于逻辑简单、结构固定的场景
- import_playbook: 导入另一个Playbook文件
- import_tasks: 导入任务文件
示例:
配置
playbook
,repo.yml
[student@master ansible] vim repo.yml
# playbook内容如下
---
- name: repohosts: alltasks:- name: baseosyum_repository:name: baseosdescription: rhel9-baseosbaseurl: http://ansible.example.com/rhel9/BaseOSenabled: yesgpgcheck: no- name: appstreamyum_repository:name: appstreamdescription: rhel9-appstreambaseurl: http://ansible.example.com/rhel9/AppStreamenabled: yesgpgcheck: no
配置
tasks
,http.yml
[student@master ansible] vim http.yml
# tasks内容如下
---- name: install httpyum: name: httpdstate: installed
配置
playbook
,install1.yml
[student@master ansible] vim install1.yml
# playbook内容如下
---
- name: import-repoimport_playbook: repo.yml
- name: install hhosts: node1tasks:- import_tasks: http.yml- name: start httpdservice:name: httpdstate: startedenabled: yes
2. 包含(include_*
) - 动态执行
在Play运行期间遇到include_*
语句时,才会处理导入的文件内容。更灵活,支持与循环结合使用
- include_tasks: 动态包含任务文件
示例:
配置
tasks
,vsftp.yml
[student@master ansible] vim vsftp.yml
# tasks内容如下
---- name: install vsftpdyum: name: vsftpdstate: installed
配置
playbook
,install2.yml
[student@master ansible] vim install2.yml
# playbook内容如下
---
- name: install ftphosts: node1tasks:- include_tasks: vsftp.yml- name: start vsftpdservice:name: vsftpdstate: startedenabled: yes
导入 vs. 包含 关键区别
特性 | 导入 (import_* ) | 包含 (include_* ) |
---|---|---|
处理时机 | 解析时(静态) | 运行时(动态) |
循环 | 不支持 | 支持与loop 一起使用 |
条件触发 | 对所有导入任务应用单个when 条件 | 可为包含的每个任务应用不同条件 |
变量 | 导入时变量必须已定义 | 运行时变量可用,更灵活 |
最佳实践: 优先使用导入,除非你需要循环包含或依赖于运行时变量的动态功能。