Управление выполнением плейбуков: стратегии и многое другое
По умолчанию Ansible выполняет каждую задачу на всех затронутых узлах плей перед запуском следующей задачи на любом узле, используя 5 процессов. Если вы хотите изменить это поведение по умолчанию, вы можете использовать другой плагин стратегии, изменить количество процессов или применить один из нескольких ключевых слов, таких как serial.
Выбор стратегии
Поведение по умолчанию, описанное выше, — это линейная стратегия. Ansible предлагает другие стратегии, включая стратегию отладки (см. также Отладка задач) и свободную стратегию, которая позволяет каждому узлу выполняться до конца плей как можно быстрее:
- hosts: all strategy: free tasks: # ...
Вы можете выбрать другую стратегию для каждого плей, как показано выше, или установить предпочтительную стратегию глобально в ansible.cfg, в разделе defaults:
[defaults] strategy = free
Все стратегии реализованы как плагины стратегий. Для получения подробной информации о работе каждого плагина стратегии ознакомьтесь с документацией по этому плагину.
Установка количества процессов
Если у вас есть доступные вычислительные ресурсы и вы хотите использовать больше процессов, вы можете установить это значение в ansible.cfg:
[defaults] forks = 30
или передать его в командной строке: ansible-playbook -f 30 my_playbook.yml.
Использование ключевых слов для управления выполнением
Помимо стратегий, несколько ключевых слов также влияют на выполнение пьесы. Вы можете установить количество, процент или список чисел хостов, которыми вы хотите управлять за раз с помощью serial. Ansible завершает игру на указанном количестве или проценте хостов перед началом следующей группы хостов. Вы можете ограничить количество рабочих процессов, выделенных для блока или задачи, с помощью throttle. Вы можете контролировать, как Ansible выбирает следующий хост в группе для выполнения с помощью order. Вы можете выполнить задачу на одном хосте с помощью run_once. Эти ключевые слова не являются стратегиями. Это директивы или параметры, применяемые к пьесе, блоку или задаче.
Другие ключевые слова, влияющие на выполнение пьесы, включают ignore_errors, ignore_unreachable, и any_errors_fatal. Эти параметры документированы в Обработке ошибок в пьесах.
Установка размера пакета с serial
По умолчанию Ansible выполняется параллельно для всех хостов в шаблоне, который вы задали в поле hosts: каждой пьесы. Если вы хотите управлять только несколькими машинами за раз, например, во время развертывания, вы можете определить, сколько хостов Ansible должно управлять за один раз, используя ключевое слово serial.
---
- name: test play
hosts: webservers
serial: 3
gather_facts: False
tasks:
- name: first task
command: hostname
- name: second task
command: hostname
В приведенном выше примере, если у нас было 6 хостов в группе «webservers», Ansible полностью выполнит пьесу (обе задачи) на 3 хостах перед переходом к следующим 3 хостам:
PLAY [webservers] *********************************************************************** TASK [first task] *********************************************************************** changed: [web1] changed: [web3] changed: [web2] TASK [second task] ********************************************************************** changed: [web1] changed: [web2] changed: [web3] PLAY [webservers] *********************************************************************** TASK [first task] *********************************************************************** changed: [web4] changed: [web5] changed: [web6] TASK [second task] ********************************************************************** changed: [web4] changed: [web5] changed: [web6] PLAY RECAP ****************************************************************************** web1 : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 web2 : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 web3 : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 web4 : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 web5 : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 web6 : ok=2 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Примечание
Установка размера пакета с помощью serial изменяет область действия сбоев Ansible на размер пакета, а не на весь список хостов. Вы можете использовать ignore_unreachable или max_fail_percentage для изменения этого поведения.
Вы также можете указать процент с помощью ключевого слова serial. Ansible применяет процент к общему количеству хостов в пьесе для определения количества хостов за проход:
--- - name: test play hosts: webservers serial: "30%"
Если количество хостов не делится равномерно на количество проходов, последний проход содержит остаток. В этом примере, если у вас было 20 хостов в группе webservers, первый пакет будет содержать 6 хостов, второй пакет будет содержать 6 хостов, третий пакет будет содержать 6 хостов, а последний пакет будет содержать 2 хоста.
Вы также можете указать размеры пакетов в виде списка. Например:
---
- name: test play
hosts: webservers
serial:
- 1
- 5
- 10
В приведенном выше примере первый пакет будет содержать один хост, следующий — 5 хостов, а (если хосты остались), каждый последующий пакет будет содержать либо 10 хостов, либо все оставшиеся хосты, если их осталось меньше 10.
Вы также можете указать несколько размеров пакетов в процентах:
---
- name: test play
hosts: webservers
serial:
- "10%"
- "20%"
- "100%"
Вы также можете смешивать и сочетать значения:
---
- name: test play
hosts: webservers
serial:
- 1
- 5
- "20%"
Примечание
Независимо от того, насколько мал процент, количество хостов за проход всегда будет 1 или больше.
Ограничение выполнения с throttle
Ключевое слово throttle ограничивает количество рабочих процессов для конкретной задачи. Его можно установить на уровне блока и задачи. Используйте throttle для ограничения задач, которые могут быть ресурсоемкими или взаимодействовать с API с ограничениями скорости:
tasks: - command: /path/to/cpu_intensive_command throttle: 1
Если вы уже ограничили количество вилок или количество машин для параллельного выполнения, вы можете уменьшить количество рабочих процессов с помощью throttle, но не можете увеличить его. Другими словами, чтобы это имело эффект, значение throttle должно быть меньше значения forks или serial, если вы используете их вместе.
Порядок выполнения на основе инвентаризации
Ключевое слово order контролирует порядок выполнения хостов. Возможные значения для порядка:
- inventory:
-
(по умолчанию) Порядок, предоставленный инвентаризацией для запрошенного выбора (см. примечание ниже)
- reverse_inventory:
-
То же самое, что и выше, но список возвращается в обратном порядке
- sorted:
-
Сортировка по алфавиту по имени
- reverse_sorted:
-
Сортировка по имени в обратном алфавитном порядке
- shuffle:
-
Случайный порядок при каждом запуске
Примечание
Порядок ‘inventory’ не эквивалентен порядку, в котором хосты/группы определены в файле инвентаризации, а порядку, в котором выбор возвращается из скомпилированной инвентаризации. Это обратная совместимая опция, и, хотя воспроизводимая, она обычно непредсказуема. Из-за природы инвентаризации, шаблонов хостов, ограничений, плагинов инвентаризации и возможности разрешения нескольких источников, вернуть такой порядок практически невозможно. В простых случаях это может совпасть с порядком определения файла, но это не гарантируется.
Выполнение на одной машине с помощью run_once
Если вы хотите, чтобы задача выполнялась только на первом хосте в вашей группе хостов, установите run_once в значение true для этой задачи:
---
# ...
tasks:
# ...
- command: /opt/application/upgrade_db.py
run_once: true
# ...
Ansible выполняет эту задачу на первом хосте в текущей группе и применяет все результаты и факты ко всем хостам в той же группе. Этот подход аналогичен применению условия к задаче, например:
- command: /opt/application/upgrade_db.py when: inventory_hostname == webservers[0]
Однако, с run_once, результаты применяются ко всем хостам. Чтобы выполнить задачу на определенном хосте, а не на первом хосте в группе, делегируйте задачу:
- command: /opt/application/upgrade_db.py run_once: true delegate_to: web01.example.org
Как всегда с делегированием, действие будет выполнено на делегированном хосте, но информация по-прежнему относится к исходному хосту в задаче.
Примечание
При использовании вместе с serial, задачи, помеченные как run_once, будут выполняться на одном хосте в каждом пакете. Если задача должна выполняться только один раз, независимо от режима serial, используйте конструкцию when: inventory_hostname == ansible_play_hosts_all[0].
Примечание
Любое условие (иными словами, when:) будет использовать переменные «первого хоста», чтобы решить, выполняется ли задача или нет, другие хосты проверены не будут.
Примечание
Если вы хотите избежать поведения по умолчанию установки факта для всех хостов, установите delegate_facts: True для конкретной задачи или блока.
См. также
- Пьесы Ansible
-
Введение в пьесы
- Управление тем, где выполняются задачи: делегирование и локальные действия
-
Выполнение задач на определенных машинах или присвоение фактов конкретным машинам
- Роли
-
Организация пьес по ролям
- Общение
-
У вас есть вопросы? Нужна помощь? Хотите поделиться своими идеями? Посетите руководство по общению Ansible
© 2012–2018 Michael DeHaan
© 2018–2024 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_strategies.html