管理多个 Ansible 清单

AnsibleAnsibleBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

介绍

在本实验中,你将学习如何在 Ansible 中处理多个清单(inventory)。在复杂的环境中,管理多个清单是一种常见场景,尤其是在涉及不同主机组或独立环境的情况下。你将学习如何定义和组织多个清单,访问来自不同清单的主机,并在多个清单之间执行操作。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL ansible(("`Ansible`")) -.-> ansible/AnsibleSetupandConfigurationGroup(["`Ansible Setup and Configuration`"]) ansible(("`Ansible`")) -.-> ansible/ModuleOperationsGroup(["`Module Operations`"]) ansible(("`Ansible`")) -.-> ansible/InventoryManagementGroup(["`Inventory Management`"]) ansible(("`Ansible`")) -.-> ansible/PlaybookEssentialsGroup(["`Playbook Essentials`"]) ansible/AnsibleSetupandConfigurationGroup -.-> ansible/install("`Ansible Setup`") ansible/ModuleOperationsGroup -.-> ansible/debug("`Test Output`") ansible/InventoryManagementGroup -.-> ansible/groups_inventory("`Define Inventory Groups`") ansible/InventoryManagementGroup -.-> ansible/mutil_inventory("`Multiple Inventory Sources`") ansible/PlaybookEssentialsGroup -.-> ansible/playbook("`Execute Playbook`") subgraph Lab Skills ansible/install -.-> lab-290193{{"`管理多个 Ansible 清单`"}} ansible/debug -.-> lab-290193{{"`管理多个 Ansible 清单`"}} ansible/groups_inventory -.-> lab-290193{{"`管理多个 Ansible 清单`"}} ansible/mutil_inventory -.-> lab-290193{{"`管理多个 Ansible 清单`"}} ansible/playbook -.-> lab-290193{{"`管理多个 Ansible 清单`"}} end

创建清单目录和文件

让我们从创建一个目录来存储清单文件开始,然后为开发环境和生产环境创建两个独立的清单文件。

首先,在 /home/labex/project 路径下创建一个名为 inventory 的新目录:

mkdir -p /home/labex/project/inventory

此命令将创建一个名为 inventory 的新目录。-p 选项确保如果父目录不存在,则会自动创建。

接下来,在 inventory 目录中创建两个清单文件:dev_inventory.iniprod_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

在这一步中,我们将创建一个可以同时适用于开发和生产清单的 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,以理解每个部分:

  1. 文件顶部的 --- 表示 YAML 文档的开始。
  2. name: Demonstrate multi-environment playbook 是这个 play 的描述性名称。
  3. hosts: all 表示这个 playbook 将在清单中的所有主机上运行。
  4. gather_facts: no 跳过事实收集阶段以加快执行速度。事实收集是 Ansible 收集目标主机信息的过程。
  5. tasks: 开始列出要执行的任务。
  6. 第一个任务使用 debug 模块打印一条消息。它使用条件语句来确定主机是属于生产环境还是开发环境:
    • group_names 是一个特殊变量,包含当前主机所属的所有组的列表。
    • 如果 group_names 列表中包含 'prod',则打印 "production",否则打印 "development"。
  7. 第二个任务运行 hostname 命令,并将其输出存储在一个名为 hostname_output 的变量中。
  8. 第三个任务使用 debug 模块显示主机名。它通过 hostname_output.stdout 访问存储的输出。

使用开发清单运行 Playbook

现在我们已经设置好了 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

此输出表明:

  1. Playbook 在开发环境中成功运行。
  2. 它正确地识别出主机属于开发环境。
  3. 它成功获取并显示了主机名。
  4. "PLAY RECAP" 显示了 playbook 执行的摘要。在这里,"ok=3" 表示三个任务成功执行,"changed=1" 表示一个任务对系统进行了更改(运行了 hostname 命令)。

使用生产清单运行 Playbook

现在,让我们使用生产清单运行相同的 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

最后,让我们同时使用两个清单运行 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。

本实验的关键要点包括:

  1. 创建和组织多个清单文件:你学习了如何为不同的环境创建单独的清单文件,这有助于组织和管主机。
  2. 编写能够适应不同环境的 playbook:你创建了一个 playbook,它可以检查当前运行的环境并相应地调整其行为。
  3. 使用单个或多个清单运行 playbook:你学习了如何在运行 playbook 时指定一个或多个清单文件,从而灵活地选择目标主机。
  4. 理解 Ansible 如何处理出现在多个清单中的主机:你了解到 Ansible 会去重主机,并在确定组归属时使用主机的第一个匹配项。

这些技能在管理具有不同环境的复杂基础设施时至关重要。通过利用多个清单,你可以更好地组织和控制跨不同主机集或环境的 Ansible 自动化。

您可能感兴趣的其他 Ansible 教程