Полное руководство по настройке кэширования фактов Ansible
Возможность Ansible собирать факты об управляемых узлах имеет решающее значение для динамического инвентарирования, выполнения по условию и детальной отчетности. Однако запуск gather_facts: true при каждом выполнении плейбука может значительно увеличить общее время выполнения плейбука, особенно в средах с сотнями или тысячами хостов. Это узкое место в производительности эффективно устраняется с помощью кэширования фактов Ansible (Ansible Fact Caching).
Кэширование фактов позволяет Ansible сохранять собранные факты из предыдущего запуска и мгновенно повторно использовать их при последующих запусках, минуя трудоемкие SSH-соединения и процесс сбора данных. В этом руководстве подробно описано, как настроить и использовать кэширование фактов с помощью двух основных методов: файлов JSON и Redis, что обеспечивает значительное повышение производительности ваших рабочих процессов автоматизации.
Понимание фактов Ansible и их влияния на производительность
Ansible собирает факты с помощью модуля setup (или неявно через gather_facts: true). Эти факты включают сведения об операционной системе, сетевых интерфейсах, установленных пакетах и многое другое. Хотя сбор этих фактов неоценим, он может быть медленным при использовании SSH, особенно при соединениях с высокой задержкой или при управлении большим парком машин.
Ключевое преимущество в производительности: Включение кэширования позволяет последующим запускам плейбуков считывать факты из локального кэша (файл JSON) или быстрого хранилища в оперативной памяти (Redis) вместо выполнения модуля setup на удаленных хостах.
Методы настройки кэширования фактов
Ansible поддерживает несколько механизмов кэширования, настраиваемых через файл ansible.cfg. Двумя наиболее распространенными и надежными методами являются кэширование в файлах JSON и кэширование в Redis.
1. Кэширование в файлах JSON (локальное хранилище)
Кэширование JSON является самым простым методом, сохраняя данные фактов в виде сериализованных файлов на управляющей машине. Оно не требует внешних сервисов.
Настройка кэширования JSON в ansible.cfg
Чтобы включить кэширование 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
- Работающий сервер Redis, доступный с управляющей машины Ansible.
- Библиотека Python
redisдолжна быть установлена на управляющей машине:pip install redis.
Настройка кэширования в Redis в ansible.cfg
При использовании 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 используется для других целей.
Интеграция кэширования в плейбуки
Настройка ansible.cfg определяет поведение по умолчанию. Чтобы эффективно использовать кэширование, необходимо обеспечить две вещи в ваших плейбуках:
- Кэш заполняется при запуске операции, собирающей факты.
- Последующие операции полагаются на кэш, а не на повторный сбор фактов.
Принудительный сбор фактов для первоначального заполнения
Когда вы запускаете плейбук в первый раз или после истечения таймаута, Ansible выполнит процесс сбора фактов.
- name: Play 1 - Gather Facts and Execute Tasks
hosts: webservers
gather_facts: true # Это первоначально заполняет кэш
tasks:
- name: Use gathered facts
debug:
msg: "OS Family is {{ 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
Предупреждение: Команды
FLUSHDBилиFLUSHALLв Redis следует использовать с особой осторожностью, поскольку они удаляют все данные в указанной базе данных или во всем экземпляре Redis соответственно.
Резюме лучших практик
- Выбирайте мудро: Используйте кэширование JSON для простых установок с одним пользователем или в случаях, когда внешние зависимости ограничены. Используйте Redis для совместных сред или крупномасштабной интеграции CI/CD.
- Устанавливайте реалистичные таймауты: Настройте
fact_caching_timeout, чтобы найти баланс между приростом производительности и актуальностью данных. Таймаут от 1 до 24 часов является обычным явлением для сред, где конфигурации меняются нечасто. - Проверяйте конфигурацию: Всегда запускайте
ansible --versionили проверяйте вывод первого кэшированного запуска, чтобы убедиться, что плагин кэша активен и функционирует. - Зависимость от инвентаризации: Кэширование фактов лучше всего работает со статическими или динамически генерируемыми инвентаризациями. Если используются скрипты динамической инвентаризации, которые часто меняются, преимущество кэширования может быть сведено на нет устареванием или ошибками.
Правильно внедрив кэширование фактов, вы превращаете Ansible из полностью итеративного инструмента настройки в высокооптимизированную систему, способную управлять инфраструктурой в огромных масштабах с минимальной задержкой при каждом запуске.