Files
K3S/docs/molecule-testing.md
Sergey Antropoff eccc1c2a01 docs: полная документация проекта — docs/ и README.md для каждого аддона
- README.md: перепиcан как компактный обзор (98 строк) с навигацией по docs/
- docs/: 13 файлов — getting-started, architecture, configuration, addons,
  storage, security, cicd, observability, networking, operations,
  make-reference, molecule-testing, troubleshooting
- addons/*/README.md: 31 новый файл — описание, параметры, примеры кода
  для каждого из 34 аддонов (vault и external-secrets уже существовали)
2026-04-26 00:22:06 +03:00

8.3 KiB
Raw Blame History

Тестирование через Molecule

Molecule — стандартный инструмент для тестирования Ansible ролей. Каждая роль запускается в Docker-контейнерах, проходит набор автоматических проверок и удаляется. Реальные серверы не нужны.

Требования

Только Docker — Molecule, Python и зависимости уже внутри образа k3s-ansible.

make build          # собрать образ (один раз)
make molecule-k3s   # запустить тест

Как это работает: make molecule-* запускает контейнер k3s-ansible с примонтированным Docker socket. Внутри этого контейнера Molecule создаёт тестовые контейнеры — Docker внутри Docker без демона (только socket от хоста).

Доступные тесты

make molecule-k3s           # Роль k3s — 3 ноды: master01, worker01, rpi01 (~8-12 мин)
make molecule-prometheus    # Роль prometheus-stack (~2-3 мин)
make molecule-istio         # Роль istio (~2-3 мин)
make molecule-all           # Все тесты последовательно (~15-20 мин)
make molecule-lint          # Линтинг YAML + ansible-lint (~30 сек)

Жизненный цикл теста

dependency   → зависимые роли
lint         → yamllint + ansible-lint
syntax       → ansible-playbook --syntax-check
create       → запустить Docker-контейнер
prepare      → подготовить контейнер (Python, collections)
converge     → выполнить тестируемые задачи
idempotency  → повторный converge (проверка изменений = 0)
verify       → assertions (проверить результаты)
destroy      → удалить контейнер

При ошибке на любой фазе тест падает, контейнер удаляется автоматически.

Что тестирует каждая роль

Роль k3s (3 контейнера, ~8-12 мин)

Контейнер Образ Соответствует
master01 geerlingguy/docker-ubuntu2204-ansible Ubuntu 22.04 x86_64
worker01 geerlingguy/docker-ubuntu2204-ansible Ubuntu 22.04 x86_64
rpi01 geerlingguy/docker-debian12-ansible Debian 12 (Raspberry Pi OS)

Что проверяет verify.yml:

Проверка Нода Что именно
/etc/kubernetes/k3s существует все Директория создана
config.yaml существует, права 0600 все Файл конфига
cluster-init: true master01 Первый мастер инициализирует
server: https://...:6443 worker01, rpi01 Присоединяются к master01
cluster-cidr: 10.42.0.0/16 все Правильная подсеть
disable: [traefik] все Traefik выключен
net.ipv4.ip_forward = 1 все sysctl применён

Роль prometheus-stack (~2-3 мин)

Тестирует рендеринг Jinja2-шаблона без privileged режима.

Проверка Что именно
grafana.adminUser Значение переменной
grafana.persistence.enabled true
prometheus.retention 7d
alertmanager.enabled true
nodeExporter.enabled true

Роль istio (~2-3 мин)

Тестирует рендеринг всех четырёх шаблонов роли.

Файл Проверка
istiod-values.yaml Ресурсы pilot, meshConfig, enablePrometheusMerge: true
kiali-values.yaml auth.strategy: token, Prometheus URL
peer-authentication.yaml kind: PeerAuthentication, spec.mtls.mode: STRICT
kiali-token-secret.yaml type: kubernetes.io/service-account-token

Запуск тестов пошагово

Линтинг (~30 сек)

make molecule-lint

Запускает yamllint . и ansible-lint на всём проекте. Используй перед каждым коммитом.

Тест одной роли

make molecule-k3s

Ожидаемый вывод (успешный):

INFO     Running default > create
TASK [Create instance(s)] ****
changed: [localhost] => (item=master01)
changed: [localhost] => (item=worker01)
changed: [localhost] => (item=rpi01)

INFO     Running default > converge
TASK [Test server config template rendering] ***
changed: [master01]

INFO     Running default > idempotency
PLAY RECAP
master01  : ok=12  changed=0  unreachable=0  failed=0
worker01  : ok=12  changed=0  unreachable=0  failed=0
rpi01     : ok=12  changed=0  unreachable=0  failed=0

INFO     Idempotency completed successfully.

INFO     Running default > verify
TASK [Assert cluster-init is set (только master01)] ***
ok: [master01] => {"msg": "All assertions passed"}

INFO     Running default > destroy
✓ k3s role: OK

Отладка упавших тестов

# Войти в runner-контейнер с Docker socket:
docker run --rm -it \
  -v $(pwd):/ansible \
  -v /var/run/docker.sock:/var/run/docker.sock \
  --entrypoint bash \
  k3s-ansible

# Внутри — перейти к нужной роли:
cd /ansible/roles/k3s   # или roles/prometheus-stack / addons/jenkins/role

# Запускать фазы вручную:
molecule converge          # создать контейнер и запустить задачи
molecule login             # войти в тестовый контейнер
molecule login --host master01   # конкретная нода
molecule verify            # только assertions
molecule converge -- -vvv  # подробный вывод
molecule destroy           # удалить тестовые контейнеры

# Отдельные фазы:
molecule lint
molecule syntax
molecule create
molecule prepare
molecule idempotency

Написание новых тестов

molecule.yml

driver:
  name: docker
platforms:
  - name: my-test-instance
    image: geerlingguy/docker-ubuntu2204-ansible:latest
    pre_build_image: true
    privileged: true            # нужно для sysctl, модулей ядра
    groups:
      - k3s_master
provisioner:
  name: ansible
verifier:
  name: ansible

converge.yml

- name: Converge
  hosts: all
  become: true
  vars:
    kube_vip_address: "192.168.1.100"   # все нужные переменные здесь
    k3s_version: "v1.29.3+k3s1"
  tasks:
    - name: Render template
      ansible.builtin.template:
        src: "{{ playbook_dir }}/../../templates/my-template.j2"
        dest: /tmp/result.yaml

verify.yml

- name: Verify
  hosts: all
  tasks:
    - name: Read result
      ansible.builtin.slurp:
        src: /tmp/result.yaml
      register: raw

    - name: Parse YAML
      ansible.builtin.set_fact:
        result: "{{ raw.content | b64decode | from_yaml }}"

    - name: Assert key exists
      ansible.builtin.assert:
        that:
          - result.myKey == 'expected-value'
          - result.enabled == true
        fail_msg: "Ожидалось 'expected-value', получено: {{ result.myKey }}"

Типичные ошибки

Ошибка Причина Решение
Unable to pull image Нет интернета docker pull geerlingguy/docker-ubuntu2204-ansible:latest
FAILED: assert ... is defined Переменная не задана Добавь в секцию vars: converge.yml
Idempotency: CHANGED Таск не идемпотентен Добавь changed_when: false или исправь задачу
yamllint: wrong indentation Ошибка отступа Исправь файл, make molecule-lint
ansible-lint: no-changed-when shell/command без changed_when Добавь changed_when: <условие>
sysctl: Operation not permitted Нет privileged Добавь privileged: true в molecule.yml