Ответ
Параллельное выполнение в Ansible значительно ускоряет развертывание на множестве хостов. Я использую несколько механизмов в зависимости от сценария.
1. Стратегия выполнения free (наиболее агрессивная)
---
- name: Deploy application cluster
hosts: web_servers # Группа из 10+ хостов
strategy: free
tasks:
- name: Update packages
apt:
update_cache: yes
cache_valid_time: 3600
async: 300 # Асинхронное выполнение с таймаутом
poll: 0 # Не ждем завершения, продолжаем
- name: Deploy application code
synchronize:
src: ./app/
dest: /opt/app/
delegate_to: "{{ inventory_hostname }}"
- name: Restart service
systemd:
name: app-service
state: restarted
async: 60
poll: 10 # Проверяем статус каждые 10 секунд
2. Настройка количества форков (параллельных соединений)
# В командной строке
ansible-playbook deploy.yml --forks 20
# Или в ansible.cfg
[defaults]
forks = 20
host_key_checking = False
# Увеличиваем таймауты для параллельного выполнения
timeout = 30
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
3. Параллельное выполнение с ограничениями
- name: Rolling update with batch
hosts: web_servers
serial: 3 # Обрабатываем по 3 хоста одновременно
tasks:
- name: Take host out of load balancer
uri:
url: "http://lb-api/disable/{{ inventory_hostname }}"
method: POST
- name: Apply updates
include_tasks: update_tasks.yml
- name: Return host to load balancer
uri:
url: "http://lb-api/enable/{{ inventory_hostname }}"
method: POST
4. Асинхронные задачи с проверкой статуса
- name: Run long operation
command: /opt/scripts/long-running-process.sh
async: 1800 # 30 минут максимум
poll: 30 # Проверяем каждые 30 секунд
register: long_task
- name: Check async task status
async_status:
jid: "{{ long_task.ansible_job_id }}"
register: job_result
until: job_result.finished
retries: 30
delay: 30
5. Параллельное выполнение разных задач на разных хостах
- name: Database migration (только на master)
hosts: db_master
tasks:
- name: Run migrations
command: /opt/app/migrate.sh
- name: Application deployment (параллельно на всех app servers)
hosts: app_servers
strategy: free
tasks:
- name: Deploy code
synchronize:
src: ./app/
dest: /opt/app/
6. Использование throttle для ограничения нагрузки
- name: CPU-intensive operation
hosts: all
tasks:
- name: Compile software
make:
chdir: /src/
throttle: 2 # Не более 2 хостов одновременно
Ключевые практики:
- Тестирую параллельное выполнение в staging перед production
- Мониторю нагрузку на управляющей машине (CPU, память, сеть)
- Использую
serialдля rolling updates критических сервисов - Настраиваю правильные таймауты в
ansible.cfg - Логирую выполнение с тегами хостов для отладки
- Для очень больших инфраструктур (>1000 хостов) использую Ansible Tower/AWX с разбивкой на job templates
Ответ 18+ 🔞
Ёпта, ну смотри, тут про параллельное выполнение в Ansible. Всё просто, как три копейки, но если не знать этих фокусов — можно ждать, пока хуй с горы свалится, пока плейбук на сотне серверов отработает.
Вот, например, самая агрессивная стратегия — free. Это когда ты говоришь: "Похуй, чувак, делай всё что хочешь и как хочешь". Сервера начинают работать асинхронно, без оглядки друг на друга. Главное — правильно таймауты выставить, а то получишь овердохуища ошибок.
---
- name: Deploy application cluster
hosts: web_servers # Группа из 10+ хостов
strategy: free
tasks:
- name: Update packages
apt:
update_cache: yes
cache_valid_time: 3600
async: 300 # Асинхронное выполнение с таймаутом
poll: 0 # Не ждем завершения, продолжаем
А ещё можно просто в командной строке форков накрутить. Типа --forks 20. Это как сказать: "Э, сабака сука, у меня двадцать рук, я всеми сразу могу работать". Но тут главное — не переборщить, а то управляющая машина взвоет, как мартышлюшка, и накроется медным тазом.
Самый адекватный подход для прода — это rolling update. Ставишь serial: 3 и обрабатываешь по три хоста за раз. Сначала выводишь из балансировщика, потом обновляешь, потом обратно загоняешь. Так и волнение ебать поменьше, и если что-то пойдёт не так — только три сервера в ауте, а не все сразу.
- name: Rolling update with batch
hosts: web_servers
serial: 3 # Обрабатываем по 3 хоста одновременно
А бывают задачи, которые выполняются хуй знает сколько. Для них есть асинхронный режим с проверкой статуса. Запустил, зарегистрировал job id, и потом периодически дёргаешь: "Ну что, готово, пидарас шерстяной, или ещё нет?" Пока не скажет finished.
Ну и, конечно, для особо прожорливых операций есть throttle. Скажем, компиляция софта. Если на всех серверах одновременно запустить make — они друг другу все ресурсы сожрут. Ставишь throttle: 2 и спокойно смотришь, как они по очереди, не спеша, всё делают.
Главное, чувак, — тестировать это всё на staging-окружении. Потому что если сразу на прод запустишь с неправильными настройками, будет тебе хиросима и нигерсраки. Сервера попадают, задачи зависают, а ты сидишь и думаешь: "Э, бошка думай, что же пошло не так?". А всё пошло не так с самого начала, потому что доверия ебать ноль к непроверенным конфигам.
Для совсем больших фертин, где серверов больше, чем мозгов у менеджера, уже нужен Ansible Tower или AWX. Там уже встроенные механизмы для работы с овердохуищем хостов, с очередями и распределением нагрузки. Но это уже совсем другая история, с кот сука собака сложностью.