现代 IT 人一定要知道的 Ansible系列教程:Ansiable配置
配置文件
Ansible 中的某些设置可通过配置文件 (ansible.cfg
) 进行调整。 库存配置对于大多数用户来说应该足够了,但您可能出于某些原因想要更改它们。
可以在配置文件中进行更改并使用该更改,该文件将按以下顺序搜索:
ANSIBLE_CONFIG
(如果设置了环境变量)ansible.cfg
(在当前目录中)~/.ansible.cfg
(在主目录中)/etc/ansible/ansible.cfg
获取最新配置
如果从软件包管理器安装 Ansible,则最新的 ansible.cfg
文件可能会出现在 /etc/ansible
中 作为 .rpmnew
文件(或其他文件)(视更新情况而定)。
如果您从 pip
或源安装 Ansible,您可能需要创建此文件来覆盖 Ansible 中的默认设置。
您可以生成 Ansible 配置文件ansible.cfg
,其中列出了所有默认设置,如下所示:
$ ansible-config init --disabled > ansible.cfg
包含可用插件以创建更完整的 Ansible 配置,如下所示:
$ ansible-config init --disabled -t all > ansible.cfg
更多配置请参考:https://docs.ansible.com/ansible/latest/reference_appendices/config.html#ansible-configuration-settings
构建 Ansiable inventories
Ansible 使用称为清单的列表或列表组自动执行基础架构中的托管节点或“主机”上的任务。可以在命令行传递主机名,但大多数 Ansible 用户都会创建清单文件。清单文件定义了自动化的托管节点,并带有组,以便我们可以同时在多个主机上运行自动化任务。 定义清单后,我们可以使用模式来选择我们希望 Ansible 运行的主机或组。
最简单的清单是包含主机和组列表的单个文件。此文件的默认位置是 /etc/ansible/hosts
。 我们可以在命令行中使用 选项指定不同的清单文件,或在配置中使用 指定不同的清单文件。-i <path> inventory
Ansible 库存插件支持多种格式和来源,使我们的库存灵活且可定制。随着我们的库存扩展,可能需要多个文件来组织主机和组。以下是 /etc/ansible/hosts
文件之外的三个选项:
- 可以创建一个包含多个清单文件的目录。它们可以使用不同的格式(YAML、ini 等)。
- 可以动态提取库存。例如,您可以使用动态库存插件来列出一个或多个云提供商中的资源。
- 可以使用多个清单源,包括动态清单和静态文件。
inventories 基础知识
清单将托管节点组织在集中式文件中,为 Ansible 提供系统信息和网络位置。使用清单文件,Ansible 可以通过单个命令管理大量主机。
INI 或 YAML 格式的清单
您可以在 INI
文件或 中创建 YAML
清单。在大多数情况下,例如前面步骤中的示例,对于少量受管节点来说, INI
文件是简单明了且易于阅读的。
随着托管节点数量的增加,以 YAML
格式创建清单成为明智的选择。例如,以下内容等 inventory.ini
效于声明受管节点的唯一名称并使用该 ansible_host
字段:
myhosts:
hosts:
my_host_01:
ansible_host: 192.168.2.129
my_host_02:
ansible_host: 192.168.2.130
我们在创建一个目录/root/ansible_quickstart
并创建文件 inventory.ini
,将新 [myhosts]
组添加到该文件中 inventory.ini
,并指定每个主机系统的 IP 地址。
[myhosts] 192.168.2.129 192.168.2.130
使用以下命令来验证 inventory.ini
ansiable-inventory -i inventory.ini --list
root@master:~/ansible_quickstart# ansible-inventory -i inventory.ini --list
{
"_meta": {
"hostvars": {}
},
"all": {
"children": [
"ungrouped",
"myhosts"
]
},
"myhosts": {
"hosts": [
"192.168.2.129",
"192.168.2.130"
]
}
}
对清单中的 myhosts
组执行 Ping 操作。
如果控制节点和受管节点上的用户名不同,则通过
ansible
命令传递该-u
选项。
root@master:~/ansible_quickstart# ansible myhosts -m ping -i inventory.ini
192.168.2.129 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
192.168.2.130 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
我们可以看到已经成功建立 inventory 。通过创建 playbook 继续开始使用 Ansible。
上面已经提到过构建清单 inventory 可以使用 ini
格式的文件,同时也是可以使用 yml
文件的。我们可以区分场景使用,如果构建的清单是比较复杂的,那么建议使用 yml
文件构建,因为yml
文件的语义更强,不过需要以下几点:
- 确保组名称有意义且唯一。组名称也区分大小写。
- 在组名称中避免使用空格、连字符和前面的数字(use
floor_19
、not19th_floor
)。 - 根据清单中的主机的内容、位置和时间对主机进行逻辑分组。
- 根据拓扑对主机进行分组,例如:db、web、leaf、spine。
- 按地理位置对主机进行分组,例如:数据中心、区域、楼层、建筑物。
- 按阶段对主机进行分组,例如:开发、测试、暂存、生产。
yml
文件示例:
root@master:~/ansible_quickstart# cat inventory.yml
myhosts:
hosts:
node129:
ansiable_host: 192.168.2.129
node130:
ansiable_host: 192.168.2.130
root@master:~/ansible_quickstart# ansible myhosts -m ping -i inventory.yml
node130 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
node129 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
使用 metagroups
创建一个元组,使用以下语法组织清单中的多个组:
metagroupname:
children:
以下清单说明了数据中心的基本结构。此示例清单包含一个 network
包含所有网络设备的元组和一个包含该 network
组和所有 Web 服务器的 datacenter
元组。
leafs:
hosts:
leaf01:
ansible_host: 192.0.2.100
leaf02:
ansible_host: 192.0.2.110
spines:
hosts:
spine01:
ansible_host: 192.0.2.120
spine02:
ansible_host: 192.0.2.130
network:
children:
leafs:
spines:
webservers:
hosts:
webserver01:
ansible_host: 192.0.2.140
webserver02:
ansible_host: 192.0.2.150
datacenter:
children:
network:
webservers:
以上示例仅仅演示
创建变量
变量设置受管节点的值,例如 IP 地址、操作系统和 SSH 用户以及端口,因此我们在运行 Ansible
命令时无需传递它们。
变量可以应用于特定主机。
webservers:
hosts:
webserver01:
ansible_host: 192.0.2.140
http_port: 80
webserver02:
ansible_host: 192.0.2.150
http_port: 443
变量还可以应用于组中的所有主机。
webservers:
hosts:
webserver01:
ansible_host: 192.0.2.140
http_port: 80
webserver02:
ansible_host: 192.0.2.150
http_port: 443
vars:
ansible_user: root
Inventory 别名
还可以使用主机变量在清单中定义别名
In INI: 在 INI 中:
jumper ansible_port=5555 ansible_host=192.168.2.129
In YAML: 在 YAML 中:
...
hosts:
jumper:
ansible_port: 5555
ansible_host: 192.168.2.129
在此示例中,针对主机别名 jumper 运行 Ansible 将连接到端口 5555 上的 192.168.2.129。
将变量分配给多台计算机:组变量
如果组中的所有主机共享一个变量值,则可以一次将该变量应用于整个组。
In INI: 在 INI 中:
[atlanta]
host1
host2
[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com
In YAML: 在 YAML 中:
atlanta:
hosts:
host1:
host2:
vars:
ntp_server: ntp.atlanta.example.com
proxy: proxy.atlanta.example.com
组变量是一次将变量应用于多个主机的便捷方法。但是,在执行之前,Ansible 始终将变量(包括清单变量)展平到主机级别。如果主机是多个组的成员,则 Ansible 会从所有这些组中读取变量值。如果为不同组中的同一变量分配不同的值,Ansible 会根据内部合并规则选择要使用的值。
继承变量值:组的组变量
您可以将变量应用于父组(嵌套组或组组)以及子组。
语法相同: :vars
对于 INI 格式和 vars:
YAML 格式:
In INI: 在 INI 中:
[atlanta]
host1
host2
[raleigh]
host2
host3
[southeast:children]
atlanta
raleigh
[southeast:vars]
some_server=foo.southeast.example.com
halon_system_timeout=30
self_destruct_countdown=60
escape_pods=2
[usa:children]
southeast
northeast
southwest
northwest
In YAML: 在 YAML 中:
usa:
children:
southeast:
children:
atlanta:
hosts:
host1:
host2:
raleigh:
hosts:
host2:
host3:
vars:
some_server: foo.southeast.example.com
halon_system_timeout: 30
self_destruct_countdown: 60
escape_pods: 2
northeast:
northwest:
southwest:
子组的变量将比父组的变量具有更高的优先级(覆盖)
变量如何合并
默认情况下,在运行播放之前,变量会合并/展平到特定主机。这使 Ansible 专注于主机和任务,因此组无法在清单和主机匹配之外生存。默认情况下,Ansible 会覆盖变量,包括为组和/或主机定义的变量(参见 DEFAULT_HASH_BEHAVIOUR)。顺序/优先级为(从低到高):
- all group
- parent group
- child group
- host
默认情况下,Ansible 会按 ASCII 顺序合并同一父/子级别的组,并且加载的最后一个组中的变量会覆盖前一个组中的变量。例如,将合并 b_group
和 b_group
匹配的变量将 a_group
覆盖 a_group
中的变量。
可以通过设置组变量 ansible_group_priority
来更改同一级别的组的合并顺序(在解析父/子顺序后)来更改此行为。数字越大,合并时间越晚,优先级越高。此变量默认为 1
if un set。
例如:
a_group:
vars:
testvar: a
ansible_group_priority: 10
b_group:
vars:
testvar: b
在此示例中,如果两个组具有相同的优先级,则结果通常为 testvar == b
,但由于我们赋予了 a_group
更高的优先级,因此结果将是 testvar == a
。