Ansible 事实缓存配置的综合指南

通过掌握事实缓存配置,优化 Ansible playbook 的执行速度。本指南提供了在您的 `ansible.cfg` 中设置本地 JSON 文件缓存和高性能 Redis 缓存机制的逐步说明。了解如何减少 SSH 开销、设置适当的超时时间以及有效管理事实缓存,从而在大型环境中获得显著的性能提升。

40 浏览量

Ansible Fact Caching 配置的全面指南

Ansible 收集托管节点事实信息(facts)的能力对于动态清单、条件执行和详细报告至关重要。然而,在每次 playbook 执行时都运行 gather_facts: true 会显著增加整体 playbook 的运行时间,尤其是在拥有数百或数千台主机的环境中。这种性能瓶颈可以通过 Ansible Fact Caching 有效解决。

事实缓存允许 Ansible 存储前一次运行中收集到的事实信息,并立即在后续运行中重用它们,从而避免了耗时的 SSH 连接和数据收集过程。本指南将详细介绍如何使用两种主要方法配置和利用事实缓存:JSON 文件和 Redis,从而在您的自动化工作流程中实现显著的性能提升。

理解 Ansible Facts 与性能影响

Ansible 使用 setup 模块(或通过 gather_facts: true 隐式地)收集事实信息。这些事实信息包括操作系统详细信息、网络接口、已安装的软件包等。尽管这些信息非常有价值,但通过 SSH 收集它们可能会很慢,尤其是在高延迟连接或管理大量机器时。

关键性能优势: 通过启用缓存,后续的 playbook 运行将从本地缓存(JSON 文件)或快速的内存存储(Redis)中读取事实信息,而不是在远程主机上执行 setup 模块。

事实缓存的配置方法

Ansible 支持通过 ansible.cfg 文件配置多种缓存机制。最常见和最可靠的两种方法是 JSON 文件缓存和 Redis 缓存。

1. JSON 文件缓存(本地存储)

JSON 缓存是最简单的方法,它将事实数据作为序列化文件存储在控制机上。它不需要任何外部服务。

ansible.cfg 中配置 JSON 缓存

要启用 JSON 缓存,您必须定义缓存插件并指定文件存储的位置。

[defaults]
# 指定要使用的缓存插件
fact_caching = json

# 指定事实文件将存储的目录
fact_caching_connection = /path/to/ansible_facts_cache

# 设置缓存过期时间(秒)。0 表示永不过期。
fact_caching_timeout = 600

参数解释:

  • fact_caching = json: 激活内置的 JSON 缓存插件。
  • fact_caching_connection: 此目录必须存在,并且执行 Ansible 的用户必须有写入权限。
  • fact_caching_timeout: 在此示例中,事实信息在 600 秒(10 分钟)后被视为过期,将重新收集。

最佳实践: 确保缓存目录位于快速的本地存储(如 NVMe 驱动器)上,以获得最佳的读/写性能。

2. Redis 缓存(共享、高性能存储)

Redis 是一种常被用作高性能缓存或消息代理的内存数据结构存储。将 Redis 用于事实缓存非常适合团队环境,在这种环境中,多个用户或 CI/CD 流水线需要快速、一致地访问同一缓存。

Redis 缓存的先决条件

  1. 一个可从 Ansible 控制机访问的运行中的 Redis 服务器。
  2. 控制机上必须安装 Python redis 库:pip install redis

ansible.cfg 中配置 Redis 缓存

使用 Redis 时,fact_caching_connection 用于定义 Redis 连接参数(主机和端口)。

[defaults]
# 指定要使用的缓存插件
fact_caching = redis

# 连接字符串格式:<host>[:<port>][/<db_number>]
# 如果在同一机器上使用默认端口运行:
fact_caching_connection = 127.0.0.1:6379/0

# 设置缓存过期时间(秒)。强烈推荐用于 Redis。
fact_caching_timeout = 3600

关于 Redis 数据库的说明: 最后的数字(例如 /0)指定要使用的 Redis 数据库索引。确保此索引专用于 Ansible 事实,以防止在 Redis 用于其他目的时发生冲突。

将缓存集成到 Playbooks 中

配置 ansible.cfg 设置的是默认行为。要有效利用缓存,您必须确保 playbook 中有两点:

  1. 通过运行收集事实的 play 来填充缓存。
  2. 后续的 play 依赖于缓存而不是重新收集事实。

强制收集事实以进行初始填充

当您第一次运行 playbook,或者在超时后运行 playbook 时,Ansible 将执行事实收集过程。

- name: Play 1 - 收集事实并执行任务
  hosts: webservers
  gather_facts: true  # 这将首先填充缓存
  tasks:
    - name: 使用收集到的事实
      debug:
        msg: "OS 家族是 {{ ansible_os_family }}"

在后续运行中利用缓存

如果配置了 fact_caching,并且 gather_facts 设置为 true 且事实信息在超时期限内,后续运行将自动使用缓存的数据。

然而,如果您想保证 Ansible 完全跳过事实收集并仅依赖缓存(如果缓存丢失则失败),在初始填充后,您可以将 gather_facts 设置为 false,前提是事实信息仍然有效。

如果明确设置 gather_facts: false 并且启用了缓存,Ansible 将首先检查缓存。如果存在有效数据,则使用它。如果不存在,它将继续执行而没有事实信息,这可能会破坏依赖于事实的任务。

关键行为: 如果使用 gather_facts: true,只有在缓存的事实信息已过期或丢失时,Ansible 才会执行远程事实收集。

管理事实缓存

有时需要手动清除缓存,强制 Ansible 从所有主机收集最新数据。

清除 JSON 缓存

如果使用 JSON 缓存,只需删除 fact_caching_connection 中指定的目录的内容。

# 使用前面定义的路径进行示例
rm -rf /path/to/ansible_facts_cache/*

清除 Redis 缓存

如果使用 Redis,您可以选择性地清除与 Ansible 相关的键,或清除 Ansible 使用的整个数据库。

要清除与默认 Ansible 前缀相关的所有键(通常与清单源相关):

# 连接到 redis-cli 并刷新整个数据库(此示例中为 DB 0)
redis-cli -n 0 FLUSHDB

警告: 必须非常谨慎地使用 Redis 中的 FLUSHDBFLUSHALL,因为它会删除指定数据库或整个 Redis 实例中的所有数据。

最佳实践总结

  1. 明智选择: 对于简单的单用户设置或受外部依赖限制的情况,请使用 JSON 缓存。对于协作环境或大规模 CI/CD 集成,请使用 Redis。
  2. 设置合理的超时时间: 配置 fact_caching_timeout 以平衡性能提升和数据新鲜度。对于配置变化不频繁的环境,1 到 24 小时的超时时间很常见。
  3. 验证配置: 始终运行 ansible --version 或检查首次缓存运行的输出,以确认缓存插件已激活并正常工作。
  4. 清单依赖: 事实缓存最适用于静态或动态生成的清单。如果使用频繁更改的动态清单脚本,缓存的好处可能会被过期或错误所抵消。

通过正确实施事实缓存,您可以将 Ansible 从一个完全迭代的配置工具转变为一个高度优化的系统,该系统能够以最小的每次运行延迟来管理大规模的基础设施。