介绍
Ansible 是一种现代化的配置管理工具,它有助于设置和维护远程服务器的任务,其极简设计旨在让用户快速启动和运行。 Ansible 使用 库存文件 来跟踪哪些主机是您的基础架构的一部分,以及如何访问它们以运行命令和剧本。
您可以通过多种方式设置 Ansible 清单文件,具体取决于您的环境和项目需求。 在本指南中,我们将演示如何创建清单文件并将服务器组织成组和子组,如何设置主机变量,以及如何使用模式来控制每个主机和每个组的 Ansible 命令和剧本的执行。
先决条件
为了遵循本指南,您需要:
- 一个 Ansible 控制节点:安装了 Ansible 并配置为使用 SSH 密钥连接到 Ansible 主机的 Ubuntu 20.04 机器。 确保控制节点具有具有 sudo 权限的普通用户并启用了防火墙,如我们的 初始服务器设置 指南中所述。 要设置 Ansible,请按照我们关于 如何在 Ubuntu 20.04 上安装和配置 Ansible 的指南进行操作。
- 两台或多台 Ansible 主机:两台或多台远程 Ubuntu 20.04 服务器。
第 1 步 — 创建自定义库存文件
安装后,Ansible 会创建一个清单文件,该文件通常位于 /etc/ansible/hosts
。 这是 Ansible 在 playbook 或命令执行期间未使用 -i
选项提供自定义清单文件时使用的默认位置。
尽管您可以毫无问题地使用此文件,但使用每个项目的清单文件是避免在执行命令和 playbook 时混合服务器的好习惯。 拥有每个项目的清单文件也将有助于与协作者共享您的配置设置,前提是您将清单文件包含在项目的代码存储库中。
首先,访问您的主文件夹并创建一个新目录来保存您的 Ansible 文件:
cd ~ mkdir ansible
移动到该目录并使用您选择的文本编辑器打开一个新的库存文件。 在这里,我们将使用 nano
:
cd ansible nano inventory
您的节点列表(每行一台服务器)足以设置功能清单文件。 主机名和 IP 地址可以互换:
~/ansible/库存
203.0.113.111 203.0.113.112 203.0.113.113 server_hostname
设置清单文件后,您可以使用 ansible-inventory
命令验证并获取有关 Ansible 清单的信息:
ansible-inventory -i inventory --list
Output{ "_meta": { "hostvars": {} }, "all": { "children": [ "ungrouped" ] }, "ungrouped": { "hosts": [ "203.0.113.111", "203.0.113.112", "203.0.113.113", "server_hostname" ] } }
尽管我们没有在我们的清单中设置任何组,但输出显示了 Ansible 自动推断的 2 个不同的组:all
和 ungrouped
。 顾名思义,all
用于引用库存文件中的所有服务器,无论它们是如何组织的。 ungrouped
组用于指代未在组中列出的服务器。
使用自定义清单运行命令和剧本
要使用自定义清单文件运行 Ansible 命令,请使用 -i
选项,如下所示:
ansible all -i inventory -m ping
这将在自定义清单文件中列出的 all 主机上执行 ping
模块。
同样,这是使用自定义清单文件执行 Ansible playbook 的方式:
ansible-playbook -i inventory playbook.yml
注意:关于如何连接节点的更多信息,请参考我们的如何使用Ansible指南,因为它演示了更多的连接选项。
到目前为止,我们已经了解了如何创建基本清单以及如何使用它来运行命令和剧本。 在下一步中,我们将看到如何将节点组织成组和子组。
第 2 步 — 将服务器组织成组和子组
在清单文件中,您可以将服务器组织成不同的组和子组。 除了帮助保持主机井井有条之外,这种做法还将使您能够使用 组变量 ,该功能可以极大地促进使用 Ansible 管理 多个暂存环境 。
主机可以是多个组的一部分。 以下 INI 格式的清单文件演示了具有四个组的设置:webservers
、dbservers
、development
和 production
。 您会注意到服务器按两种不同的特性进行分组:它们的用途(Web 和数据库)以及它们的使用方式(开发和生产)。
~/ansible/库存
[webservers] 203.0.113.111 203.0.113.112 [dbservers] 203.0.113.113 server_hostname [development] 203.0.113.111 203.0.113.113 [production] 203.0.113.112 server_hostname
如果您要使用此清单文件再次运行 ansible-inventory
命令,您将看到以下安排:
Output{ "_meta": { "hostvars": {} }, "all": { "children": [ "dbservers", "development", "production", "ungrouped", "webservers" ] }, "dbservers": { "hosts": [ "203.0.113.113", "server_hostname" ] }, "development": { "hosts": [ "203.0.113.111", "203.0.113.113" ] }, "production": { "hosts": [ "203.0.113.112", "server_hostname" ] }, "webservers": { "hosts": [ "203.0.113.111", "203.0.113.112" ] } }
也可以将多个组聚合为“父”组下的 children。 然后,“父”被称为 元组。 以下示例演示了另一种使用元组组织先前清单的方法,以实现可比较但更精细的排列:
~/ansible/库存
[web_dev] 203.0.113.111 [web_prod] 203.0.113.112 [db_dev] 203.0.113.113 [db_prod] server_hostname [webservers:children] web_dev web_prod [dbservers:children] db_dev db_prod [development:children] web_dev db_dev [production:children] web_prod db_prod
您拥有的服务器越多,分解组或创建替代安排就越有意义,以便您可以根据需要定位更小的服务器组。
第 3 步 — 设置主机别名
您可以使用别名来命名服务器,以便以后在运行命令和 playbook 时引用这些服务器。
要使用别名,请在别名后包含一个名为 ansible_host
的变量,其中包含应响应该别名的服务器的相应 IP 地址或主机名:
~/ansible/库存
server1 ansible_host=203.0.113.111 server2 ansible_host=203.0.113.112 server3 ansible_host=203.0.113.113 server4 ansible_host=server_hostname
如果您要使用此清单文件运行 ansible-inventory
命令,您将看到类似于以下内容的输出:
Output{ "_meta": { "hostvars": { "server1": { "ansible_host": "203.0.113.111" }, "server2": { "ansible_host": "203.0.113.112" }, "server3": { "ansible_host": "203.0.113.113" }, "server4": { "ansible_host": "server_hostname" } } }, "all": { "children": [ "ungrouped" ] }, "ungrouped": { "hosts": [ "server1", "server2", "server3", "server4" ] } }
请注意服务器现在是如何通过别名而不是 IP 地址或主机名来引用的。 这使得在运行命令和 playbook 时更容易定位单个服务器。
第 4 步 — 设置主机变量
可以使用清单文件设置变量,这些变量将在节点上连接和执行命令时更改 Ansible 的默认行为。 这实际上是我们在上一步中设置主机别名时所做的。 ansible_host
变量告诉 Ansible 在哪里可以找到远程节点,以防使用别名来引用该服务器。
可以为每个主机或每个组设置清单变量。 除了自定义 Ansible 的默认设置外,还可以从您的 playbook 访问这些变量,从而可以进一步自定义各个主机和组。
以下示例显示了在连接到此清单文件中列出的每个节点时如何定义默认远程用户:
~/ansible/库存
server1 ansible_host=203.0.113.111 ansible_user=sammy server2 ansible_host=203.0.113.112 ansible_user=sammy server3 ansible_host=203.0.113.113 ansible_user=myuser server4 ansible_host=server_hostname ansible_user=myuser
您还可以创建一个组来聚合具有相似设置的主机,然后在组级别设置它们的变量:
~/ansible/库存
[group_a] server1 ansible_host=203.0.113.111 server2 ansible_host=203.0.113.112 [group_b] server3 ansible_host=203.0.113.113 server4 ansible_host=server_hostname [group_a:vars] ansible_user=sammy [group_b:vars] ansible_user=myuser
这种库存安排将使用 ansible-inventory
生成以下输出:
Output{ "_meta": { "hostvars": { "server1": { "ansible_host": "203.0.113.111", "ansible_user": "sammy" }, "server2": { "ansible_host": "203.0.113.112", "ansible_user": "sammy" }, "server3": { "ansible_host": "203.0.113.113", "ansible_user": "myuser" }, "server4": { "ansible_host": "server_hostname", "ansible_user": "myuser" } } }, "all": { "children": [ "group_a", "group_b", "ungrouped" ] }, "group_a": { "hosts": [ "server1", "server2" ] }, "group_b": { "hosts": [ "server3", "server4" ] } }
请注意,所有库存变量都列在 ansible-inventory
生成的 JSON 输出中的 _meta
节点中。
第 5 步 — 使用模式来定位命令和剧本的执行
使用 Ansible 执行命令和 playbook 时,您必须提供一个目标。 Patterns 允许您定位清单文件中的特定主机、组或子组。 它们非常灵活,支持正则表达式和通配符。
考虑以下清单文件:
~/ansible/库存
[webservers] 203.0.113.111 203.0.113.112 [dbservers] 203.0.113.113 server_hostname [development] 203.0.113.111 203.0.113.113 [production] 203.0.113.112 server_hostname
现在假设您需要执行一个仅针对在生产环境中运行的数据库服务器的命令。 在此示例中,只有 server_hostname
符合该条件; 但是,您可能在该组中有大量数据库服务器。 您可以使用以下模式,而不是单独定位每个服务器:
ansible dbservers:\&production -m ping
&
字符代表逻辑运算 AND
,这意味着有效的目标必须在两个组中。 因为这是在 Bash 上运行的临时命令,所以我们必须在表达式中包含 \
转义字符。
前面的示例将仅针对同时存在于 dbservers
和 production
组中的服务器。 如果您想反其道而行之,仅针对 dbservers
中存在的服务器,但 production
组中的 not 中存在的服务器,则可以改用以下模式:
ansible dbservers:\!production -m ping
要指示目标必须 而不是 在某个组中,您可以使用 !
字符。 再次,我们在表达式中包含 \
转义字符以避免命令行错误,因为 &
和 !
都是可以被 Bash 解析的特殊字符。
下表包含在使用 Ansible 运行命令和 playbook 时可以使用的常见模式的几个不同示例:
图案 | 结果目标 |
---|---|
all
|
清单文件中的所有主机 |
host1
|
单主机(host1 )
|
host1:host2
|
host1 和 host2
|
group1
|
单组(group1 )
|
group1:group2
|
group1 和 group2 中的所有服务器
|
group1:\&group2
|
仅在 group1 和 group2 中 both 的服务器
|
group1:\!group2
|
group1 中的服务器除了 那些也在 group2 中的服务器
|
有关更高级的模式选项,例如使用位置模式和正则表达式来定义目标,请参阅 关于模式的官方 Ansible 文档。
结论
在本指南中,我们详细了解了 Ansible 库存。 我们已经了解了如何将节点组织成组和子组,如何设置库存变量,以及如何在运行命令和 playbook 时使用模式来定位不同的服务器组。
在本系列的下一部分中,我们将了解如何使用 Ansible ad-hoc 命令管理多个服务器。