Максимизация производительности Ansible с помощью ControlPersist и Pipelining

Значительно повысьте производительность ваших плейбуков Ansible, включив повторное использование SSH-соединений с помощью ControlPersist и оптимизировав выполнение модулей через Pipelining. Это руководство предоставляет важную информацию и практические настройки для сокращения времени выполнения, особенно в крупномасштабных средах. Узнайте, как настроить ваш файл `ansible.cfg` для более быстрой и эффективной автоматизации ИТ.

31 просмотров

Максимизация производительности Ansible с помощью ControlPersist и Pipelining

Ansible — это мощный инструмент для автоматизации ИТ-инфраструктуры, позволяющий управлять конфигурациями и развертывать приложения в большом масштабе. Однако в средах с высокой нагрузкой или при управлении большим количеством узлов накладные расходы, связанные с установкой SSH-соединений для каждой задачи, могут стать серьезным узким местом. Это может привести к очень медленному выполнению плейбуков. К счастью, Ansible предлагает две мощные функции — ControlPersist и Pipelining — которые могут значительно повысить производительность за счет оптимизации взаимодействия Ansible с управляемыми узлами.

В этом руководстве мы разберем понимание и внедрение ControlPersist и Pipelining. Используя эти методы, вы можете значительно сократить время выполнения, сделав автоматизацию Ansible более эффективной и отзывчивой, особенно в средах с сотнями или тысячами хостов. Освоение этих оптимизаций крайне важно для всех, кто стремится эффективно масштабировать свои развертывания Ansible.

Понимание стандартного поведения подключения Ansible

По умолчанию Ansible устанавливает новое SSH-соединение с каждым управляемым хостом для каждой задачи, выполняемой в плейбуке. Для каждого соединения он выполняет несколько шагов:

  1. Установление SSH-соединения: Устанавливается новое SSH-соединение.
  2. Передача модулей: Ansible передает необходимые Python-модули (или другие соответствующие файлы) на удаленный хост.
  3. Выполнение модуля: Модуль выполняется на удаленном хосте.
  4. Получение вывода: Ansible получает результаты выполнения.
  5. Закрытие соединения: SSH-соединение разрывается.

Хотя этот подход надежен и обеспечивает чистое состояние для каждой задачи, повторяющийся процесс установки соединения и передачи модулей занимает значительное время, особенно при работе с многочисленными задачами или большим инвентарем.

Оптимизация соединений с помощью ControlPersist

ControlPersist — это функция SSH, которая позволяет поддерживать SSH-соединения открытыми в течение определенного периода времени, даже после завершения первоначальной команды. Это означает, что последующие задачи Ansible, нацеленные на один и тот же хост, могут повторно использовать существующее открытое соединение вместо установки нового. Это значительно снижает задержку, связанную с установкой SSH-сессий.

Как работает ControlPersist

При включении ControlPersist клиент SSH получает указание поддерживать главное управляющее соединение. Последующие SSH-соединения с тем же хостом, использующие те же учетные данные и параметры, могут затем мультиплексироваться через это главное соединение. Ansible использует это, устанавливая параметры ControlPath и ControlPersist в своей конфигурации SSH.

Включение ControlPersist в Ansible

Вы можете включить ControlPersist несколькими способами:

  1. Через ansible.cfg (рекомендуется для глобальных настроек или настроек для конкретного проекта):
    Отредактируйте или создайте файл ansible.cfg (он находится в каталоге вашего проекта Ansible, ~/.ansible.cfg или /etc/ansible/ansible.cfg). Добавьте следующую конфигурацию в раздел [ssh_connection]:

    ini [ssh_connection] ssh_args = -o ControlMaster=auto -o ControlPersist=600 -o ControlPath=~/.ssh/ansible_control_%r@%h:%p

    • -o ControlMaster=auto: Включает общий доступ к соединениям. Если главное соединение существует, оно используется; в противном случае создается новое.
    • -o ControlPersist=600: Поддерживает управляющее соединение открытым в течение 600 секунд (10 минут). Настройте это значение в зависимости от вашего рабочего процесса и политик безопасности. Большая продолжительность означает больше возможностей для повторного использования, но также и больше ресурсов, которые остаются открытыми.
    • -o ControlPath=~/.ssh/ansible_control_%r@%h:%p: Определяет путь к сокету управления. %r — имя удаленного пользователя, %h — имя хоста, а %p — порт. Это гарантирует уникальность сокетов для разных соединений.
  2. Через переменную окружения:
    Вы можете установить аргументы SSH напрямую, используя переменную окружения:

    bash export ANSIBLE_SSH_ARGS='-o ControlMaster=auto -o ControlPersist=600 -o ControlPath=~/.ssh/ansible_control_%r@%h:%p' ansible-playbook your_playbook.yml

  3. Через плейбук (менее распространено для этой настройки):
    Хотя это возможно, обычно не рекомендуется устанавливать постоянные параметры SSH внутри самого плейбука, поскольку это настройка уровня соединения. Однако для полноты картины вы можете использовать ansible.builtin.set_fact или аналогичные средства для влияния на нее, но ansible.cfg является предпочтительным.

Соображения по ControlPersist

  • Безопасность: Убедитесь, что ControlPath защищен, чтобы только авторизованные пользователи могли получить доступ к сокетам управления. Путь по умолчанию в примере обычно безопасен для конфигураций на уровне пользователя.
  • Использование ресурсов: Поддержание открытых соединений потребляет ресурсы как на управляющем узле, так и на управляемых узлах. Отслеживайте использование ресурсов, если у вас очень большое количество постоянных соединений.
  • Сброс соединения: Если промежуточное сетевое устройство или удаленный SSH-сервер принудительно устанавливает временные ограничения на соединение, более короткие, чем ControlPersist, соединение все равно может разорваться. ControlPersist лучше всего работает в стабильных сетевых средах.

Ускорение выполнения модулей с помощью Pipelining

Pipelining — это еще одна мощная оптимизация Ansible, которая дополнительно снижает накладные расходы на выполнение задач. Вместо того чтобы передавать модули на удаленный хост, выполнять их, а затем получать вывод, pipelining передает команды напрямую по SSH-соединению. Это означает, что Ansible не нужно помещать модули в файловую систему удаленного хоста или создавать временные файлы для вывода.

Как работает Pipelining

При включении pipelining Ansible выполняет модули напрямую через ssh на удаленном хосте. Стандартный вывод и стандартный поток ошибок модуля передаются обратно в Ansible по тому же SSH-соединению. Это устраняет необходимость в том, чтобы Ansible записывал файлы в файловую систему удаленного хоста (например, /usr/bin/ansible_module_name или временные файлы), а затем выполнял их. Это особенно эффективно для модулей, которые не требуют повышения привилегий или значительного взаимодействия с файловой системой удаленного хоста.

Включение Pipelining в Ansible

Pipelining включается через файл ansible.cfg или переменные окружения.

  1. Через ansible.cfg:
    Добавьте или измените раздел [ssh_connection]:

    ini [ssh_connection] pipelining = True

  2. Через переменную окружения:
    bash export ANSIBLE_PIPELINING=True ansible-playbook your_playbook.yml

Соображения по Pipelining

  • Повышение привилегий: Pipelining лучше всего работает с модулями, которые не требуют повышения привилегий (например, с использованием become: yes или sudo). Когда используется become, Ansible обычно необходимо копировать файлы в удаленную систему. Если вы часто используете become, pipelining может не дать такого большого преимущества или даже вызвать проблемы с некоторыми типами модулей.
  • Совместимость модулей: Большинство встроенных модулей Ansible хорошо работают с pipelining. Однако пользовательские модули или те, которые в значительной степени полагаются на операции с файловой системой удаленного хоста, могут вести себя по-разному. Тщательно протестируйте.
  • Стабильность соединения: Стабильное SSH-соединение крайне важно для правильной работы pipelining.
  • Настройка SSH requiretty: Pipelining несовместим с параметром SSH requiretty на удаленном сервере. Если на вашем SSH-сервере установлен Defaults requiretty в /etc/sudoers, вам может потребоваться отключить его или использовать !requiretty для конкретного пользователя, под которым подключается Ansible.

Сочетание ControlPersist и Pipelining для максимальной производительности

Для достижения наиболее значительного прироста производительности настоятельно рекомендуется включить как ControlPersist, так и Pipelining. Эта комбинация устраняет два основных накладных расхода: установку соединения и выполнение модуля.

Вот как может выглядеть ваш ansible.cfg с обеими включенными функциями:

[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=600 -o ControlPath=~/.ssh/ansible_control_%r@%h:%p
pipelining = True

Когда обе функции активны:

  1. Ansible инициирует SSH-соединение и устанавливает ControlMaster, если он еще не существует (ControlPersist).
  2. Для последующих задач используется существующее открытое соединение.
  3. Модули выполняются напрямую через поток без копирования в файловую систему (Pipelining).

Эта синергия значительно сокращает время, которое Ansible тратит на взаимодействие с каждым управляемым узлом, что приводит к гораздо более быстрой работе плейбуков.

Практический пример сценария

Представим плейбук, который должен выполнить 10 простых задач на 100 хостах.

Без оптимизаций:
Каждая задача требует нового SSH-соединения, передачи модуля, выполнения и закрытия соединения. Это составляет 100 хостов * 10 задач * (время_соединения + время_передачи_модуля). Если время_соединения составляет 0,5 секунды, а время_передачи_модуля — 0,2 секунды, то накладные расходы только на связь и передачу составят 100 * 10 * 0,7 = 700 секунд, не считая фактического выполнения модуля.

С включенными ControlPersist и Pipelining:

  1. Первая задача на каждом хосте устанавливает начальное соединение и настраивает ControlMaster.
  2. Все последующие 9 задач на этом хосте повторно используют открытое соединение и выполняют модули в потоковом режиме.

Накладные расходы на хост приближаются к время_соединения + (9 * минимальные_накладные_расходы_на_потоковую_передачу). Общее время значительно сокращается, и большая часть времени выполнения плейбука посвящается фактической работе, которую выполняют модули, а не механике связи.

Когда следует быть осторожным

Хотя эти оптимизации мощны, они не универсальны и требуют рассмотрения:

  • Среда со строгими межсетевыми экранами или сетевыми ограничениями: Частые обрывы соединения или проверка состояния могут помешать работе ControlPersist.
  • Среды с повышенной безопасностью: Долгоживущие SSH-соединения могут вызывать опасения по поводу безопасности в строго регулируемых средах. Соответствующим образом настройте продолжительность ControlPersist.
  • Плейбуки, сильно зависящие от become и файловых операций: Эффективность Pipelining снижается при постоянном использовании become, поскольку это часто требует файловых операций. Протестируйте влияние на производительность.

Заключение

Оптимизация взаимодействия Ansible с управляемыми узлами — ключевой шаг к эффективной и масштабируемой автоматизации. Понимая и внедряя ControlPersist и Pipelining, вы можете значительно сократить время выполнения плейбуков. ControlPersist поддерживает SSH-соединения открытыми, снижая накладные расходы на подключение, в то время как Pipelining передает выполнение модулей в потоковом режиме, устраняя необходимость в передаче файлов. Комбинирование этих двух настроек, в основном через ansible.cfg, является лучшей практикой для любого пользователя Ansible, управляющего значительным количеством хостов или выполняющего сложные плейбуки. Всегда тестируйте эти конфигурации в вашей конкретной среде, чтобы точно настроить производительность и обеспечить совместимость.