模板管理
用于定义配置文件。Ansible将jinja2模板系统用于模板文件。Ansible还使用jinja2语法来引用playbook中的变量。
{# 这是一个注释 #}
{{ ansible_facts['default_ipv4']['address'] }} {{ ansible_facts['hostname'] }}
[[email protected] ansible]# vim playbook/test.yml
---
- hosts: '192.168.111.142'
tasks:
- name: test
template:
src: files/hosts
dest: /etc/hosts
[[email protected] ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.111.142 apache
jinja2模板由多个元素组成:数据、变量和表达式。在呈现jinja2模板时,这些变量和表达式被替换为对应的值。模板中使用的变量可以在playbook的vars部分中指定。可以将受管主机的事实用作模板中的变量。
可以使用ansible system_hostname -i inventory_file -m setup命令来获取与受管主机相关的事实。
演示了如何使用变量及Ansible从受管主机检索的事实创建/etc/ssh/sshd_config的模板。执行相关的playbook时,任何事实都将被替换为所配置的受管主机中对应的值。
template模块还允许指定已部署文件的所有者、组、权限和SELINUX上下文。
为避免系统管理员修改Ansible部署的文件,最好在模板顶部包含注释,以指示不应手动编辑该文件。
用户可以在模板文件中使用jinja2控制结构,以减少重复输入,为play中的每个主机动态输入条目,或者有条件地将文本插入到文件中。
{% for myuser in users if not myuser == "root" %}
User number {{ loop.index }} - {{ myuser }}
{% endfor %}
在Ansible模板中我们可以使用jinja2循环和条件,但不能在Ansible Playbook中使用。
清单管理
主机模式用于指定要作为play或临时命令的目标的主机。在最简单的形式中,清单中受管主机或主机组的名称就是指定该主机或主机组的主机模式。
受管主机
最基本的主机模式是单一受管主机名称列在清单中。这将指定该主机是清单中ansible命令要执行操作的唯一主机。
使用组指定主机
当组名称用作主机模式时,它指定Ansible将对属于该组的成员的主机执行操作。
---
- hosts: lab
使用通配符匹配多个主机
若要达成与all主机模式相同的目标,另一种方法是使用*通配符,它将匹配任意字符串。如果主机模式只是带引号的星号,则清单中的所有主机都将匹配。
---
- hosts: '*'
匹配以.example.com结尾的所有清单
---
- hosts: '*.example.com'
匹配开头为192.168.2.的主机或主机组
---
- hosts: '192.168.2.*'
匹配开头为datacenter的主机或主机组
---
- hosts: 'datacenter*'
管理动态清单
以下示例演示了如何使用ansible-inventory命令来处理INI样式的清单文件并以JSON格式输出。
[[email protected] ~]# cat inventory
workstation1.lab.example.com
[webservers]
web1.lab.example.com
web2.lab.example.com
[databases]
db1.lab.example.com
db2.lab.example.com
[[email protected] ~]# ansible-inventory -i inventory --list
该脚本也支持–host managed-host选项。此选项必须显示由与该主机关联的变量组成的JSON散列/字典,或者空白的JSON散列/字典。
[[email protected] ~]# ./inventoryscript --host server5.demo.example.com
{
"ntpserver": "ntp.demo.example.com",
"dnsserver": "dns.demo.example.com"
}
Ansible支持在同一运行中使用多个清单。如果清单的位置是一个目录(不论是由-i选项设置的、是inventory参数的值,还是以某种其他方式设置的),将组合该目录中包含的所有清单文件(不论是静态还是动态)来确定清单。该目录中的可执行文件将用于检索动态清单,其他文件则被用作静态清单。
清单文件不应依赖于其他清单文件或脚本来解析。例如,如果静态清单文件指定某一个组应当是另一个组的子级,则它也需要具有该组的占位符条目,即使该组的所有成员都来自动态清单。
[cloud-east]
[servers]
test.demo.example.com
[servers:children]
cloud-east
并行方式
当Ansible处理playbook时,会按顺序运行每个play。确定play的主机列表之后,Ansible将按顺序运行每个任务。通常,所有主机必须在任何主机在play中启动下一个任务之前成功完成任务。
理论上,Ansible可以同时连接到play中的所有主机以执行每项任务。这非常适用于小型主机列表。但如果该play以数百台主机为目标,则可能会给控制节点带来沉重负担。
forks
Ansible所进行的最大同时连接数由Ansible配置文件中的forks参数控制。默认情况下设为5,这可通过以下方式之一来验证。
[[email protected] ~]# grep forks /etc/ansible/ansible.cfg
#forks = 5
[[email protected] ~]# ansible-config dump|grep -i forks
DEFAULT_FORKS(default) = 5
[[email protected] ~]# ansible-config list|grep -i forks
DEFAULT_FORKS:
description: Maximum number of forks Ansible will use to execute tasks on target
- {name: ANSIBLE_FORKS}
- {key: forks, section: defaults}
name: Number of task forks
forks的默认值设置得非常保守。如果你的控制节点正在管理Linux主机,则大多数任务将在受管主机上运行,并且控制节点的负载较少。在这种情况下,通常可以将forks的值设置得更高,可能接近100,然后性能就会提高。
如果playbook在控制节点上运行很多代码,则应明智地提高forks限值。如果使用Ansible管理网络路由器和交换机,则大多数模块在控制节点上运行而不是在网络设备上运行。由于这会增加控制节点上的负载,因此其支持forks数量增加的能力将显著低于仅管理Linux主机的控制节点。
可以从命令行覆盖Ansible配置文件中forks的默认设置。ansible和ansible-playbook命令均提供-f或–forks选项以指定要使用的forks数量。
serial
通常,当Ansible运行play时,它会确保所有受管主机在启动任何主机进行下一个任务之前已完成每个任务。在所有受管主机完成所有任务后,将运行任何通知的处理程序。
避免此问题的一种方法是使用serial关键字,通过play批量运行主机。在下一批次启动之前,每批主机将在整个play中运行。
---
- name: Rolling update
hosts: webservers
serial: 2
tasks:
- name: latest apache httpd package is installed
yum:
name: httpd
state: latest
notify: restart apache
handlers:
- name: restart apache
service:
name: httpd
state: restarted
serial关键字也可以指定为百分比。此百分比应用于play中的主机总数,以确定滚动更新批处理大小。无论百分比为何,每一工序的主机数始终为1或以上。