Управление выполнением плейбуков: стратегии и многое другое
По умолчанию 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. Эти ключевые слова не являются стратегиями. Это директивы или параметры, применяемые к плейбуку, блоку или задаче.
Установка размера пакета с serial
По умолчанию Ansible работает параллельно со всеми узлами в шаблоне, который вы установили в поле hosts: каждого плейбука. Если вы хотите управлять только несколькими машинами за раз, например, во время постепенного обновления, вы можете определить, сколько узлов Ansible должен обрабатывать за один раз, с помощью ключевого слова serial:
---
- name: test play
hosts: webservers
serial: 2
gather_facts: False
tasks:
- name: first task
command: hostname
- name: second task
command: hostname
В приведенном выше примере, если в группе ‘webservers’ у нас было 4 узла, Ansible полностью выполнит плейбук (обе задачи) на 2 из узлов, прежде чем перейти к следующим 2 узлам:
PLAY [webservers] **************************************** TASK [first task] **************************************** changed: [web2] changed: [web1] TASK [second task] *************************************** changed: [web1] changed: [web2] PLAY [webservers] **************************************** TASK [first task] **************************************** changed: [web3] changed: [web4] TASK [second task] *************************************** changed: [web3] changed: [web4] PLAY RECAP *********************************************** web1 : ok=2 changed=2 unreachable=0 failed=0 web2 : ok=2 changed=2 unreachable=0 failed=0 web3 : ok=2 changed=2 unreachable=0 failed=0 web4 : ok=2 changed=2 unreachable=0 failed=0
Вы также можете указать процент с помощью ключевого слова 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:
-
Случайный порядок на каждом запуске
Другие ключевые слова, которые влияют на выполнение плейбука, включают ignore_errors, ignore_unreachable и any_errors_fatal. Эти параметры документированы в Обработка ошибок в плейбуках.
Выполнение на одном компьютере с 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 для конкретной задачи или блока.
См. также
- Введение в плейбуки
-
Введение в плейбуки
- Управление местом выполнения задач: делегирование и локальные действия
-
Выполнение задач на определенных машинах или присвоение фактов определенным машинам
- Роли
-
Организация плейбуков по ролям
- Список рассылки пользователей
-
Есть вопрос? Загляните в группу Google!
- irc.freenode.net
-
IRC-чат-канал #ansible
© 2012–2018 Michael DeHaan
© 2018–2019 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/2.10/user_guide/playbooks_strategies.html