Execution Environments: контейнеры для запуска Ansible

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

Execution Environments: контейнеры для запуска Ansible

Сообщение 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
Знакомая боль: плейбук отлично крутится на твоём ноуте, ты пушишь его в git, коллега запускает у себя - и всё разваливается. У тебя ansible-core 2.16 и свежая community.general, у него 2.14 и старая коллекция из системного пакета. На CI-раннере вообще нет нужного питоновского модуля pyVmomi, а боевой bastion не видит kubernetes.core. Каждый запуск превращается в лотерею: один и тот же код ведёт себя по-разному в зависимости от того, ГДЕ его запустили. Это и есть проблема консистентности окружения, и именно её решает ansible execution environment.

Что такое Execution Environment и зачем он нужен

Execution Environment (EE) - это контейнерный образ, внутри которого упакован весь стек, нужный для запуска Ansible: сам ansible-core, ansible-runner, набор коллекций, Python-зависимости и системные пакеты. Идея простая до гениальности: вместо того чтобы тащить и синхронизировать всё это по куче управляющих машин, ты собираешь один образ и запускаешь Ansible ВНУТРИ него. Образ один и тот же у тебя на ноуте, у коллеги, на CI и в проде. Версии зафиксированы, зависимости вмёрзли в слои контейнера. Плейбук теперь работает одинаково везде - потому что везде один и тот же execution environment ansible.

Раньше эту роль играл хост: ставишь ansible через dnf или pip, докидываешь коллекции через ansible-galaxy, ставишь python-зависимости в systemwide или venv. Хрупкая конструкция. Обновил одну библиотеку для другого проекта - сломал три плейбука. EE решает это через изоляцию: окружение - это артефакт, который ты версионируешь и распространяешь как любой другой контейнер. По сути ansible контейнер становится единицей поставки автоматизации, ровно как Docker-образ - единицей поставки приложения.
EE - это для Ansible примерно то же, чем стал контейнер для приложений: "работает на моей машине" перестаёт быть оправданием, потому что машина теперь едет вместе с кодом.
Важно: для Ansible Automation Platform (AAP 2.x) EE - это не опция, а основа исполнения. Automation Controller (бывший Tower) вообще не умеет запускать джобы иначе как внутри execution environment. Так что если ты целишься в энтерпрайз с AAP - тема обязательная.

Изображение

Из чего собран ansible ee: разбираем по слоям

Образ EE строится инструментом ansible-builder из декларативного файла execution-environment.yml (актуальная схема - version 3). Он описывает четыре кита окружения:
  • Базовый образ - от чего наследуемся. Red Hat даёт официальные ee-minimal и ee-supported, но можно взять и чистую базу вроде registry.fedoraproject.org/fedora или ubi9.
  • ansible-core - версия движка. Ставится через pip, версию фиксируешь явно.
  • Коллекции - описываются в requirements.yml (формат ansible-galaxy). Сюда складываешь community.general, ansible.posix, kubernetes.core и прочее.
  • Python-зависимости - requirements.txt. Все pip-пакеты, которые нужны модулям: jmespath для json_query, pyvmomi для VMware, kubernetes для k8s.
  • Системные пакеты - bindep.txt в формате bindep. Сюда идут rpm/deb уровня ОС: openssh-clients, sshpass, git, gcc для сборки нативных питоновских колёс.
Вот как выглядит современный execution-environment.yml по схеме v3:

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

version: 3

images:
  base_image:
    name: registry.redhat.io/ansible-automation-platform-25/ee-minimal-rhel9:latest

dependencies:
  ansible_core:
    package_pip: ansible-core==2.16.*
  ansible_runner:
    package_pip: ansible-runner
  python: requirements.txt
  galaxy: requirements.yml
  system: bindep.txt

options:
  package_manager_path: /usr/bin/microdnf
Файлы зависимостей лежат рядом. requirements.yml:

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

---
collections:
  - name: ansible.posix
    version: ">=1.5.0"
  - name: community.general
  - name: kubernetes.core
requirements.txt:

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

kubernetes>=24.2.0
jmespath
bindep.txt (третья колонка - метка платформы):

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

git [platform:rpm]
openssh-clients [platform:rpm]
sshpass [platform:rpm]
Собираем образ:

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

ansible-builder build --tag my-ee:1.0 -f execution-environment.yml -v 3
Под капотом ansible-builder генерирует Containerfile и context, а собирает всё podman (на RHEL он по умолчанию, rootless, без демона - в отличие от Docker). На выходе - локальный образ my-ee:1.0.

Практика: запускаем плейбук в execution environment

Запускать плейбук в EE удобнее всего через ansible-navigator - это современная замена ansible-playbook, которая умеет работать с контейнерами из коробки. Простейший плейбук test.yml:

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

---
- name: Проверка идемпотентной настройки
  hosts: web
  become: true
  tasks:
    - name: Установить nginx
      ansible.builtin.dnf:
        name: nginx
        state: present

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

    - name: Положить конфиг
      ansible.builtin.copy:
        src: nginx.conf
        dest: /etc/nginx/nginx.conf
        owner: root
        group: root
        mode: "0644"
Запуск в нашем образе:

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

ansible-navigator run test.yml \
  --execution-environment-image my-ee:1.0 \
  --mode stdout \
  --pull-policy missing
Флаг --eei (короткий синоним --execution-environment-image) говорит, какой ansible контейнер использовать. --mode stdout даёт привычный вывод вместо интерактивного TUI. Проверить, что внутри образа лежит, можно не вскрывая его руками:

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

ansible-navigator images --execution-environment-image my-ee:1.0
navigator покажет версию ansible-core, список установленных коллекций и python-пакетов прямо из образа. Очень удобно, когда надо понять, почему модуль "не находится".

Типичные грабли
  • Забыл version: 3. Если в execution-environment.yml нет строки version, ansible-builder считает, что это схема v1, и валится на незнакомых ключах. Всегда указывай версию явно.
  • Коллекция есть, а модуль падает. Классика: положил kubernetes.core в requirements.yml, а питоновский пакет kubernetes в requirements.txt не добавил. Коллекция - это обёртка, ей нужны python-библиотеки. ansible-builder подтягивает зависимости коллекций автоматически, но не всегда полно - проверяй руками.
  • Нет компилятора для нативных колёс. Часть pip-пакетов собирается из исходников. Нет gcc и python3-devel в bindep.txt - сборка образа падает с невнятной ошибкой про wheel. Докинь их в системные зависимости.
  • SELinux и тома. Когда монтируешь рабочую директорию в контейнер на RHEL, без правильной метки (:Z) SELinux заблокирует доступ. navigator обычно метит сам, но если используешь podman run напрямую - помни про :Z.
  • pull-policy always на медленном канале. По умолчанию navigator может лезть в реестр каждый запуск. Для локального образа ставь --pull-policy missing, иначе будешь ждать сеть на ровном месте.
Мини-лаба: собери свой первый ansible ee

Повтори руками, без этого тема не уляжется:
  • Поставь инструменты: dnf install ansible-builder ansible-navigator (или pip в venv).
  • Создай каталог проекта, положи в него execution-environment.yml (schema v3), requirements.yml с community.general, requirements.txt с jmespath, bindep.txt с git.
  • Собери образ: ansible-builder build --tag lab-ee:1.0 -v 3. Дождись успеха и найди образ в podman images.
  • Напиши плейбук с одной задачей через community.general (например, community.general.timezone) и фильтром json_query (он требует jmespath - так проверишь, что python-зависимость уехала в образ).
  • Запусти через ansible-navigator run ... --eei lab-ee:1.0 --mode stdout. Прогони дважды - убедись, что второй прогон идемпотентен (changed=0).
  • Глянь содержимое: ansible-navigator images --eei lab-ee:1.0 и проверь версию ansible-core.
Контрольные вопросы
  • Какие четыре класса зависимостей описывает execution-environment.yml и в каких файлах живут коллекции, python- и системные пакеты?
  • Чем грозит отсутствие строки version: 3 в определении EE и почему?
  • Зачем коллекции kubernetes.core нужен ещё и pip-пакет kubernetes, и где его прописать?
  • Каким флагом ansible-navigator указываешь, какой execution environment использовать для прогона?
Итог

Execution Environment превращает капризное "у меня работает" в воспроизводимый артефакт: один контейнерный образ с зафиксированными ansible-core, коллекциями и зависимостями ездит вместе с твоим кодом по всем машинам и пайплайнам. Собираешь его через ansible-builder из execution-environment.yml (schema v3), запускаешь через ansible-navigator с флагом --eei. Для AAP это фундамент, а на современном RHCE (версия EX294 на RHEL 9 c AAP 2.x) понимание EE и ansible-navigator - уже часть программы, а не экзотика. Разберёшься здесь - перестанешь ловить плавающие баги окружения навсегда.
👍4 ❤️3 🔥1 😄 🤔2
Аватара пользователя
grumpymonk
Сообщения: 1
Зарегистрирован: 19 май 2026, 08:58

Re: Execution Environments: контейнеры для запуска Ansible

Сообщение grumpymonk »

Наконец дошло, зачем эта возня с контейнерами вокруг ansible. Месяц бился, почему на джесткинс-раннере плейбук падал на json_query, а локально нет - оказалось ровно ваш кейс с jmespath, которого в окружении раннера не было. Собрал EE - проблема ушла.
👍1 ❤️ 🔥 😄 🤔
Аватара пользователя
idleraccoon
Сообщения: 1
Зарегистрирован: 03 июн 2026, 03:38

Re: Execution Environments: контейнеры для запуска Ansible

Сообщение idleraccoon »

Вопрос по экзамену: на EX294v9 (RHEL 9) реально могут попросить собрать EE через ansible-builder, или там только запуск через navigator с готовым образом? Хочу понять, нужно ли заучивать синтаксис execution-environment.yml наизусть или достаточно уметь прогнать плейбук в EE.
👍1 ❤️1 🔥1 😄 🤔1
Ответить
← Предыдущая глава
Коллекции Ansible: ansible.posix, community и своя коллекция
Следующая глава →
Сборка Execution Environment с ansible-builder

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

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

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

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

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