Spec-Zone.ru › Ansible 2.10

Асинхронные действия и опрос

По умолчанию Ansible выполняет задачи синхронно, удерживая соединение с удаленным узлом открытым до завершения действия. Это означает, что в рамках плейбука каждая задача блокирует следующую задачу по умолчанию, и последующие задачи не будут выполняться до завершения текущей задачи. Это поведение может создавать проблемы. Например, задача может занимать больше времени, чем позволяет сессия SSH, что приводит к таймауту. Или вы можете захотеть, чтобы долго выполняемый процесс выполнялся в фоновом режиме, в то время как вы выполняете другие задачи одновременно. Режим асинхронного выполнения позволяет управлять выполнением задач с длительным временем выполнения.

  • Асинхронные задачи ad-hoc
  • Асинхронные задачи плейбука

    • Избегание таймаутов соединения: poll > 0
    • Выполнение задач одновременно: poll = 0

Асинхронные задачи ad-hoc

Вы можете выполнять длительные операции в фоновом режиме с помощью задач ad-hoc. Например, для асинхронного выполнения long_running_operation в фоновом режиме с таймаутом (-B) 3600 секунд и без опроса (-P):

$ ansible all -B 3600 -P 0 -a "/usr/bin/long_running_operation --do-stuff"

Чтобы позже проверить статус задания, используйте модуль async_status, передав ему идентификатор задания, который был возвращен при запуске исходного задания в фоновом режиме:

$ ansible web1.example.com -m async_status -a "jid=488359678239.2844"

Ansible также может автоматически проверять статус вашего долго выполняемого задания с помощью опроса. В большинстве случаев Ansible будет сохранять соединение с вашим удаленным узлом открытым между опросами. Для выполнения в течение 30 минут и опроса статуса каждые 60 секунд:

$ ansible all -B 1800 -P 60 -a "/usr/bin/long_running_operation --do-stuff"

Режим опроса является интеллектуальным, поэтому все задания будут запущены до начала опроса на любом компьютере. Убедитесь, что вы используете достаточно высокое значение --forks, если хотите быстро запустить все ваши задания. После истечения лимита времени (в секундах) (-B) процесс на удаленных узлах будет завершен.

Асинхронный режим лучше всего подходит для длительных команд оболочки или обновлений программного обеспечения. Например, запуск модуля копирования в асинхронном режиме не выполняет фоновый перенос файла.

Асинхронные задачи плейбука

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

Избегание таймаутов соединения: poll > 0

Если вы хотите установить более длительный лимит таймаута для определенной задачи в вашем плейбуке, используйте async со значением poll больше нуля. Ansible по-прежнему будет блокировать следующую задачу в вашем плейбуке, ожидая, пока асинхронная задача завершится, завершится с ошибкой или не истечет время ожидания. Однако задача будет завершена только в случае превышения вами установленного лимита таймаута с помощью параметра async.

Чтобы избежать таймаута в задаче, укажите максимальное время выполнения и частоту опроса статуса:

---

- hosts: all
  remote_user: root

  tasks:

  - name: Simulate long running op (15 sec), wait for up to 45 sec, poll every 5 sec
    ansible.builtin.command: /bin/sleep 15
    async: 45
    poll: 5

Примечание

Значение опроса по умолчанию устанавливается настройкой DEFAULT_POLL_INTERVAL. Для асинхронного лимита времени нет значения по умолчанию. Если вы опускаете ключевое слово «async», задача выполняется синхронно, что является стандартным поведением Ansible.

Примечание

Начиная с Ansible 2.3, async не поддерживает режим проверки и завершит задачу при запуске в режиме проверки. Смотрите Проверка задач: режим проверки и режим сравнения для информации о пропуске задачи в режиме проверки.

Выполнение задач одновременно: poll = 0

Если вы хотите выполнить несколько задач в плейбуке одновременно, используйте async со значением poll равным 0. При установке poll: 0, Ansible запускает задачу и сразу переходит к следующей задаче, не ожидая результата. Каждая асинхронная задача выполняется до тех пор, пока она не завершится, не завершится с ошибкой или не истечет время ожидания (выполняется дольше, чем её значение async). Запуск плейбука завершается без проверки асинхронных задач.

Чтобы выполнить задачу плейбука асинхронно:

---

- hosts: all
  remote_user: root

  tasks:

  - name: Simulate long running op, allow to run for 45 sec, fire and forget
    ansible.builtin.command: /bin/sleep 15
    async: 45
    poll: 0

Примечание

Не указывайте значение poll равное 0 для операций, требующих эксклюзивных блокировок (таких как операции yum), если вы ожидаете выполнения других команд позже в плейбуке с теми же ресурсами.

Примечание

Использование более высокого значения для --forks приведет к ещё более быстрому запуску асинхронных задач. Это также повышает эффективность опроса.

Если вам нужна точка синхронизации с асинхронной задачей, вы можете зарегистрировать её для получения ID задания и использовать модуль async_status для наблюдения за ним в последующей задаче. Например:

- name: Run an async task
  ansible.builtin.yum:
    name: docker-io
    state: present
  async: 1000
  poll: 0
  register: yum_sleeper

- name: Check on an async task
  async_status:
    jid: "{{ yum_sleeper.ansible_job_id }}"
  register: job_result
  until: job_result.finished
  retries: 100
  delay: 10

Примечание

Если значение async: недостаточно велико, это приведёт к завершению задачи «проверить позже» с ошибкой, потому что временный файл статуса, который ищет модуль async_status:, не будет создан или больше не существует.

Для выполнения нескольких асинхронных задач, ограничивая количество одновременно выполняемых задач:

#####################
# main.yml
#####################
- name: Run items asynchronously in batch of two items
  vars:
    sleep_durations:
      - 1
      - 2
      - 3
      - 4
      - 5
    durations: "{{ item }}"
  include_tasks: execute_batch.yml
  loop: "{{ sleep_durations | batch(2) | list }}"

#####################
# execute_batch.yml
#####################
- name: Async sleeping for batched_items
  ansible.builtin.command: sleep {{ async_item }}
  async: 45
  poll: 0
  loop: "{{ durations }}"
  loop_control:
    loop_var: "async_item"
  register: async_results

- name: Check sync status
  async_status:
    jid: "{{ async_result_item.ansible_job_id }}"
  loop: "{{ async_results.results }}"
  loop_control:
    loop_var: "async_result_item"
  register: async_poll_results
  until: async_poll_results.finished
  retries: 30

См. также

Управление выполнением плейбука: стратегии и многое другое

Варианты управления выполнением плейбука

Введение в плейбуки

Введение в плейбуки

Пользовательская рассылка

Есть вопросы? Зайдите на форум 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_async.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API