Files
KindClustersDashboard/README.md
Sergey Antropoff c1e867a01f Веб-UI: логи kind create, старт/стоп кластеров, документация README
- Потоковые логи в job_store и UI; kind create через Popen с построчным выводом
- POST /clusters/{name}/start|stop; create по сохранённому kind-config.yaml
- Страница /documentation: GET /api/v1/docs/readme, marked+DOMPurify из static/vendor
- Иконки действий, плавающие подсказки, модалка подтверждения вместо confirm
- Makefile: make docker|podman rebuild; compose: монтирование README.md
- Dockerfile: COPY README.md; readme_doc: несколько путей к README

Автор: Сергей Антропов — https://devops.org.ru
2026-04-04 06:21:00 +03:00

17 KiB
Raw Blame History

kind-k8s-develop — локальные кластеры Kubernetes (kind)

Образ kind-k8s-tools:local и Makefile поднимают веб-интерфейс (FastAPI) на порту 8080 на хосте по умолчанию (или KIND_K8S_WEB_PORT в .env; внутри контейнера приложение слушает 6000). Порт 6000 на хосте не используем по умолчанию: Chrome и другие браузеры на Chromium отдают ERR_UNSAFE_PORT. Через браузер создаёте и удаляете кластеры, смотрите статистику и вывод kubectl. kubeconfig сохраняется в clusters/<имя>/. На хосте достаточно Docker (или Podman) и make; kind и kubectl — внутри контейнера.

Автор: Сергей Антропов — devops.org.ru

Документация

Ресурс Описание
app/docs/api_routes.md Описание REST API /api/v1/* с примерами JSON (для фронтенда и интеграций)
app/docs/README.md Указатель по каталогу app/docs/
/docs (Swagger), /redoc, /api/v1/health На панели открываются в отдельном окне браузера (window.open); прямой URL — тот же порт, что и UI (по умолчанию 8080)

Шаблона env.example в репозитории нет: переменные для .env задаются интерактивно скриптом scripts/setup_env_interactive.py (make setup).

Зачем это нужно

  • Быстро получить Kubernetes без облака (интеграционные тесты, манифесты, обучение).
  • Версия кластера и число worker-нод задаются в веб-UI (или через REST API / скрипты в контейнере).
  • Количество кластеров не ограничено кодом (ограничения — ресурсы хоста и Docker).
  • Артефакты на хосте: clusters/<имя>/ — удобно указать путь к kubeconfig в приложении или в kubectl.

Веб-интерфейс

  • Верхняя единая карточка: заголовок, краткое описание и строка состояния среды (kind / kubectl / Docker или Podman API).
  • Статистика: число кластеров в kind, локальных каталогов, сумма workers из meta.json, счётчики фоновых заданий.
  • Создание кластера: форма с подсказкой тегов kindest/node (GET /api/v1/versions), фоновое задание и опрос статуса (JSON в сворачиваемом блоке).
  • Таблица кластеров: признаки регистрации в kind и наличия kubeconfig, скачивание kubeconfig, просмотр узлов/подов в модальном окне, удаление.
  • Последние задания создания (данные в памяти процесса; после перезапуска контейнера история сбрасывается).
  • Автообновление таблиц и плашки среды каждые ~3,5 с (fetch к API без перезагрузки страницы).
  • При создании кластера — прогресс-бар и текст текущего этапа; кнопка «Отменить создание» (между этапами; шаг kind create до конца не прерывается).
  • Уведомления (toast) при успехе/ошибке; в подвале — копирайт и ссылка на devops.org.ru.

Шапка: навигация в виде пилюль (стили .nav-pill); пункты Swagger, ReDoc и Health открывают страницу в отдельном именованном окне (~1240×840), чтобы не уходить с панели (см. скрипт в base.html).

Структура фронтенда: app/templates/base.html (шапка и меню), app/templates/dashboard.html, app/static/style.css, app/static/js/dashboard.js (префикс API: data-api-base на <body>, по умолчанию /api/v1).

Требования на хосте

Компонент Назначение
Docker + Compose v2 (или Podman + compose) Сборка образа и запуск веб-сервиса
make make docker up / make podman up и вспомогательные цели
python3 Только для make setup (создание .env)
kubectl (опционально) Проверка API с хоста: kubectl --kubeconfig=clusters/<имя>/kubeconfig get nodes

В образ не обязательно ставить на хост: kind, Python приложения — они внутри контейнера.

Смонтированы сокет Docker/Podman и каталог ./clusters → в контейнере /work/clusters. Каталог ./app монтируется в /opt/kind-k8s/app для разработки без пересборки образа. Файл ./README.md монтируется в /opt/kind-k8s/README.md (страница «Документация» и GET /api/v1/docs/readme без пересборки образа).

После создания кластера kubeconfig по умолчанию патчится на https://127.0.0.1:<порт> для доступа с хоста (KIND_K8S_PATCH_KUBECONFIG, см. app/kubeconfig_patch.py).

Быстрый старт

cd kind-k8s-develop
make setup           # опционально: интерактивно создать .env (Enter — дефолты из скрипта)
make docker check-docker    # или: make podman check-docker
make docker up       # или: make podman up
# Браузер: http://127.0.0.1:8080  (порт: KIND_K8S_WEB_PORT в .env; не 6000 на хосте — Chrome ERR_UNSAFE_PORT)

Из родительского каталога: make -C kind-k8s-develop docker up.

Логи, статус и остановка: make docker logs / make podman logs (follow), make docker ps / make podman ps, make docker down / make podman down.

Разработка UI и API без пересборки образа

В docker-compose.yml смонтированы ./app/opt/kind-k8s/app и ./README.md/opt/kind-k8s/README.md (только чтение).

По умолчанию (KIND_K8S_UVICORN_RELOAD=1) uvicorn запускается с --reload (см. scripts/run_uvicorn.sh) и перезапускает процесс при изменении *.py, *.html, *.css, *.js в app/. Пересобирать образ нужно после изменений Dockerfile, requirements.txt или scripts/run_uvicorn.sh.

Отключить reload: в .env задать KIND_K8S_UVICORN_RELOAD=0.

Дополнительно: CLI в одноразовом контейнере

Если нужен сценарий без UI (CI, скрипты):

docker compose run --rm --entrypoint python3 kind-k8s-web \
  /opt/kind-k8s/app/create_cluster.py --non-interactive --name dev --kubernetes-version 1.29.4 --workers 2

docker compose run --rm --entrypoint python3 kind-k8s-web \
  /opt/kind-k8s/app/delete_cluster.py --non-interactive --name dev --yes

Рабочий каталог сервиса в образе — /opt/kind-k8s/app; том clusters/ и сокет те же, что у docker compose up.

После успешного kind create по умолчанию выполняется kubectl wait готовности нод (KIND_K8S_WAIT_NODES, KIND_K8S_WAIT_NODES_TIMEOUT_SEC в .env).

Команды Makefile

Цель Описание
make help Краткая справка
make docker up / make podman up Поднять веб-UI (kind-k8s-web)
make docker down / make podman down Остановить compose в каталоге репозитория
make docker logs / make podman logs Логи kind-k8s-web (stream, -f)
make docker ps / make podman ps Статус контейнеров текущего compose-проекта
make docker compose-build / make podman compose-build Собрать образ kind-k8s-tools:local
make docker rebuild / make podman rebuild Пересборка образа без кэша (build --no-cache) и пересоздание контейнера (up -d --force-recreate)
make docker check-docker / make podman check-docker Проверить выбранный CLI и compose version
make setup Интерактивно создать .env (список переменных в scripts/setup_env_interactive.py)
make clusters-dir Создать каталог clusters/
make docker … / make podman … Префикс обязателен для целей up, down, logs, ps, compose-build, rebuild, check-docker

Цели up, down, logs, ps, compose-build, rebuild и check-docker без docker/podman в той же команде завершатся с подсказкой.

Переменные окружения

Файл .env в корне репозитория подхватывает Compose. Создать его: make setup или вручную по списку в scripts/setup_env_interactive.py. Файл .env в git не коммитится (см. .gitignore).

Переменные DOCKER_HOST, KIND_K8S_IN_CONTAINER, KIND_K8S_WORKDIR в контейнере задаются литералами в docker-compose.yml, а не из .env.

Переменная Где используется Назначение
KIND_VERSION build-arg Версия бинарника kind при сборке образа
KUBECTL_VERSION build-arg Версия kubectl в образе; пусто в compose → в Dockerfile подставляется stable.txt при сборке; make setup предлагает закреплённый тег
KIND_K8S_WEB_PORT ports Порт на хосте для веб-UI (по умолчанию 8080; в контейнере публикация идёт на процесс на 6000)
KIND_K8S_WEB_HOST локальный uvicorn / Settings Хост привязки при запуске вне compose (в контейнере задаётся entrypoint)
KIND_K8S_UVICORN_RELOAD контейнер 1 (по умолчанию) — hot-reload при правках в ./app; 0 — без reload
KIND_K8S_APP_TITLE контейнер / Settings Заголовок OpenAPI и HTML; пустое значение из compose не ломает приложение (env_ignore_empty, fallback)
KIND_K8S_WAIT_NODES контейнер 0 — не ждать Ready нод после create
KIND_K8S_WAIT_NODES_TIMEOUT_SEC контейнер Таймаут kubectl wait (секунды)
CONTAINER_SOCKET volume Сокет Docker/Podman на хосте
KIND_K8S_PATCH_KUBECONFIG контейнер Патч server в kubeconfig для хоста; по умолчанию включено (1 в compose и в make setup)
CONTAINER_CLI контейнер CLI для docker port / podman port (docker или podman)
KIND_K8S_SKIP_VERSION_LIST контейнер Не ходить в Docker Hub за тегами
KIND_K8S_VERSION_LIST_DISPLAY контейнер Сколько тегов отдавать в API/UI
KIND_K8S_HUB_TAGS_MAX_PAGES контейнер Лимит страниц API Hub
KIND_K8S_DEBUG контейнер 1/true/yes/да — уровень DEBUG в логах
KIND_K8S_JOB_LOG_MAX_LINES приложение Размер буфера строк журнала фонового задания (kind create) для поля progress_log в API/UI; по умолчанию 500 (задаётся в коде, при необходимости передайте в compose)
KIND_K8S_README_PATH контейнер / приложение Абсолютный путь к README.md для страницы /documentation; если пусто — используется README.md рядом с каталогом app/ (в образе: /opt/kind-k8s/README.md)
KIND_K8S_WORKDIR локальный запуск Корень данных на машине разработчика без compose
COMPOSE_BUILD_FLAGS Makefile Например make docker compose-build COMPOSE_BUILD_FLAGS=--platform linux/arm64 (то же для make docker rebuild)

Podman (пример rootless)

export CONTAINER_SOCKET="$XDG_RUNTIME_DIR/podman/podman.sock"
make podman up

Структура репозитория (основное)

Путь Назначение
Makefile Запуск веб-UI; префикс docker или podman обязателен; цели up, rebuild, compose-build и др.
scripts/setup_env_interactive.py Интерактивное создание .env (все ключи и дефолты внутри скрипта)
scripts/run_uvicorn.sh Точка входа контейнера: uvicorn с опциональным --reload
Dockerfile Образ: kind, kubectl, docker-cli, FastAPI
requirements.txt pip-зависимости веб-приложения
docker-compose.yml Сервис kind-k8s-web, тома ./clusters, ./app, ./README.md, сокет
app/main.py FastAPI: дашборд /, /documentation, редирект /ui, монтирование /static
app/api/v1/ REST API: router.py, endpoints/ (health, versions, docs_readme, clusters)
app/core/ Жизненный цикл кластеров, задания, настройки, блокировки (kind_guard), пути
app/models/schemas.py Pydantic-схемы запросов/ответов API
app/templates/ Jinja2: base.html, dashboard.html, documentation.html
app/static/ style.css, js/dashboard.js, js/documentation.js, js/vendor/ (marked, DOMPurify для README в UI)
app/docs/ api_routes.md, README.md
app/create_cluster.py, delete_cluster.py, cluster_status.py CLI и переиспользование из API / compose run

В UI и API список версий kindest/node по умолчанию тянется с Docker Hub (нужна сеть). В изолированной среде: KIND_K8S_SKIP_VERSION_LIST=1 — версию вводят вручную.

Где лежат данные на хосте

  • clusters/<имя>/kind-config.yaml
  • clusters/<имя>/kubeconfig
  • clusters/<имя>/meta.json

Содержимое clusters/*/ не коммитится; в репозитории есть clusters/.gitkeep.

Git и артефакты

В .gitignore: .env, каталоги в clusters/ (кроме .gitkeep), __pycache__/ и *.pyc, .DS_Store.

Ограничения

  • Образ kindest/node:v… должен быть доступен для pull.
  • На Windows без WSL удобнее WSL2 + Docker Desktop.
  • Для проверки с хоста нужен отдельный kubectl (в образе kubectl только внутри контейнера).
  • История заданий создания в UI/API хранится в памяти (до 200 записей); после перезапуска контейнера очищается.
  • При exec format error у kind пересоберите образ: make docker rebuild COMPOSE_BUILD_FLAGS=--platform linux/arm64 (или make podman …, или compose-build без --no-cache, или linux/amd64).