- 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 уже существовали)
229 lines
8.3 KiB
Markdown
229 lines
8.3 KiB
Markdown
# Тестирование через Molecule
|
||
|
||
Molecule — стандартный инструмент для тестирования Ansible ролей. Каждая роль запускается в Docker-контейнерах, проходит набор автоматических проверок и удаляется. Реальные серверы не нужны.
|
||
|
||
## Требования
|
||
|
||
Только **Docker** — Molecule, Python и зависимости уже внутри образа `k3s-ansible`.
|
||
|
||
```bash
|
||
make build # собрать образ (один раз)
|
||
make molecule-k3s # запустить тест
|
||
```
|
||
|
||
Как это работает: `make molecule-*` запускает контейнер `k3s-ansible` с примонтированным Docker socket. Внутри этого контейнера Molecule создаёт тестовые контейнеры — Docker внутри Docker без демона (только socket от хоста).
|
||
|
||
## Доступные тесты
|
||
|
||
```bash
|
||
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 сек)
|
||
|
||
```bash
|
||
make molecule-lint
|
||
```
|
||
|
||
Запускает `yamllint .` и `ansible-lint` на всём проекте. Используй перед каждым коммитом.
|
||
|
||
### Тест одной роли
|
||
|
||
```bash
|
||
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
|
||
```
|
||
|
||
## Отладка упавших тестов
|
||
|
||
```bash
|
||
# Войти в 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
|
||
|
||
```yaml
|
||
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
|
||
|
||
```yaml
|
||
- 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
|
||
|
||
```yaml
|
||
- 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 |
|