Максимизация производительности Ansible с помощью ControlPersist и Pipelining
Ansible — это мощный инструмент для автоматизации ИТ-инфраструктуры, позволяющий управлять конфигурациями и развертывать приложения в большом масштабе. Однако в средах с высокой нагрузкой или при управлении большим количеством узлов накладные расходы, связанные с установкой SSH-соединений для каждой задачи, могут стать серьезным узким местом. Это может привести к очень медленному выполнению плейбуков. К счастью, Ansible предлагает две мощные функции — ControlPersist и Pipelining — которые могут значительно повысить производительность за счет оптимизации взаимодействия Ansible с управляемыми узлами.
В этом руководстве мы разберем понимание и внедрение ControlPersist и Pipelining. Используя эти методы, вы можете значительно сократить время выполнения, сделав автоматизацию Ansible более эффективной и отзывчивой, особенно в средах с сотнями или тысячами хостов. Освоение этих оптимизаций крайне важно для всех, кто стремится эффективно масштабировать свои развертывания Ansible.
Понимание стандартного поведения подключения Ansible
По умолчанию Ansible устанавливает новое SSH-соединение с каждым управляемым хостом для каждой задачи, выполняемой в плейбуке. Для каждого соединения он выполняет несколько шагов:
- Установление SSH-соединения: Устанавливается новое SSH-соединение.
- Передача модулей: Ansible передает необходимые Python-модули (или другие соответствующие файлы) на удаленный хост.
- Выполнение модуля: Модуль выполняется на удаленном хосте.
- Получение вывода: Ansible получает результаты выполнения.
- Закрытие соединения: SSH-соединение разрывается.
Хотя этот подход надежен и обеспечивает чистое состояние для каждой задачи, повторяющийся процесс установки соединения и передачи модулей занимает значительное время, особенно при работе с многочисленными задачами или большим инвентарем.
Оптимизация соединений с помощью ControlPersist
ControlPersist — это функция SSH, которая позволяет поддерживать SSH-соединения открытыми в течение определенного периода времени, даже после завершения первоначальной команды. Это означает, что последующие задачи Ansible, нацеленные на один и тот же хост, могут повторно использовать существующее открытое соединение вместо установки нового. Это значительно снижает задержку, связанную с установкой SSH-сессий.
Как работает ControlPersist
При включении ControlPersist клиент SSH получает указание поддерживать главное управляющее соединение. Последующие SSH-соединения с тем же хостом, использующие те же учетные данные и параметры, могут затем мультиплексироваться через это главное соединение. Ansible использует это, устанавливая параметры ControlPath и ControlPersist в своей конфигурации SSH.
Включение ControlPersist в Ansible
Вы можете включить ControlPersist несколькими способами:
-
Через
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— порт. Это гарантирует уникальность сокетов для разных соединений.
-
Через переменную окружения:
Вы можете установить аргументы 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 -
Через плейбук (менее распространено для этой настройки):
Хотя это возможно, обычно не рекомендуется устанавливать постоянные параметры 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 или переменные окружения.
-
Через
ansible.cfg:
Добавьте или измените раздел[ssh_connection]:ini [ssh_connection] pipelining = True -
Через переменную окружения:
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 несовместим с параметром SSHrequirettyна удаленном сервере. Если на вашем 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
Когда обе функции активны:
- Ansible инициирует SSH-соединение и устанавливает ControlMaster, если он еще не существует (ControlPersist).
- Для последующих задач используется существующее открытое соединение.
- Модули выполняются напрямую через поток без копирования в файловую систему (Pipelining).
Эта синергия значительно сокращает время, которое Ansible тратит на взаимодействие с каждым управляемым узлом, что приводит к гораздо более быстрой работе плейбуков.
Практический пример сценария
Представим плейбук, который должен выполнить 10 простых задач на 100 хостах.
Без оптимизаций:
Каждая задача требует нового SSH-соединения, передачи модуля, выполнения и закрытия соединения. Это составляет 100 хостов * 10 задач * (время_соединения + время_передачи_модуля). Если время_соединения составляет 0,5 секунды, а время_передачи_модуля — 0,2 секунды, то накладные расходы только на связь и передачу составят 100 * 10 * 0,7 = 700 секунд, не считая фактического выполнения модуля.
С включенными ControlPersist и Pipelining:
- Первая задача на каждом хосте устанавливает начальное соединение и настраивает ControlMaster.
- Все последующие 9 задач на этом хосте повторно используют открытое соединение и выполняют модули в потоковом режиме.
Накладные расходы на хост приближаются к время_соединения + (9 * минимальные_накладные_расходы_на_потоковую_передачу). Общее время значительно сокращается, и большая часть времени выполнения плейбука посвящается фактической работе, которую выполняют модули, а не механике связи.
Когда следует быть осторожным
Хотя эти оптимизации мощны, они не универсальны и требуют рассмотрения:
- Среда со строгими межсетевыми экранами или сетевыми ограничениями: Частые обрывы соединения или проверка состояния могут помешать работе ControlPersist.
- Среды с повышенной безопасностью: Долгоживущие SSH-соединения могут вызывать опасения по поводу безопасности в строго регулируемых средах. Соответствующим образом настройте продолжительность
ControlPersist. - Плейбуки, сильно зависящие от
becomeи файловых операций: Эффективность Pipelining снижается при постоянном использованииbecome, поскольку это часто требует файловых операций. Протестируйте влияние на производительность.
Заключение
Оптимизация взаимодействия Ansible с управляемыми узлами — ключевой шаг к эффективной и масштабируемой автоматизации. Понимая и внедряя ControlPersist и Pipelining, вы можете значительно сократить время выполнения плейбуков. ControlPersist поддерживает SSH-соединения открытыми, снижая накладные расходы на подключение, в то время как Pipelining передает выполнение модулей в потоковом режиме, устраняя необходимость в передаче файлов. Комбинирование этих двух настроек, в основном через ansible.cfg, является лучшей практикой для любого пользователя Ansible, управляющего значительным количеством хостов или выполняющего сложные плейбуки. Всегда тестируйте эти конфигурации в вашей конкретной среде, чтобы точно настроить производительность и обеспечить совместимость.