介绍
在本实验中,你将学习如何在 Ansible 中处理多个清单(inventory)。在复杂的环境中,管理多个清单是一种常见场景,尤其是在涉及不同主机组或独立环境的情况下。你将学习如何定义和组织多个清单,访问来自不同清单的主机,并在多个清单之间执行操作。
在本实验中,你将学习如何在 Ansible 中处理多个清单(inventory)。在复杂的环境中,管理多个清单是一种常见场景,尤其是在涉及不同主机组或独立环境的情况下。你将学习如何定义和组织多个清单,访问来自不同清单的主机,并在多个清单之间执行操作。
让我们从创建一个目录来存储清单文件开始,然后为开发环境和生产环境创建两个独立的清单文件。
首先,在 /home/labex/project
路径下创建一个名为 inventory
的新目录:
mkdir -p /home/labex/project/inventory
此命令将创建一个名为 inventory
的新目录。-p
选项确保如果父目录不存在,则会自动创建。
接下来,在 inventory
目录中创建两个清单文件:dev_inventory.ini
和 prod_inventory.ini
:
touch /home/labex/project/inventory/dev_inventory.ini
touch /home/labex/project/inventory/prod_inventory.ini
touch
命令用于创建空文件(如果文件不存在),或者更新文件的修改时间(如果文件已存在)。
接下来,我们将向这些清单文件中添加内容。使用文本编辑器(例如 nano
或你习惯的其他编辑器)打开 dev_inventory.ini
:
nano /home/labex/project/inventory/dev_inventory.ini
添加以下内容:
[dev]
localhost ansible_connection=local
保存文件并退出编辑器(在 nano 中,可以按 Ctrl+X,然后按 Y,最后按 Enter)。
现在,打开 prod_inventory.ini
:
nano /home/labex/project/inventory/prod_inventory.ini
添加以下内容:
[prod]
localhost ansible_connection=local
保存并退出编辑器。
在这些清单文件中:
[dev]
和 [prod]
是组名。它们帮助将主机组织到逻辑组中。localhost
是主机名。我们使用 localhost 来模拟同一台机器上的不同环境。ansible_connection=local
告诉 Ansible 在本地运行命令,而不是尝试通过 SSH 连接到机器。这对于在安装 Ansible 的同一台机器上运行 Ansible 非常有用。在实际场景中,你通常会为开发和生产服务器使用不同的 IP 地址或主机名,而不是为两者都使用 localhost。
在这一步中,我们将创建一个可以同时适用于开发和生产清单的 playbook。在 Ansible 中,playbook 是一个 YAML 文件,用于定义在主机上执行的一组任务。
首先,在 /home/labex/project
目录下创建一个名为 multi_env_playbook.yaml
的新文件:
touch /home/labex/project/multi_env_playbook.yaml
现在,使用文本编辑器打开 multi_env_playbook.yaml
文件。我们将使用 nano
,这是一个简单的命令行文本编辑器:
nano /home/labex/project/multi_env_playbook.yaml
将以下内容复制并粘贴到文件中:
---
- name: Demonstrate multi-environment playbook
hosts: all
gather_facts: no
tasks:
- name: Print environment type
debug:
msg: "This host belongs to the {{ 'production' if 'prod' in group_names else 'development' }} environment"
- name: Show hostname
command: hostname
register: hostname_output
- name: Display hostname
debug:
msg: "The hostname is: {{ hostname_output.stdout }}"
粘贴完成后,按 Ctrl + X
,然后按 Y
,最后按 Enter
保存并退出 nano。
让我们分解这个 playbook,以理解每个部分:
---
表示 YAML 文档的开始。name: Demonstrate multi-environment playbook
是这个 play 的描述性名称。hosts: all
表示这个 playbook 将在清单中的所有主机上运行。gather_facts: no
跳过事实收集阶段以加快执行速度。事实收集是 Ansible 收集目标主机信息的过程。tasks:
开始列出要执行的任务。debug
模块打印一条消息。它使用条件语句来确定主机是属于生产环境还是开发环境:
group_names
是一个特殊变量,包含当前主机所属的所有组的列表。group_names
列表中包含 'prod',则打印 "production",否则打印 "development"。hostname
命令,并将其输出存储在一个名为 hostname_output
的变量中。debug
模块显示主机名。它通过 hostname_output.stdout
访问存储的输出。现在我们已经设置好了 playbook 和清单,接下来让我们使用开发清单运行 playbook。
在终端中执行以下命令:
ansible-playbook -i /home/labex/project/inventory/dev_inventory.ini /home/labex/project/multi_env_playbook.yaml
让我们分解这个命令:
ansible-playbook
是运行 Ansible playbook 的命令。-i /home/labex/project/inventory/dev_inventory.ini
指定要使用的清单文件。-i
选项代表 "inventory"(清单)。/home/labex/project/multi_env_playbook.yaml
是我们的 playbook 文件的路径。此命令告诉 Ansible 使用 dev_inventory.ini
文件并运行 multi_env_playbook.yaml
playbook。
你应该会看到类似以下的输出:
PLAY [Demonstrate multi-environment playbook] *******************************************
TASK [Print environment type] *********************************************************
ok: [localhost] => {
"msg": "This host belongs to the development environment"
}
TASK [Show hostname] ******************************************************************
changed: [localhost]
TASK [Display hostname] ***************************************************************
ok: [localhost] => {
"msg": "The hostname is: 66d80191e483433f91fbdca9"
}
PLAY RECAP ****************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
此输出表明:
hostname
命令)。现在,让我们使用生产清单运行相同的 playbook,看看它的行为有何不同。
在终端中执行以下命令:
ansible-playbook -i /home/labex/project/inventory/prod_inventory.ini /home/labex/project/multi_env_playbook.yaml
此命令与之前的命令类似,但它使用的是 prod_inventory.ini
文件,而不是 dev_inventory.ini
。
你应该会看到类似以下的输出:
PLAY [Demonstrate multi-environment playbook] *********************************
TASK [Print environment type] *************************************************
ok: [localhost] => {
"msg": "This host belongs to the production environment"
}
TASK [Show hostname] **********************************************************
changed: [localhost]
TASK [Display hostname] *******************************************************
ok: [localhost] => {
"msg": "The hostname is: labex-instance"
}
PLAY RECAP ********************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
请注意,这次 playbook 正确地识别出它正在生产环境中运行。这是因为我们使用了生产清单文件,该文件将主机定义在 [prod]
组下。
其余的输出与我们在开发清单中看到的内容类似,这是预期的,因为我们仍然在同一台本地机器上运行。
最后,让我们同时使用两个清单运行 playbook。这将展示 Ansible 如何同时处理多个清单。
在终端中执行以下命令:
ansible-playbook -i /home/labex/project/inventory/dev_inventory.ini -i /home/labex/project/inventory/prod_inventory.ini /home/labex/project/multi_env_playbook.yaml
此命令通过多个 -i
选项包含了两个清单文件。Ansible 在运行 playbook 时会合并这些清单。
你应该会看到类似以下的输出:
PLAY [Demonstrate multi-environment playbook] *******************************************************************************************************************************************************************************************************************************************
TASK [Print environment type] ***********************************************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "This host belongs to the production environment"
}
TASK [Show hostname] ********************************************************************************************************************************************************************************************************************************************************************
changed: [localhost]
TASK [Display hostname] *****************************************************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "The hostname is: 66d80191e483433f91fbdca9"
}
PLAY RECAP ******************************************************************************************************************************************************************************************************************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
你可能会注意到,尽管我们包含了两个清单,但 playbook 只运行了一次。这是因为两个清单都引用了同一个 localhost
,而 Ansible 默认会去重主机。如果每个清单中有不同的主机,Ansible 会为每个唯一的主机运行 playbook。
环境被识别为 "development",因为开发清单文件在命令中首先被指定。Ansible 在确定组归属时使用主机的第一个匹配项。
这种使用多个清单的方法在实际场景中非常有用,例如当你在不同环境中拥有共同的主机,或者希望针对来自不同清单文件的主机组合运行 playbook 时。
在本实验中,你学习了如何管理多个 Ansible 清单。你为开发和生产环境创建了单独的清单文件,编写了一个可以适用于两种环境的 playbook,并使用不同的清单配置执行了 playbook。
本实验的关键要点包括:
这些技能在管理具有不同环境的复杂基础设施时至关重要。通过利用多个清单,你可以更好地组织和控制跨不同主机集或环境的 Ansible 自动化。