Spec-Zone.ru › Ansible

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

По умолчанию 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 не поддерживает режим проверки и завершит задачу при запуске в режиме проверки. Смотрите Проверка задач: режим проверки и режим diff о том, как пропустить задачу в режиме проверки.

Примечание

По завершении асинхронной задачи с включённым опросом временный кэш асинхронного задания (по умолчанию в ~/.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

Примечание

Не указывайте значение poll равное 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.finished
  retries: 100
  delay: 10

Примечание

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

Примечание

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

См. также

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

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

Плейбуки 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_async.html

Spec-Zone.ru

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