`kube_vip_interface` определяется автоматически через `ansible_default_ipv4.interface` — работает для Ubuntu, Debian, Raspberry Pi OS без дополнительных настроек.
### Шаг 6 — Vault с секретами
```bash
@@ -286,16 +306,18 @@ make build
### Шаг 8 — Прогнать тесты (рекомендуется)
Перед деплоем убедись что роли корректны:
Перед деплоем убедись что роли корректны. Molecule запускается **внутри Docker** — устанавливать ничего не нужно.
```bash
# Установить зависимости для Molecule (один раз)
pip install -r requirements-python.txt
# Убедись что образ собран (если ещё не сделал на шаге 7):
# make build
# Запустить все тесты (~10-15 минут)
# Запустить все тесты (~15-20 минут)
make molecule-all
```
Что поднимается: 3 контейнера (master01/worker01 на Ubuntu 22.04 + rpi01 на Debian 12), тест конфигурации K3S HA, шаблонов Prometheus и Istio.
Если всё зелёное — можно деплоить. Если есть ошибки — смотри раздел [Тестирование через Molecule](#тестирование-через-molecule).
### Шаг 9 — Проверить SSH и dry-run
@@ -316,13 +338,15 @@ make install
```
Плейбук выполняет всё последовательно (`serial: 1`):
1. master01: prereqs → K3S server (cluster-init) → ждёт готовности API → kube-vip
1. master01: prereqs → K3S server (cluster-init) → ждёт готовности API
# cilium_k8s_service_host автоматически = kube_vip_address
```
При смене CNI необходима переустановка кластера — CNI нельзя поменять "горячей" заменой.
### kube-vip
```yaml
kube_vip_address:"192.168.1.100"# Свободный IP — обязательно задать!
kube_vip_interface:"eth0"# Интерфейс master01 (ip a)
kube_vip_interface:""# пусто = автоопределение
# Ansible определит eth0/enp3s0/end0 автоматически
# Переопредели только если нужно: "eth0"
kube_vip_mode:"arp"# arp (L2) для домашних сетей | bgp (L3)
```
Автоопределение интерфейса работает через `ansible_default_ipv4.interface` — корректно определяет интерфейс на Ubuntu, Debian, Raspberry Pi OS. Если у разных нод разные имена интерфейсов — задай `kube_vip_interface` принудительно.
@@ -682,6 +739,7 @@ make lint # Проверить синтаксис плейбуков
```bash
make install # Полный базовый стек
make install-k3s # Только K3S HA кластер
make install-cni # CNI плагин (make install-cni K3S_CNI=calico|cilium)
make install-kubevip # Только kube-vip
make install-nfs # NFS + CSI
make install-ingress # ingress-nginx
@@ -689,14 +747,14 @@ make install-istio # Istio + Kiali (нужен istio_enabled: true в var
make install-monitoring # Prometheus + Grafana (нужен prometheus_stack_enabled: true)
```
### Тестирование (Molecule)
### Тестирование (Molecule — всё в Docker, pip не нужен)
```bash
make molecule-k3s # Тест роли k3s (~5-8 мин)
make molecule-k3s # Тест роли k3s — 3 контейнера (Ubuntu+Debian), ~8-12 мин
make molecule-prometheus # Тест роли prometheus-stack (~2-3 мин)
make molecule-istio # Тест роли istio (~2-3 мин)
make molecule-all # Все тесты последовательно (~15 мин)
make molecule-lint # Только линтинг YAML+ansible-lint (без Docker, ~30 сек)
make molecule-all # Все тесты последовательно (~15-20 мин)
make molecule-lint # Линтинг YAML+ansible-lint в контейнере (~30 сек)
```
### Обновление и диагностика
@@ -737,22 +795,22 @@ EXTRA_VARS="k3s_version=v1.30.0+k3s1" make install-k3s # Доп. пер
## Тестирование через Molecule
Molecule — стандартный инструмент для тестирования Ansible ролей. Каждая роль запускается в Docker-контейнере, проходит набор автоматических проверок и удаляется. Реальные серверы при этом **не нужны**.
Molecule — стандартный инструмент для тестирования Ansible ролей. Каждая роль запускается в Docker-контейнерах, проходит набор автоматических проверок и удаляется. Реальные серверы при этом **не нужны**.
### Установка
### Требования
Только **Docker** — Molecule, Python и зависимости уже внутри образа `k3s-ansible`. Устанавливать ничего дополнительно не нужно.
```bash
# Установить зависимости (один раз)
pip install -r requirements-python.txt
# Убедись что образ собран:
make build
# Проверить
molecule --version
# molecule 6.x.x ...
docker --version
# Docker version 24.x.x ...
# Запустить тесты (всё в Docker):
make molecule-k3s
```
Как это работает: `make molecule-*` запускает контейнер `k3s-ansible`с примонтированным Docker socket (`/var/run/docker.sock`). Внутри этого контейнера Molecule создаёт тестовые контейнеры для каждой роли — **Docker внутри Docker без демона** (только socket от хоста).
### Жизненный цикл теста
Команда `molecule test` выполняет следующие фазы по порядку:
Запускает `yamllint .` и `ansible-lint` на всём проекте. Выполняется за ~30 секунд, Docker не нужен. Используй перед каждым коммитом.
Запускает `yamllint .` и `ansible-lint` на всём проекте внутри Docker-контейнера. Используй перед каждым коммитом.
```
Запуск линтинга...
yamllint .
ansible-lint
✓ Линтинг прошёл
```
@@ -865,70 +926,58 @@ ansible-lint
make molecule-k3s
```
Вывод (успешный):
Вывод (успешный, сокращён):
```
INFO default scenario test matrix: dependency, lint, cleanup, destroy, syntax, create, prepare, converge, idempotency, verify, cleanup, destroy
INFO Performing prerun with role_name_check=1...
INFO Running default > create
INFO Sanity checks: 'docker'
TASK [Create instance(s)] ****
changed: [localhost] => (item=master01)
changed: [localhost] => (item=worker01)
changed: [localhost] => (item=rpi01)
INFO Running default > prepare
PLAY [Prepare k3s test environment] ****
TASK [Wait for systemd to start] ***
ok: [k3s-node]
TASK [Install Python3] ***
changed: [k3s-node]
ok: [master01]
ok: [worker01]
ok: [rpi01]
INFO Running default > converge
PLAY [Converge — k3s role unit tests] ****
TASK [Mock k3s binary] ***
changed: [k3s-node]
TASK [Test prereqs — install packages] ***
changed: [k3s-node] => (item=curl)
changed: [k3s-node] => (item=iptables)
changed: [master01]
changed: [worker01]
changed: [rpi01]
TASK [Test server config template rendering] ***
changed: [k3s-node]
changed: [master01]
changed: [worker01]
changed: [rpi01]
INFO Running default > idempotency
PLAY [Converge — k3s role unit tests] ****
...
PLAY RECAP
k3s-node : ok=12 changed=0 unreachable=0 failed=0
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
PLAY [Verify — k3s role] ****
TASK [Assert cluster-init is set (только master01)] ***
ok: [master01] => {"msg": "All assertions passed"}
skipping: [worker01]
skipping: [rpi01]
TASK [Assert config directory] ***
ok: [k3s-node] => {"changed": false, "msg": "All assertions passed"}
TASK [Assert config file exists] ***
ok: [k3s-node] => {"changed": false, "msg": "All assertions passed"}
TASK [Assert cluster-init is set] ***
ok: [k3s-node] => {"changed": false, "msg": "All assertions passed"}
TASK [Assert traefik is disabled] ***
ok: [k3s-node] => {"changed": false, "msg": "All assertions passed"}
TASK [Assert server URL is set (worker01 и rpi01)] ***
skipping: [master01]
ok: [worker01] => {"msg": "All assertions passed"}
ok: [rpi01] => {"msg": "All assertions passed"}
TASK [Assert ip_forward is 1] ***
ok: [k3s-node] => {"changed": false, "msg": "All assertions passed"}
TASK [Summary] ***
ok: [k3s-node] => {
"msg": "Все проверки прошли успешно для ноды k3s-node"
}
ok: [master01]
ok: [worker01]
ok: [rpi01]
INFO Running default > destroy
INFO Pruning extra files from scenario ephemeral directory
✓ k3s role: OK
```
@@ -939,7 +988,7 @@ make molecule-all
```
```
Тестирую роль k3s...
Тестирую роль k3s (3 ноды: master01, worker01, rpi01)...
...
✓ k3s role: OK
@@ -958,29 +1007,37 @@ make molecule-all
### Отладка упавших тестов
Если тест упал — контейнер удаляется автоматически. Чтобы оставить контейнер живым для ручной отладки, используй отдельные фазы:
Если тест упал — контейнеры удаляются автоматически. Чтобы оставить контейнеры живыми для ручной отладки, войди в интерактивный shell внутри Molecule-контейнера и запускай отдельные фазы:
```bash
# Перейти в директорию роли
cd roles/prometheus-stack
# Открыть shell внутри ansible-runner контейнера с Docker socket
docker run --rm -it \
-v $(pwd):/ansible \
-v /var/run/docker.sock:/var/run/docker.sock \
--entrypoint bash \
k3s-ansible
# Только создать контейнер и запустить задачи (без удаления)
molecule converge
# Внутри контейнера — перейти к роли и запускать фазы вручную:
**Автоопределение интерфейса:** Ansible определяет сетевой интерфейс каждой master-ноды через `ansible_default_ipv4.interface`. На Ubuntu это может быть `enp3s0`, на Raspberry Pi — `end0`, на VM — `eth0`. Принудительное задание: `kube_vip_interface: "eth0"` в `group_vars/all/main.yml`.
### NFS + CSI
NFS сервер разворачивается на master01. Каждый PVC создаёт отдельную папку внутри `/srv/nfs/k8s`:
NFS сервер разворачивается на master01. StorageClass автоматически именуется `nfs-<hostname NFS сервера>` — например, `nfs-master01`. Это позволяет сразу понять на какой сервер указывает StorageClass при `kubectl get sc`. Если NFS вынесен на отдельный хост с hostname `storage01`, StorageClass будет `nfs-storage01`.
Каждый PVC создаёт отдельную папку внутри `/srv/nfs/k8s`:
```
/srv/nfs/k8s/
@@ -1162,13 +1228,16 @@ k3s_node_taints: []
## Docker образ
Образ собирается один раз через `make build` и содержит всё необходимое для управления кластером:
Образ собирается один раз через `make build` и содержит всё необходимое — как для управления кластером, так и для Molecule-тестирования:
```
FROM python:3.12-slim-bookworm
├── openssh-client, curl, jq, git
├── docker-ce-cli (Docker CLI для Molecule)
├── ansible-core 2.16, ansible 9.x
├── kubernetes, openshift Python пакеты
├── molecule >= 6.0 + molecule-plugins[docker]
├── yamllint, ansible-lint
├── Helm 3.14.4
├── kubectl v1.29.3
└── Ansible Collections:
@@ -1177,13 +1246,19 @@ FROM python:3.12-slim-bookworm
└── kubernetes.core >= 3.0
```
При запуске монтируются:
При обычном запуске (`make install`, `make ping`):
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.