Spec-Zone.ru › Ansible

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

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

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

    • Предотвращение тайм-аутов соединения: poll > 0
    • Параллельное выполнение задач: poll = 0

Асинхронные разовые задачи

Вы можете выполнять длительные операции в фоновом режиме с помощью разовых задач. Например, чтобы асинхронно выполнить 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) процесс на удалённых узлах будет завершён.

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

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

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

Примечание

Когда асинхронная задача завершается при включённом опросе, временный файл кэша асинхронного задания (по умолчанию в ~/.ansible_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 позволит ещё быстрее запускать асинхронные задачи. Это также повышает эффективность опроса.

Примечание

При использовании poll: 0 Ansible не будет автоматически удалять файл кэша асинхронного задания. Вам потребуется удалить его вручную с помощью модуля async_status и mode: cleanup.

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

Примечание

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

Примечание

Асинхронные задачи плейбука всегда возвращают состояние changed. Если задача использует модуль, для которого пользователь должен указывать изменения с помощью changed_when, creates и так далее, добавьте их в следующую задачу 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 is finished
  retries: 30

См. также

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

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

Плейбуки Ansible

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

Общение

Есть вопросы? Нужна помощь? Хотите поделиться идеями? Посетите руководство Ansible по общению

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

Spec-Zone.ru

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