Архитектура Ansible: control node, узлы, модули и плагины

Рейтинг: 60.1% · 14 голосов
Подробный курс по Ansible с прицелом на экзамен RHCE EX294: установка и инвентарь, плейбуки, переменные и факты, Vault, циклы и условия, шаблоны Jinja2, роли и коллекции, Execution Environments и ansible-navigator, управление системами (диски, LVM, cron, SELinux, firewalld). Примеры на RHEL/Fedora. Актуально на 2026.
Ответить
Аватара пользователя
Maksim_DevOps
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Архитектура Ansible: control node, узлы, модули и плагины

Сообщение Maksim_DevOps »

Оглавление курса (47)
  1. Что такое Ansible и зачем он нужен: автоматизация без агентов
  2. Сертификация RHCE и экзамен EX294: что внутри и как готовиться
  3. Архитектура Ansible: control node, узлы, модули и плагины (вы здесь)
  4. Установка Ansible на control node: dnf, pip и версии ansible-core
  5. Подготовка управляемых узлов: SSH, пользователь и sudo
  6. Инвентарь Ansible: hosts, группы и переменные
  7. Настройка Ansible: файл ansible.cfg и приоритеты конфигурации
  8. Host patterns и инструменты командной строки Ansible
  9. Ad hoc команды Ansible: быстрые задачи без плейбука
  10. Ansible playbook: что это такое и как устроен
  11. Структура плейбука: play, task, модули и переменные
  12. Запуск плейбуков: проверка, теги, ограничения и отладка
  13. Параллелизм и порядок выполнения: forks, serial, strategy
  14. Факты Ansible: сбор информации об узлах
  15. Переменные Ansible: типы, объявление и приоритет
  16. Регистрация результатов и специальные переменные
  17. Ansible Vault: шифрование паролей и секретов
  18. Организация инвентаря: group_vars, host_vars и вложенные группы
  19. Динамический инвентарь и инвентарные плагины
  20. Циклы в Ansible: loop, списки и словари
  21. Повтор задачи до условия: until, retries и delay
  22. Условия в Ansible: директива when и логика
  23. Jinja2 в Ansible: выражения, фильтры и подстановки
  24. Обработчики Ansible: handlers, notify и flush_handlers
  25. Обработка ошибок: failed_when, changed_when и ignore_errors
  26. Блоки в Ansible: block, rescue и always
  27. Управление файлами: модули file, copy, fetch и stat
  28. Архивы и сборка файлов: archive, unarchive, assemble
  29. Точечное редактирование файлов: lineinfile и blockinfile
  30. Шаблоны Jinja2: модуль template и динамические конфиги
  31. Jinja2 продвинуто: фильтры, циклы, макросы и lookup
  32. Модули Ansible: ansible-doc и поиск нужного модуля
  33. Разработка собственного модуля Ansible на Python
  34. Роли Ansible и Ansible Galaxy: переиспользование
  35. Разработка роли Ansible: создание с нуля
  36. Зависимости ролей и requirements.yml
  37. Коллекции Ansible: ansible.posix, community и своя коллекция
  38. Execution Environments: контейнеры для запуска Ansible
  39. Сборка Execution Environment с ansible-builder
  40. ansible-navigator: запуск плейбуков в Execution Environment
  41. Управление SSH-ключами через Ansible: authorized_key
  42. Управление дисками: filesystem, mount и parted
  43. LVM через Ansible: тома, группы и расширение
  44. Планировщик задач: cron и systemd timers через Ansible
  45. Безопасность: hardening SSH и репозитории dnf/yum
  46. SELinux через Ansible: булевы, контексты и порты
  47. Сквозной проект и подготовка к экзамену EX294
Ты установил Ansible, прогнал первый ping и увидел зелёный SUCCESS. Отлично. Но как только дойдёт до боевых плейбуков, посыпятся вопросы, на которых спотыкается большинство новичков и половина людей на экзамене RHCE. Почему на управляемых серверах ничего не нужно ставить, кроме Python и SSH? Куда и как попадает код модуля? Что такое эти длинные имена вида ansible.builtin.copy и почему короткое copy однажды перестанет работать? В этом уроке разберём архитектуру по косточкам - без неё ты будешь писать плейбуки наугад и злиться, когда они ломаются по непонятным причинам.

Control node и управляемые узлы: кто кого толкает

Ansible построен на простой и при этом гениальной идее - push-модель без агента. Есть одна управляющая машина (control node) и есть пачка управляемых узлов (managed nodes). Всё движение идёт в одну сторону: control node подключается к узлам и продавливает на них изменения. Обратного канала, демона или постоянного агента нет - это принципиально отличает Ansible от Puppet или Chef, где на каждой машине крутится свой агент.

На control node живёт ansible-core - это и есть сам движок: бинарники ansible, ansible-playbook, ansible-navigator, парсер инвентаря, набор базовых модулей и плагинов. Ставится он на RHEL/Fedora из пакета:

Код: Выделить всё

sudo dnf install ansible-core
ansible --version
# ansible [core 2.20.x]
#   python version = 3.12.x
Требование к control node жёсткое: это Linux/Unix с установленным Python. Windows как control node официально не поддерживается (только как управляемый узел через WinRM/SSH). А вот управляемому узлу нужен минимум: рабочий Python и доступ по SSH. Никакого ansible на нём не стоит и не должно. Именно поэтому связка ansible python такая лёгкая - ты управляешь сотней серверов, не выкатывая на них ни одного дополнительного пакета.

Код: Выделить всё

# control node -> managed node, ничего предварительно не ставя на узел
ansible all -i inventory -m ansible.builtin.ping
# web1 | SUCCESS => { "ping": "pong" }
Модуль ping тут не сетевой - он проверяет, что Ansible смог подключиться по SSH и запустить Python на той стороне. На RHEL 9/10 системный Python (/usr/libexec/platform-python или /usr/bin/python3) есть из коробки, поэтому управляемый узел обычно готов сразу. Для Ubuntu/Debian иногда придётся доставить python3 (например, через raw-команду на голую систему), а на RED OS и Astra Linux Python тоже идёт штатно.

Изображение

Модули: ansible modules как единицы работы

Модуль - это атомарная единица работы. Когда ты пишешь задачу "скопировать файл", "создать пользователя", "открыть порт в firewalld", за каждым действием стоит конкретный модуль. Все ansible modules - это, по сути, небольшие программы (чаще всего на Python), которые принимают параметры, выполняют действие на узле и возвращают JSON с результатом: что изменилось, что осталось как было, были ли ошибки.

Ключевое свойство нормального модуля - идемпотентность. Запусти задачу один раз или десять раз подряд - результат на узле одинаковый, а ненужные изменения не делаются. Модуль сам проверяет текущее состояние и меняет систему, только если она не совпадает с желаемой. Поэтому в выводе ты видишь changed=1 при первом прогоне и ok (changed=0) при повторном.

Код: Выделить всё

- name: Положить конфиг на узлы
  hosts: webservers
  become: true
  tasks:
    - name: Скопировать nginx.conf
      ansible.builtin.copy:
        src: files/nginx.conf
        dest: /etc/nginx/nginx.conf
        owner: root
        group: root
        mode: "0644"

    - name: Открыть http в firewalld
      ansible.posix.firewalld:
        service: http
        permanent: true
        immediate: true
        state: enabled

    - name: Положить SSH-ключ деплоера
      ansible.posix.authorized_key:
        user: deploy
        key: "{{ lookup('file', 'files/deploy.pub') }}"
        state: present
Обрати внимание на длинные имена: ansible.builtin.copy, ansible.posix.firewalld. Это и есть FQCN.

FQCN и ansible builtin: почему имена стали длинными

FQCN - fully qualified collection name, полностью квалифицированное имя в формате namespace.collection.module. Разберём ansible.builtin.file по частям:
  • ansible - namespace (пространство имён, по сути вендор/команда)
  • builtin - имя коллекции
  • file - имя модуля внутри коллекции
Коллекция builtin от namespace ansible - это базовый набор, который встроен прямо в ansible-core. Сюда входят copy, file, template, service, systemd, dnf, user, command, shell и десятки других - всё, что доступно сразу после установки ansible-core без единой дополнительной зависимости. Когда люди гуглят ansible builtin, они ищут именно эти базовые модули.

Почему перешли на длинные имена? Раньше писали просто copy или file. Но модулей с одинаковыми короткими именами в разных коллекциях стало много, и возникали коллизии: какой именно user ты имел в виду? FQCN снимает любую двусмысленность - ты явно указываешь, из какой коллекции брать модуль. Короткие имена пока работают для встроенных модулей, но это считается устаревшим стилем, и для community-модулей короткое имя может вообще не разрешиться.

Это прямо влияет на экзамен. На RHCE/EX294 проверяют, что ты понимаешь модули и пишешь их полными именами. Срезаются на том, что используют, например, posix-модуль firewalld или authorized_key по короткому имени - а они живут не в ansible.builtin, а в коллекции ansible.posix, которая идёт отдельным контентом. Запомни границу: ansible.posix.firewalld и ansible.posix.authorized_key - это НЕ builtin. Если их короткое имя не разрешается, плейбук падает с "couldn't resolve module". На реальном экзамене это потерянные баллы на ровном месте.

Быстрый способ узнать FQCN и параметры любого модуля - встроенная документация:

Код: Выделить всё

ansible-doc ansible.builtin.file
ansible-doc -l | grep firewalld     # найти полное имя
ansible-doc ansible.posix.firewalld
Плагины и коллекции: из чего ещё собран ansible core

Кроме модулей в ansible core есть плагины - это код, который расширяет сам движок, а не делает работу на узле. Их легко перепутать с модулями, но разница важная:
  • connection - как подключаться к узлу: ssh (по умолчанию), local, winrm, podman, docker
  • inventory - откуда брать список хостов: статический ini/yaml-файл или динамический (AWS, GCP, скрипты)
  • lookup - подтянуть данные на control node во время рендера: lookup('file', ...), lookup('env', ...), lookup('password', ...)
  • filter - Jinja2-фильтры для преобразования данных: {{ myvar | default('x') }}, | to_json, | regex_replace(...)
  • плюс callback (вывод), strategy (как раскатывать задачи), become (повышение прав) и другие
Модуль исполняется НА узле, плагин - в основном НА control node в процессе самого Ansible. Запомнишь это - перестанешь путаться, почему lookup читает файл с управляющей машины, а не с целевого сервера.

Теперь про упаковку. Коллекция (collection) - это пакет контента: модули, плагины, роли и playbooks, собранные вместе и распространяемые как единое целое. Ставятся коллекции из Ansible Galaxy или приватного хаба:

Код: Выделить всё

ansible-galaxy collection install ansible.posix
ansible-galaxy collection install community.general
ansible-galaxy collection list
Отсюда три разных продукта, которые постоянно путают:
  • ansible-core - голый движок плюс коллекция ansible.builtin. Минимальная сборка, версии вида 2.20.x. Это то, что ставишь через dnf install ansible-core.
  • Ansible community package - тот же ansible-core, но в комплекте с сотнями проверенных коллекций (ansible.posix, community.general и так далее). Версии другие, крупные - 13.x в 2026 году. Удобно для старта, когда не хочешь руками доставлять коллекции.
  • Ansible Automation Platform (AAP) - коммерческий продукт Red Hat: веб-интерфейс и API (раньше Tower/AWX), Execution Environments (контейнеры с зафиксированным набором ansible-core и коллекций), RBAC, расписания, аналитика. Это уже про управление автоматизацией в команде на масштабе.
На современном RHCE всё чаще встречается ansible-navigator и Execution Environment - запуск плейбуков внутри контейнера с заранее собранным окружением (описывается в execution-environment.yml). Команда ansible-navigator run playbook.yml гоняет плейбук в EE, чтобы у всех была одинаковая версия движка и коллекций. Концепция та же, что и раньше, просто движок едет в контейнере.

Как модуль попадает на узел и исчезает

Самое интересное - жизненный цикл модуля. Многие думают, что Ansible "удалённо вызывает команды". Нет. Происходит вот что: для каждой задачи Ansible на control node собирает код модуля с подставленными параметрами в один самодостаточный Python-пакет, по SSH копирует его во временную директорию на узле (обычно ~/.ansible/tmp/), запускает там через Python, ловит JSON-результат, а затем удаляет временные файлы. Узел остаётся чистым - никакого мусора и никаких следов агента.

Отсюда вытекает то самое требование "только Python + SSH" на управляемом узле. Питон нужен, чтобы исполнить доставленный модуль, SSH - чтобы доставить и забрать результат. Всё. Это и делает Ansible безагентным.

Типичные грабли
  • Используешь firewalld, authorized_key, parted по короткому имени и удивляешься "module not found". Они в коллекциях (ansible.posix, community.general), а не в builtin. Лечится FQCN и установкой коллекции.
  • Ставишь ansible-core и ждёшь, что community-модули заработают сами. Нет - либо ставь community package, либо доставляй коллекции через ansible-galaxy.
  • Путаешь lookup и slurp. lookup('file', ...) читает файл с control node при рендере. Чтобы прочитать файл С УЗЛА, нужен модуль ansible.builtin.slurp, который исполняется на узле.
  • Думаешь, что command и shell - модули с проверкой состояния. Нет, они не идемпотентны сами по себе. По возможности бери специализированный модуль (dnf вместо "shell: dnf install"), он умеет проверять состояние.
  • На голой Debian-системе ping падает, потому что нет python3. Доставь его модулем raw до основного плейбука.
Мини-лаба
Повтори руками на тестовой RHEL/Fedora-машине (или RED OS):
  • ansible --version - запиши версию ansible-core и Python.
  • ansible all -i inventory -m ansible.builtin.ping - убедись, что узел отвечает pong.
  • ansible-doc -l | grep -E "firewalld|authorized_key" - найди полные FQCN этих модулей.
  • ansible-galaxy collection list - посмотри, какие коллекции уже стоят. Поставь ansible.posix, если её нет.
  • Напиши плейбук из трёх задач выше (copy, firewalld, authorized_key), прогони дважды подряд и сравни changed в первом и втором запуске - так ты увидишь идемпотентность вживую.
Контрольные вопросы
  • Что должно стоять на управляемом узле, чтобы Ansible им управлял, и почему этого достаточно?
  • Разбери ansible.builtin.file на namespace, collection и module. Какой из модулей НЕ из builtin: copy, firewalld, template, user?
  • Чем модуль отличается от плагина? Где исполняется lookup, а где copy?
  • В чём разница между ansible-core, Ansible community package и AAP?
Итог
Ansible - это безагентная push-система: control node с ansible-core продавливает изменения на узлы, которым нужны только Python и SSH. Работу делают модули (ansible modules), движок расширяют плагины, всё это пакуется в коллекции. FQCN вида ansible.builtin.copy - современный стандарт, и на RHCE именно непонимание границы builtin/posix/community чаще всего стоит баллов. Держи в голове цепочку "control node собрал модуль -> доставил по SSH -> Python исполнил -> результат вернулся -> временные файлы удалены" - и поведение Ansible перестанет быть магией.
👍7 ❤️1 🔥1 😄 🤔
Аватара пользователя
liessel
Сообщения: 1
Зарегистрирован: 11 май 2026, 00:43

Re: Архитектура Ansible: control node, узлы, модули и плагины

Сообщение liessel »

Вот про lookup и slurp прям больно зашло. Полгода читал файлы lookup'ом и не понимал, почему на проде пустота - оказывается оно с control node тянет, а не с узла. Спасибо, теперь дошло.
👍1 ❤️ 🔥 😄 🤔1
Аватара пользователя
Priapos
Сообщения: 1
Зарегистрирован: 12 май 2026, 01:42

Re: Архитектура Ansible: control node, узлы, модули и плагины

Сообщение Priapos »

А можно чуть подробнее про execution environment и ansible-navigator? На RHCE 10 говорят без него вообще никак, а в большинстве гайдов всё ещё по-старому через ansible-playbook гоняют.
👍1 ❤️ 🔥1 😄 🤔
Ответить
← Предыдущая глава
Сертификация RHCE и экзамен EX294: что внутри и как готовиться
Следующая глава →
Установка Ansible на control node: dnf, pip и версии ansible-core

Все главы курса «Ansible: автоматизация и подготовка к RHCE (EX294)»

Поделиться темой: ✈ Telegram VK
Похожие запросы: что такое ansible простыми словамиansible для начинающих с чего начатьустановка ansible на linuxansible inventory и hosts файлчто такое playbook в ansibleструктура ansible playbook из чего состоит

Вернуться в «Ansible: автоматизация и подготовка к RHCE (EX294)»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость