Ansible 架构
Ansible 是一个极其简单的 IT 自动化引擎,可实现云端置备、配置管理、应用程序部署、服务间编排以及许多其他 IT 需求的自动化。
Ansible 从设计之初就面向多层部署,它通过描述所有系统如何相互关联来对您的 IT 基础设施进行建模,而不是一次仅管理一个系统。
它无需代理(agent)且无需额外的自定义安全基础设施,因此易于部署 —— 最重要的是,它使用一种非常简单的语言(以 Ansible Playbooks 形式呈现的 YAML),让您能够以接近英语自然语言的方式来描述自动化任务。
在本节中,我们将快速概述 Ansible 的工作原理,以便您了解各组件是如何协同工作的。
模块 (Modules)
Ansible 的工作方式是连接到您的节点并向其推送称为“Ansible 模块”的脚本。大多数模块接受描述系统期望状态的参数。然后 Ansible 执行这些模块(默认通过 SSH),并在完成后将其删除。您的模块库可以驻留在任何机器上,且不需要服务器、守护进程或数据库。
您可以编写自己的模块,但在开始之前,您应该先考虑是否真的需要这样做。通常,您将使用您最喜欢的终端程序、文本编辑器,以及可能是一个版本控制系统来跟踪内容的更改。您可以使用任何能返回 JSON 的语言编写专用模块(如 Ruby、Python、bash 等)。
模块实用程序 (Module utilities)
当多个模块使用相同的代码时,Ansible 将这些函数存储为模块实用程序,以尽量减少重复和维护工作。例如,解析 URL 的代码位于 lib/ansible/module_utils/url.py。您也可以编写自己的模块实用程序。模块实用程序只能用 Python 或 PowerShell 编写。
插件 (Plugins)
插件 增强了 Ansible 的核心功能。模块在目标系统的独立进程中执行(通常意味着在远程系统上),而插件在控制节点内的 /usr/bin/ansible 进程中执行。插件为 Ansible 的核心功能提供了选项和扩展 —— 如转换数据、记录输出、连接到清单(inventory)等。Ansible 附带了许多便捷的插件,您也可以轻松编写自己的插件。例如,您可以编写一个清单插件来连接到任何返回 JSON 的数据源。插件必须用 Python 编写。
清单 (Inventory)
默认情况下,Ansible 在一个文件中(INI, YAML 等)表示其管理的机器,将所有受管机器放入您自行选择的分组中。
在添加新机器时,无需涉及额外的 SSL 签名服务器,因此您再也不必为了纠结某台机器为何因模糊的 NTP 或 DNS 问题而无法连接而感到苦恼。
如果您的基础设施中存在另一个真值源(source of truth),Ansible 也可以连接到该源。Ansible 可以从 EC2、Rackspace、OpenStack 等来源获取清单、分组和变量信息。
以下是一个纯文本清单文件的样子
[webservers]
www1.example.com
www2.example.com
[dbservers]
db0.example.com
db1.example.com
清单主机列出后,可以在简单的文本文件中(在名为 'group_vars/' 或 'host_vars/' 的子目录中)或直接在清单文件中为它们分配变量。
或者,如前所述,使用动态清单从 EC2、Rackspace 或 OpenStack 等数据源提取您的清单。
剧本 (Playbooks)
剧本可以精细地编排基础设施拓扑的多个切片,并能非常详细地控制一次处理多少台机器。这是 Ansible 开始变得最有趣的地方。
Ansible 的编排方法是追求精细调优的简洁,因为我们认为您的自动化代码在数年后对您来说仍然应该是完全易懂的,且关于特殊语法或功能的记忆成本应极低。
以下是一个简单的剧本样子
---
- hosts: webservers
serial: 5 # update 5 machines at a time
roles:
- common
- webapp
- hosts: content_servers
roles:
- common
- content
Ansible 搜索路径
模块、模块实用程序、插件、剧本和角色可以存在于多个位置。如果您编写自己的代码来扩展 Ansible 的核心功能,在 Ansible 控制节点的不同位置可能会有多个名称相似或相同的文件。搜索路径决定了 Ansible 在任何给定的剧本运行时会发现并使用哪些文件。
Ansible 的搜索路径在运行过程中递增增长。当 Ansible 找到给定运行中包含的每个剧本和角色时,它会将与该剧本或角色相关的任何目录附加到搜索路径中。这些目录在运行期间一直处于作用域内,即使在剧本或角色执行完毕后也是如此。Ansible 按以下顺序加载模块、模块实用程序和插件:
命令行指定的剧本相邻目录。如果您使用
ansible-playbook /path/to/play.yml运行 Ansible,如果这些目录存在,Ansible 将其附加/path/to/modules /path/to/module_utils /path/to/plugins
由命令行指定的剧本静态导入的剧本相邻目录。如果
play.yml包含- import_playbook: /path/to/subdir/play1.yml,如果这些目录存在,Ansible 将其附加/path/to/subdir/modules /path/to/subdir/module_utils /path/to/subdir/plugins
剧本引用的角色目录的子目录。如果
play.yml运行myrole,如果这些目录存在,Ansible 将其附加/path/to/roles/myrole/modules /path/to/roles/myrole/module_utils /path/to/roles/myrole/plugins
在
ansible.cfg中或通过相关环境变量指定的默认路径目录,包括各种插件类型的路径。有关更多信息,请参阅Ansible 配置设置。ansible.cfg字段示例DEFAULT_MODULE_PATH DEFAULT_MODULE_UTILS_PATH DEFAULT_CACHE_PLUGIN_PATH DEFAULT_FILTER_PLUGIN_PATH
环境变量示例
ANSIBLE_LIBRARY ANSIBLE_MODULE_UTILS ANSIBLE_CACHE_PLUGINS ANSIBLE_FILTER_PLUGINS
随 Ansible 发行版一起提供的标准目录。
注意
用户指定目录中的模块、模块实用程序和插件将覆盖标准版本。这包括一些具有通用名称的文件。例如,如果您在用户指定目录中有一个名为 basic.py 的文件,它将覆盖标准的 ansible.module_utils.basic。
如果您在不同的用户指定目录中拥有多个同名的模块、模块实用程序或插件,那么命令行中的命令顺序以及每个 play 中的 include 和 role 顺序将影响在特定 play 中找到并使用哪一个。