Spec-Zone.ru › Ansible 2.11

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

По умолчанию 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

Примечание

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

Примечание

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

Если вам нужен момент синхронизации с асинхронной задачей, вы можете зарегистрировать её, чтобы получить её идентификатор задания, и использовать модуль 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

См. также

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

Варианты управления выполнением книги задач

Вводный курс по книгам задач

Введение в книги задач

Список рассылки пользователей

У вас есть вопрос? Задайте его на форуме!

irc.freenode.net

Канал чата IRC #ansible

© 2012–2018 Michael DeHaan
© 2018–2021 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/2.11/user_guide/playbooks_async.html

Spec-Zone.ru

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