- Добавлен docs/custom-addons.md: структура addons/<name>, playbook, group_vars, playbooks/addons.yml, Makefile, Molecule, чеклист и см. также. - docs/addons.md, getting-started.md: отсылки на custom-addons.md. - README.md: строка в таблице документации. - docs/molecule-testing.md: уточнены molecule-prometheus/istio (тесты аддонов), разделы prometheus-stack/istio, ссылка на руководство в блоке про новые тесты. - docs/make-reference.md: примечание к make addon-<name>.
12 KiB
Свои аддоны для k3s-ansible
Этот документ описывает, как добавить собственный аддон в проект: структуру каталога, плейбуки, переменные, интеграцию в make, и тесты Molecule. Предполагается, что вы уже читали Аддоны и понимаете, как включать готовые компоненты через group_vars/all/addons.yml.
1. Что считается «аддоном»
Аддон — это отдельная Ansible-роль с тонким плейбуком в каталоге addons/<имя>/. Установка с хоста делается так:
make addon-<имя> # прямой запуск
make install-addons # все аддоны с `addon_<имя>: true` в addons.yml
Внутри Docker runner вызывается addon <имя> (см. docker/entrypoint.sh): исполняется файл addons/<имя>/playbook.yml. Имя каталога должно совпадать с аргументом addon (например addons/my-app/playbook.yml → make addon-my-app).
2. Минимальная структура каталога
addons/<name>/
├── README.md # обязательно: назначение, переменные, примеры
├── playbook.yml # точка входа для make addon-<name>
└── role/
├── tasks/main.yml
├── defaults/main.yml # все пользовательские переменные с разумными default
├── meta/main.yml # опционально: dependencies, role_name
├── templates/ # Jinja2 (.j2) — манифесты, values для Helm
├── files/ # статические файлы
└── molecule/
└── default/
├── molecule.yml # драйвер docker, платформа master01
├── converge.yml # «собрать» артефакты для проверки
└── verify.yml # assert
- Роль лежит внутри
addons/<name>/role/, путь в плейбуке — относительноplaybook.yml(см. ниже). - Для Helm-чарта часто добавляют
role/chart/или скачивание chart вtasks— ориентируйтесь на существующие аддоны (gitea,loki,technitium-dns).
3. Плейбук playbook.yml
3.1. Вариант «только аддон» (как у большинства поставляемых аддонов)
---
- name: Install My Application
hosts: k3s_master[0]
gather_facts: false
become: true
roles:
- role: "{{ playbook_dir }}/role"
playbook_dir— каталог, где лежит этотplaybook.yml(т.е.addons/<name>/).hostsвыбирайте по смыслу (см. раздел 5 ниже).
3.2. Плейбук в общем списке playbooks/addons.yml
Для участия в make install-addons / make install-full добавьте отдельный play в playbooks/addons.yml в правильном месте по зависимостям (сначала NFS/CSI, ingress, cert-manager, затем остальные):
- name: Install My Application
hosts: k3s_master[0]
gather_facts: false
become: true
when: addon_my_app | default(false) | bool
roles:
- role: "{{ playbook_dir }}/../addons/my-app/role"
Имя флага в when и в group_vars должно быть согласовано: addon_my_app → addon_my_app: true/false.
4. Переменные: group_vars/all/addons.yml
-
Флаг включения (в начале файла, рядом с остальными
addon_*):addon_my_app: false -
Переменные по умолчанию для аддона (префикс лучше делать уникальным, например
my_app_*):# ─── My Application ───────────────────────────────────── my_app_namespace: "my-app" my_app_ingress_host: "myapp.example.com" -
Секреты — только через Ansible Vault, в
group_vars/all/vault.yml(и пример вvault.yml.example):vault_my_app_password: "..."
См. существующие комментарии в addons.yml: там же лежат примеры для похожих сервисов.
5. Выбор группы hosts и порядок в addons.yml
| Группа / паттерн | Когда использовать |
|---|---|
k3s_master[0] |
Почти все компоненты, которые ставятся через kubectl/helm с одной control-plane ноды |
k3s_cluster |
DaemonSet / агенты на всех нодах (пример: ingress-nginx, часть CSI) |
nfs_server |
NFS-сервер не на K8s (отдельная группа в inventory) |
hysteria2_server |
Удалённый VPS (см. hysteria2-server) |
splitgw |
Хосты split-gateway вне K8s или вместе с k8s в зависимости от роли |
Порядок play в playbooks/addons.yml важен: не ставьте приложение, требующее Ingress, раньше play с ingress-nginx, не ставьте TLS-зависимое раньше cert-manager, если оно ожидает готовые ClusterIssuer. Новый аддон обычно добавляют в конец или сразу после логического предка.
6. Цель Makefile
Чтобы make addon-<name> существовал, в Makefile в секции аддонов должен быть таргет вида:
addon-my-app: _check_env _check_image
@printf "$(CYAN)Устанавливаю My Application...$(NC)\n"
$(DOCKER_RUN) addon my-app $(ARGS)
Имя после addon — каталог addons/my-app/. См. комментарий в Makefile: «Добавить новый аддон: создай addons//playbook.yml + addons//role/».
ARGS передаётся в ansible-playbook как extra vars (кастомизация без правки addons.yml).
7. Тесты Molecule
Без Molecule легко сломать шаблоны при рефакторинге. Рекомендуемый минимум — сценарий role/molecule/default/.
7.1. Как запускается
make build
make molecule-addon-my-app
Runner (docker/entrypoint.sh, команда molecule-addon) заходит в каталог addons/<name>/role и выполняет molecule test (см. JUNIT_OUTPUT_DIR для отчётов в составе make molecule-all).
7.2. molecule.yml
Обычно одна тестовая нода master01 (образ geerlingguy/docker-ubuntu2204-ansible), без privileged, если не нужен K3S в контейнере. Шаблон — любой существующий аддон рядом с вашим по сложности.
7.3. converge.yml
Типовые варианты:
- Рендер Jinja2 + проверка файла (простой аддон).
- Helm:
template+destв/tmp/...+helm lint/helm template- Команды
helmвыполняйте сdelegate_to: localhostиrun_once: true, иначе бинарник не найдётся в ноде Molecule. - То же для
ansible.builtin.copy/template, если пишете файлы, которые читаетhelmс localhost: пишите на localhost (иначе «файл не найден» приdelegate_to: localhostу helm).
- Команды
- Переменные — задайте в
vars:все, что обязаны знать шаблоны роли (в т.ч. пустые строки для optional полей), иначеAnsibleUndefinedVariableв тесте.
7.4. verify.yml
- Assert по содержимому сгенерированных YAML/манифестов.
- Булевы из
slurp+from_yamlчасто приходят строками — сравнивайте так:(v.flag | string | lower) == 'true'. - Если проверяете multi-doc YAML (
---), используйтеfrom_yaml_all/ разбор по документам. hosts: localhostудобен, если артефакты гарантированно на runner (файлы в/tmpпослеdelegate_to: localhost).
Подробности и типовые ошибки: Тестирование через Molecule.
7.5. Включение в общий прогон
После готового сценария добавьте в Makefile цель molecule-addon-<name> (по аналогии с соседними аддонами) и вызов из molecule-addon-all, иначе CI/ручной make molecule-addon-all не увидит аддон.
8. Документация в репозитории
addons/<name>/README.md: назначение, требования (ingress, БД, storage), переменные, примерmake, ссылки на апстрим.- Корневой Аддоны: добавьте строку в таблицу «Каталог аддонов» (флаг, краткое описание, ссылка на README), если аддон попал в основной репозиторий.
- Секреты — перечислить в
group_vars/all/vault.yml.example, если введены новыеvault_*ключи.
9. Чеклист нового аддона
addons/<name>/playbook.yml+role/с осмысленнымиdefaultsи идемпотентнымиtasksaddons/<name>/README.mdaddon_<name>: falseи переменные вgroup_vars/all/addons.yml(и секреты вvaultпри необходимости)- Play в
playbooks/addons.ymlсwhen: addon_<name> | default(false) | boolи корректнымhosts - Таргет
addon-<name>вMakefile - Molecule:
role/molecule/default/*,make molecule-addon-<name>зелёный - Добавить
molecule-addon-<name>вmolecule-addon-allвMakefile(если аддон в основной ветке репо) - Строка в таблице docs/addons.md
10. Кастомизация без форка (альтернатива «своему» аддону)
Если нужно один раз переопределить поведение существующей роли:
make addon-<name> ARGS="-e var=value"host_vars/<хост>.yml/group_varsдля тонкой настройки- Для постоянного форка лучше скопировать роль в
addons/<your-name>/и следовать чеклисту выше, явно называя сущности, чтобы не пересекаться с апстримом.