Spec-Zone.ru › Ansible

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

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

  • Задачи, которые нельзя делегировать
  • Делегирование задач
  • Шаблонизация в контексте делегирования
  • Делегирование и параллельное выполнение
  • Делегирование сбора фактов
  • Локальные плейбуки

Задачи, которые нельзя делегировать

Некоторые задачи всегда выполняются на управляющем узле. Эти задачи, включая include, add_host и debug, нельзя делегировать. Возможность делегирования действия можно определить по документации атрибута connection. Если атрибут connection указывает, что support равен False или None, действие не использует подключение и не может быть делегировано.

Делегирование задач

Если нужно выполнить задачу на одном узле, используя сведения о других узлах, укажите в задаче ключевое слово delegate_to. Это удобно для управления узлами в пуле балансировщика нагрузки или контроля периодов недоступности. Для управления количеством узлов, выполняющих задачи одновременно, можно использовать делегирование вместе с ключевым словом serial:

---
- hosts: webservers
  serial: 5

  tasks:
    - name: Take out of load balancer pool
      ansible.builtin.command: /usr/bin/take_out_of_pool {{ inventory_hostname }}
      delegate_to: 127.0.0.1

    - name: Actual steps would go here
      ansible.builtin.yum:
        name: acme-web-stack
        state: latest

    - name: Add back to load balancer pool
      ansible.builtin.command: /usr/bin/add_back_to_pool {{ inventory_hostname }}
      delegate_to: 127.0.0.1

Первая и третья задачи в этом плейбуке выполняются на 127.0.0.1 — машине, на которой запущен Ansible. Для каждой задачи также можно использовать сокращённый синтаксис: local_action. Ниже приведён тот же плейбук, что и выше, но для делегирования на 127.0.0.1 используется сокращённый синтаксис:

---
# ...

  tasks:
    - name: Take out of load balancer pool
      local_action: ansible.builtin.command
      args:
        cmd: /usr/bin/take_out_of_pool {{ inventory_hostname }}

# ...

    - name: Add back to load balancer pool
      local_action: ansible.builtin.command
      args:
        cmd: /usr/bin/add_back_to_pool {{ inventory_hostname }}

Для рекурсивного копирования файлов на управляемые серверы можно использовать локальное действие, вызывающее ‘rsync’:

---
# ...

  tasks:
    - name: Recursively copy files from management server to target
      local_action: ansible.builtin.command
      args:
        cmd: "rsync -a /path/to/files {{ inventory_hostname }}:/path/to/target/"

Обратите внимание: для этого необходимо настроить SSH-ключи без парольной фразы или ssh-agent, иначе rsync запросит парольную фразу.

Чтобы указать дополнительные аргументы, используйте следующий синтаксис:

---
# ...

  tasks:
    - name: Send summary mail
      local_action: community.general.mail
      args:
        subject: "Summary Mail"
        to: "{{ mail_recipient }}"
        body: "{{ mail_body }}"
      run_once: True

Примечание

  • Переменная ansible_host и другие переменные подключения, если они заданы, содержат сведения об узле, которому делегирована задача, а не об inventory_hostname.
  • Узел, которому делегирована задача, не наследует переменные узла, делегирующего задачу.

Предупреждение

Хотя вы можете delegate_to узел, которого нет в инвентаре (указав IP-адрес, DNS-имя или другое значение, необходимое модулю подключения), это не добавит узел в инвентарь и может вызвать проблемы. Узлы, делегированные таким образом, наследуют переменные группы «all» (при условии, что VARIABLE_PRECEDENCE включает all_inventory). Если необходимо delegate_to узел, отсутствующий в инвентаре, используйте модуль add host.

Шаблонизация в контексте делегирования

Обратите внимание: при делегировании интерпретатор выполнения (обычно Python), параметры плагина connection, become и shell будут подставляться с использованием значений делегированного узла. Теперь все переменные, кроме inventory_hostname, будут браться с этого узла, а не с исходного узла задачи. Если для этих параметров нужны переменные исходного узла задачи, необходимо использовать hostvars[inventory_hostname]['varname'], даже если inventory_hostname_short ссылается на делегированный узел.

Делегирование и параллельное выполнение

По умолчанию задачи Ansible выполняются параллельно. Делегирование задачи не меняет этого и не решает проблемы параллельного доступа (например, когда несколько процессов записывают в один файл). Чаще всего пользователи сталкиваются с этим при обновлении одного файла на одном делегированном узле для всех узлов (например, с помощью модулей copy, template или lineinfile). Задачи по-прежнему будут выполняться параллельно в процессах (по умолчанию их 5) и перезаписывать данные друг друга.

Это можно решить несколькими способами:

- name: "handle concurrency with a loop on the hosts with `run_once: true`"
  lineinfile: "<options here>"
  run_once: true
  loop: '{{ ansible_play_hosts_all }}'

Использовав промежуточный плей с serial: 1 или указав throttle: 1 на уровне задачи. Подробнее см. раздел Управление выполнением плейбуков: стратегии и другие возможности.

Делегирование сбора фактов

Делегирование задач Ansible похоже на делегирование задач в реальном мире: продукты принадлежат вам, даже если кто-то другой доставляет их к вам домой. Аналогичным образом факты, собранные делегированной задачей, по умолчанию назначаются inventory_hostname (текущему узлу), а не узлу, который собрал эти факты (делегированному узлу). Чтобы назначить собранные факты делегированному узлу, а не текущему, задайте delegate_facts значение true:

---
- hosts: app_servers

  tasks:
    - name: Gather facts from db servers
      ansible.builtin.setup:
      delegate_to: "{{ item }}"
      delegate_facts: true
      loop: "{{ groups['dbservers'] }}"

Эта задача собирает факты для машин из группы dbservers и назначает их этим машинам, хотя плей нацелен на группу app_servers. Так можно находить hostvars[‘dbhost1’][‘ansible_default_ipv4’][‘address’], даже если dbservers не входят в плей или исключены с помощью --limit.

Локальные плейбуки

Иногда полезно запускать плейбук локально на удалённом узле, а не подключаться к нему по SSH. Например, это может быть полезно для обеспечения нужной конфигурации системы при запуске плейбука из crontab. Также так можно запускать плейбук в установщике ОС, например в Anaconda kickstart.

Чтобы запустить плейбук целиком локально, просто задайте строке hosts: значение hosts: 127.0.0.1, а затем запустите плейбук следующим образом:

ansible-playbook playbook.yml --connection=local

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

---
- hosts: 127.0.0.1
  connection: local

Примечание

Если вы зададите локальное подключение, но не установите ansible_python_interpreter, модули будут запускаться с помощью /usr/bin/python, а не {{ ansible_playbook_python }}. Например, задайте ansible_python_interpreter: “{{ ansible_playbook_python }}” в host_vars/localhost.yml. Эту проблему можно избежать, используя вместо этого local_action или delegate_to: localhost.

См. также

Плейбуки Ansible

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

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

Дополнительные способы управления тем, как и где 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_delegation.html

Spec-Zone.ru

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