什么是 Ansible?Ansible 是一款功能强大且易于使用的现代应用程序部署和配置管理工具。它使得从单个控制节点处理数以千计的远程服务器(也称为受管节点)变得容易。Ansible 允许您轻松地重现配置环境,并避免您登录到单个服务器并一台一台地配置它们。
即使在 Ansible 中跟踪数以千计的远程服务器也可能变得很麻烦,因此了解如何使用称为清单文件的特殊文件对托管节点进行分组和定位至关重要。
什么是 Ansible 库存文件?
Ansible 清单文件允许系统管理员跟踪他们管理的远程系统。默认清单文件称为hosts文件,位于/etc/ansible目录中。这是指定所有受管远程节点的地方。
Ansible 还使您可以灵活地在控制节点上的首选位置创建自定义清单文件以满足您的偏好。当您拥有复杂的环境并且需要将受管节点隔离到单独的清单文件而不是将它们全部放在hosts文件中时,这是理想的选择。
在本指南中,您将安装 Ansible 并在控制节点上设置自定义清单文件。
先决条件
为了演示如何在清单文件中定义远程服务器,我们将使用以下设置,其中所有服务器都部署了 Ubuntu 20.04 操作系统:
Ansible 控制节点:这是安装 Ansible 的服务器。它用于通过 SSH 连接到您的托管节点并管理它们。
托管节点:这些是将从 Ansible 控制节点管理的远程节点:
节点 1: 198.148.118.68
节点 2: 198.148.118.129
我们的小型实验室设置足以说明您如何使用 Ansible 清单文件来管理您的远程系统。但是,您可以拥有的托管节点的数量没有限制。
在 Ubuntu 20.04 上安装 Ansible
我们的第一步是在控制节点上安装 Ansible。因此,通过 SSH 或使用免费的 SSH 客户端(如PuTTY )登录到您的控制节点。
登录后,通过运行以下命令更新系统包列表。-y 选项自动假定“是”作为对所有命令行提示的回答。
sudo apt update
接下来,安装 Ansible:
sudo apt install -y ansible
这将安装 Ansible 和许多其他附加包和依赖项。完成后,通过检查 Ansible 的版本来验证是否安装了 Ansible:
ansible –-version
下面的输出证明我们已经成功安装了 Ansible 2.9.6 版本。
如前所述,默认清单文件位于 /etc/ansible/hosts。使用首选命令行编辑器打开文件后,您将看到一些关于预期内容的基本指南。
sudo nano /etc/ansible/hosts
# This is the default ansible 'hosts' file. # # It should live in /etc/ansible/hosts # # - Comments begin with the '#' character # - Blank lines are ignored # - Groups of hosts are delimited by [header] elements # - You can enter hostnames or ip addresses # - A hostname/ip can be a member of multiple groups # Ex 1: Ungrouped hosts, specify before any group headers: ## green.example.com ## blue.example.com ## 192.168.100.1 ## 192.168.100.10 # Ex 2: A collection of hosts belonging to the 'webservers' group: ## [webservers] ## alpha.example.org ## beta.example.org ## 192.168.1.100 ## 192.168.1.110
默认情况下,所有条目都被注释掉并且没有指定主机。在下一步中,您将连接到远程主机并创建自定义清单文件。
设置无密码 SSH 连接
Ansible 是一种无代理部署工具,它使用 SSH 协议与远程节点进行通信。为了无缝地实现这一点,我们需要采取额外的步骤,在 Ansible 控制节点和远程系统之间配置一个无密码的 SSH 连接。
首先,使用以下命令生成 SSH 密钥对:
ssh-keygen
它将创建一个 SSH 密钥对,其中包含存储在您主目录的 .ssh/ 文件夹中的公钥和私钥。
私钥应保留在 Ansible 控制节点上,绝不能泄露或与任何人共享,以避免中间人攻击等安全漏洞。另一方面,您可以轻松地与您选择的任何远程系统共享公钥。
要成功配置无密码 SSH 连接,您需要将公钥复制到远程节点。ssh-copy-id您可以使用所示语法中的命令轻松执行此操作:
ssh-copy-id user@server-ip-address
在我们的例子中,命令将是:
ssh-copy-id root@198.148.118.68
出现提示时输入远程系统的密码,然后按 ENTER 键将公钥复制到服务器。
为了验证我们是否可以在没有密码身份验证的情况下登录到远程系统,我们将尝试通过 SSH 登录,方法是证明用户名后跟“@”,然后是远程节点的 IP 地址。
ssh root@198.148.118.68
下面提供的代码片段是对我们刚刚在没有密码的情况下登录到远程 node1 的确认。
公钥保存在~/.ssh/authorized_keys远程节点的文件中。
您可以仔细检查它是否存在:
cat ~/.ssh/authorized_keys
对所有节点重复相同的过程,并确保您可以在没有密码身份验证的情况下通过 SSH 连接到它们。
创建自定义库存文件
Ansible 使用位于的默认清单文件来引用托管节点,除非您通过该选项/etc/ansible/hosts指定自定义清单文件。-i
默认的清单文件工作得很好。实际上,您可以使用远程节点的 IP 地址将其放入其中,如下所示:
198.148.118.68 198.148.118.129
然后,您可以在远程节点上执行 ping 模块,而无需明确指定远程主机:
sudo ansible -m ping all
当然,这没有任何问题,但是当面对不同项目下的多个托管节点时,最佳做法是为每个项目创建单独的清单文件。通过这种方式,您将促进资源跟踪并更轻松地与其他系统管理员协作,而无需让每个人都纠结在一个hosts文件中。
现在,让我们创建一个自定义清单文件。为此,您应该首先创建一个项目目录并导航到其中:
mkdir project_dir && cd project_dir
接下来,创建一个简单的文本文件。您可以给它任意名称:
nano inventory
然后使用它们的 IP 地址每行列出您的托管节点:
198.148.118.68 198.148.118.129
保存更改并退出文件。ansible-inventory现在您可以使用命令验证托管主机。请注意,使用该-i选项时必须引用清单文件的完整路径。
ansible-inventory -i project_dir/inventory --list
从这里,您可以使用自定义清单文件在托管主机上执行剧本或 ping 模块:
sudo ansible -i project_dir/inventory -m ping all
将节点组织成组和子组
为了更清晰的清单文件和更轻松地管理您的受管节点,通常建议将它们组织成组和子组。
一台主机可以属于一个或多个组。在下面的示例中,我们webservers以 INI 格式将 2 台主机分组到该组下。
[webservers] 198.148.118.68 198.148.118.129
下面的清单文件更好地说明了多台服务器被分为不同的组,例如webservers,load_balancers和db_servers.
[webservers] 198.148.118.68 198.148.118.129 198.148.118.150 198.148.118.175 [load_balancers] 198.148.118.100 198.148.118.200 [db_servers] 198.148.118.50 198.148.118.60
再次运行ansible-inventory命令,您应该会看到与此处类似的安排:
ansible-inventory -i project_dir/inventory --list
您还可以将多个组定义为“父”组下的“子”组。在这种情况下,“父”组成为元组。以下是如何使用元组重新组织以前的清单的说明:
[childgroup1] node1 node2 [childgroup2] node3 node4 [parent1:children] childgroup1 childgroup2
考虑到这一点,我们可以重新组织我们的库存,如下所示。
[webservers_miami] 198.148.118.68 198.148.118.129 [webservers_virginia] 198.148.118.150 198.148.118.175 [load_balancer_ohio] 198.148.118.100 [load_balancer_texas] 198.148.118.200 [db_server_miami] 198.148.118.50 [db_server_virginia] 198.148.118.60 [webservers:children] webservers_miami webservers_virginia [load_balancers:children] load_balancer_ohio load_balancer_texas [db_servers:children] db_server_miami db_server_virginia
再次,您可以按如下方式验证库存清单:
ansible-inventory -i project_dir/inventory --list
这样的安排可以帮助您使用剧本来定位较小的服务器组,而不是一次定位所有节点。例如,您可以在[webservers_miami]子组中执行 ping 模块,如下所示:
sudo ansible -i project_dir/inventory -m ping webservers_miami
使用模式来定位命令的执行
使用 Ansible 运行剧本或临时命令时,您需要提供通常在清单文件中定义的目标。模式可以灵活地定位清单文件中的特定主机或组。它们支持通配符、正则表达式等等。
为了演示如何使用模式,请考虑下面的清单文件:
[webservers] 198.148.118.68 198.148.118.129 198.148.118.160 [db_servers] 198.148.118.55 198.148.118.110 [staging] 198.148.118.160 198.148.118.110 [production] 198.148.118.68 198.148.118.129 198.148.118.55
假设您要执行一个仅针对生产环境中运行的 Web 服务器的临时命令。在此清单中,只有两个网络服务器符合此条件:198.148.118.68和198.148.118.129。
您可以简单地使用以下匹配模式,而不是分别针对两个目标主机:
sudo ansible webservers:\&production -m ping
& 符号 - & - 表示逻辑运算 AND。这意味着有效的主机必须在两个组中,即webservers和production。由于这是一个临时命令,我们需要\在命令中插入转义符。
要定位webservers组中但不在 中的主机production,请使用以下模式:
sudo ansible webservers:\!production -m ping
此处,!符号表示逻辑运算符 NOT,它表示有效主机不得包含在production组中。再一次,我们需要包含\转义字符,因为我们正在运行一个必须由 shell 解释的临时命令。
下表提供了在使用 Ansible 自动化工具运行临时命令和剧本时可以使用的其他模式。
图案 | 目标 |
---|---|
all | 清单文件中的所有目标 |
node1 | 单个节点或主机 ( node1) |
node1:node2 | 和node1_node2 |
group1 | group1仅适用于所有主机 |
group1:group2 | 适用于所有group1主机group2 |
group1:\&group2 | 两者兼有的主机或group1服务器group2 |
group1:\&group2 | 主机或服务器在group1但不在group2 |
配置主机别名
别名是引用受管节点的一种简单方法。就像昵称一样,它们可以帮助您轻松识别您的资源,而无需在运行剧本时回忆复杂的名称。
要定义别名,只需指定一个别名,后跟一个与远程主机的主机名或 IP 相对应的变量名。
alias variable_name
例如:
primary_server ansible_host=198.148.118.68` secondary_server ansible_host=198.148.118.129`
然后验证清单列表以检查节点是否被别名引用。
ansible-inventory -i project_dir/inventory --list
从输出中我们可以看到服务器现在被它们的别名所引用。您还可以通过使用别名引用节点来运行临时命令:
sudo ansible -i project_dir/inventory -m ping primary_server
配置变量名称
在 Ansible 中,变量用于处理托管主机之间的差异。使用变量,您可以在执行剧本或临时命令时表示系统之间的差异。例如,在上一节中,我们使用了ansible_host简单地告诉 Ansible 在哪里搜索托管节点的 IP 地址的变量。
在清单文件中,您可以使用变量来定义主机名、连接类型、端口等。在下面的示例中,我们进一步定义了用于启动到节点的远程连接的用户。
在这种情况下,我们有两个变量:ansible_host指定主机的 IP,以及ansible_user指定用于连接远程主机的用户。
server01 ansible_host=198.148.118.68 ansible_user=root server02 ansible_host=198.148.118.129 ansible_user=user
此外,您还可以创建主机组并在组级别具有变量。在这个例子中,我们有两个独立的变量组——[webservers_a:vars]它们[webservers_b:vars]定义了连接到被管节点的用户。
[webservers_a] server01 ansible_host=198.148.118.68 [webservers_b] server02 ansible_host=198.148.118.129 [webservers_a:vars] ansible_user=root [webservers_b:vars] ansible_user=user
结论
在本教程中,我们深入研究了 Ansible 清单,并演示了如何将托管主机组织成组和子组。然后我们更进一步,演示了如何使用模式来定位特定的主机组,触及别名,最后用允许某些关键参数因主机而异的变量结束。