运用动态仓库
如果咱们的 Ansible 会随时间波动,其中的主机会根据业务需求启动或关闭,那么 如何建立清单 中描述的静态仓库解决方案,将无法满足咱们的需求。咱们可能需要从多个来源跟踪主机:云服务提供商、LDAP、Cobbler 和/或企业的 CMDB 系统等。
Ansible 通过动态外部仓库系统,集成了所有这些选项。Ansible 支持两种连接外部仓库方式: 仓库插件 和 仓库脚本。
仓库插件会用到 Ansible Core 代码的最新更新。对于动态仓库,我们推荐使用插件而非脚本。你可以 编写自己的插件,连接到更多的动态仓库源。
如果愿意,咱们仍可使用仓库脚本。在实现仓库插件时,我们通过脚本仓库插件,确保向后兼容性。下面的示例说明了如何使用仓库脚本。
如果咱们偏好用图形用户界面,来处理动态仓库,那么 AWX 或 Red Hat Ansible Automation Platform 上的仓库数据库,会同步咱们所有的动态仓库源,提供了对结果的 Web 和 REST 访问,并提供图形化的仓库编辑器。有了全部主机的数据库记录,咱们就可以关联过去的事件历史,查看哪些主机在上一次 playbooks 运行过程中出现了故障。
仓库脚本示例:Cobbler
Ansible 与 Cobbler 无缝集成,Cobbler 是个 Linux 安装服务器,最初由 Michael DeHaan 编写,现在由在 Ansible 工作的 James Cammarata 领导。
虽然 Cobbler 主要用于启动操作系统安装,以及管理 DHCP 和 DNS,但他有个可表示多种配置管理系统(甚至同时)数据的通用层,而充当了一种 “轻量级的 CMDB”。
要将 Ansible 清单与 Cobbler 绑定,请将 此脚本 复制到 /etc/ansible
并 chmod +x
该文件。在使用 Ansible 的任何时候,请运行 cobblerd
,并使用 -i
命令行选项(如 -i /etc/ansible/cobbler.py
),来使用 Cobbler 的 XMLRPC API 与 Cobbler 通信。
在 /etc/ansible
目录下,添加 cobbler.ini
文件,这样 Ansible 就能知道 Cobbler 服务器的位置,以及一些可供使用的缓存改进。例如:
[cobbler]
# 设置 Cobbler 的主机名或 IP 地址
host = http://127.0.0.1/cobbler_api
# 到 Cobbler 的 API 调用可能较慢。为此,咱们就要缓存某次 API 调用的
# 结果。请将此设置为咱们打算缓存文件要写入的路径。有两个文件将被
# 写入到该目录下:
# - ansible-cobbler.cache
# - ansible-cobbler.index
cache_path = /tmp
# 缓存文件被视为有效的秒数。在此之后,将构造一次新的 API 调用,同时
# 该缓存文件将被更新。
cache_max_age = 900
首先直接运行 /etc/ansible/cobbler.py
测试脚本。咱们应会看到一些 JSON 数据输出,但其中可能还没有任何内容。
咱们来探讨一下他做了些什么。在 Cobbler 中,假设一个类似下面的场景:
cobbler profile add --name=webserver --distro=CentOS6-x86_64
cobbler profile edit --name=webserver --mgmt-classes="webserver" --ksmeta="a=2 b=3"
cobbler system edit --name=foo --dns-name="foo.example.com" --mgmt-classes="atlanta" --ksmeta="c=4"
cobbler system edit --name=bar --dns-name="bar.example.com" --mgmt-classes="atlanta" --ksmeta="c=5"
在上面的例子中,Ansible 可以直接寻址到系统 foo.example.com
,但使用组名 webserver
或 atlanta
时,也可以寻址到。由于 Ansible 使用 SSH,他只能通过 foo.example.com
与系统 foo
联系,而不能仅是 foo
。同样,如果咱们尝试使用 ansible foo
,他就会找不到系统......但使用 ansible 'foo*'
就可以,因为系统的 DNS 名称是以 foo
开头的。
该脚本提供的不仅仅是主机和组信息。此外,作为奖励,当 setup
模组运行时(使用 playbook 时他会自动运行),变量 a
、b
和 c
都会自动填充到模板中:
# file: /srv/motd.j2
Welcome, I am templated with a value of a={{ a }}, b={{ b }}, and c={{ c }}
这可以这样执行:
ansible webserver -m setup
ansible webserver -m template -a "src=/tmp/motd.j2 dest=/etc/motd"
注意:
webserver
这个名字来自于 Cobbler,配置文件的变量也是如此。咱们仍可以像在 Ansible 中一样,传递咱们自己的变量,但来自外部仓库脚本的变量,将覆盖所有同名变量。
因此,使用上述模板(motd.j2
)后,以下数据将被写入系统 foo
的 /etc/motd
:
Welcome, I am templated with a value of a=2, b=3, and c=4
而在系统 bar
(bar.example.com
)上:
Welcome, I am templated with a value of a=2, b=3, and c=5
且从技术上讲,尽管没有什么充分的理由,但这也是可行的:
ansible webserver -m ansible.builtin.shell -a "echo {{ a }}"
因此,换句话说,咱们也可以在参数/操作中,使用这些变量。
其他仓库脚本
在 Ansible 2.10 及更高版本中,仓库脚本移到了他们的相关专辑中。许多脚本现在都在 ansible-community/contrib-scripts 代码库中。我们建议使用 仓库插件。
使用仓库目录与多仓库来源
如果在 Ansible 中给到 -i
的位置,是个目录(或在 ansible.cfg
中这样配置了),那么 Ansible 就可以同时使用多个仓库源。这样,就可以在同一次 ansible
运行中,混合使用动态和静态管理的仓库源。这就是即时混合云!
在仓库目录下,可执行文件就被视为动态仓库源,而大多数其他文件则被视为静态源。以下列文件扩展名结尾的文件将被忽略:
~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo
通过在 ansible.cfg
中配置 inventory_ignore_extensions
列表,或设置 ANSIBLE_INVENTORY_IGNORE
环境变量,咱们可以用自己的选项,替换该列表。两种情况下的值,都必须是以逗号分隔的模式列表,如上所示。
仓库目录中的任何 group_vars
和 host_vars
子目录,都会如预期那样进行解析,从而使仓库目录成为组织不同配置集的有效方式。更多信息,请参阅 传递多个仓库源。
动态组构成的静态组
Static groups of dynamic groups
在静态仓库文件中定义组别时,子组别也必须在静态仓库文件中定义,否则 ansible
会返回错误。如果要定义动态子组的静态组,请在静态仓库文件中,将该动态组定义为空。例如:
[tag_Name_staging_foo]
[tag_Name_staging_bar]
[staging:children]
tag_Name_staging_foo
tag_Name_staging_bar
(End)