# Kind Clusters Dashboard — веб-интерфейс (FastAPI) для kind. # Создание кластеров — в браузере: http://127.0.0.1:8080 (порт: KIND_K8S_WEB_PORT; 6000 на хосте — ERR_UNSAFE_PORT в Chrome). # # Все операции с Compose только с явным выбором среды: # make docker up | make docker down | make docker logs | … # make podman up | make podman down | … # make docker rebuild / make podman rebuild — образ без кэша и пересоздание контейнера # Без префикса docker/podman цели up/down/logs/ps/build/rebuild/check-docker/kubectl завершатся с подсказкой. # # Автор: Сергей Антропов — https://devops.org.ru ifneq (,$(filter podman,$(MAKECMDGOALS))) COMPOSE := podman compose else ifneq (,$(filter docker,$(MAKECMDGOALS))) COMPOSE := docker compose endif .PHONY: help docker podman _require_runtime up down logs ps setup clusters-dir check-docker build rebuild kubectl KIND_K8S_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) SETUP_ENV_SCRIPT := $(KIND_K8S_DIR)/scripts/setup_env_interactive.py PYTHON ?= python3 # При «exec format error» у kind: make docker build COMPOSE_BUILD_FLAGS=--platform linux/arm64 COMPOSE_BUILD_FLAGS ?= # Для цели kubectl: имя кластера и аргументы kubectl после --kubeconfig (по умолчанию: get nodes). CLUSTER ?= KUBECTL_ARGS ?= get nodes help: ## Справка по целям @echo "Веб-UI kind — только с выбором Docker или Podman в одной команде с целью:" @echo " make docker up или make podman up → http://127.0.0.1:\$${KIND_K8S_WEB_PORT:-8080}" @echo " make docker down / make podman down" @echo " make docker logs / make podman logs (follow -f)" @echo " make docker ps / make podman ps (статус сервисов)" @echo " make docker build / make podman build" @echo " make docker rebuild / make podman rebuild (build --no-cache + up --force-recreate)" @echo " make docker check-docker / make podman check-docker" @echo " make docker kubectl CLUSTER=<имя> — kubectl в контейнере (см. KUBECTL_ARGS, по умолчанию get nodes)" @echo "Без установки Compose: make setup, make clusters-dir (python3 для setup)." @grep -E '^[a-zA-Z0-9_-]+:.*?##' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?##"} {printf " \033[36m%-28s\033[0m %s\n", $$1, $$2}' docker: ## Маркер среды: задайте вторую цель (например: make docker up) @: podman: ## Маркер среды: задайте вторую цель (например: make podman up) @: # Общая проверка: цели up/down/logs/ps/build/rebuild/check-docker/kubectl — только make docker … / make podman … _require_runtime: @if [ -z "$(COMPOSE)" ]; then \ echo >&2 "Укажите среду в той же команде, что и цель:"; \ echo >&2 " make docker up | make podman up"; \ echo >&2 " make docker down | make docker logs | make docker ps | make docker build | make docker rebuild | make docker check-docker | make docker kubectl CLUSTER=…"; \ echo >&2 " (или то же с префиксом podman)"; \ exit 1; \ fi up: _require_runtime clusters-dir build ## (с docker/podman) Поднять веб-UI в фоне cd "$(KIND_K8S_DIR)" && $(COMPOSE) up -d kind-k8s-web down: _require_runtime ## (с docker/podman) Остановить compose в этом каталоге cd "$(KIND_K8S_DIR)" && $(COMPOSE) down logs: _require_runtime ## (с docker/podman) Логи kind-k8s-web (follow -f) cd "$(KIND_K8S_DIR)" && $(COMPOSE) logs -f kind-k8s-web ps: _require_runtime ## (с docker/podman) Статус контейнеров compose-проекта cd "$(KIND_K8S_DIR)" && $(COMPOSE) ps setup: ## Интерактивно создать .env (scripts/setup_env_interactive.py; нужен python3 на хосте) @$(PYTHON) "$(SETUP_ENV_SCRIPT)" clusters-dir: ## Каталог clusters/ для тома (если ещё нет) @mkdir -p "$(KIND_K8S_DIR)/clusters" check-docker: _require_runtime ## (с docker/podman) Проверить CLI и compose @case "$(COMPOSE)" in \ docker*) command -v docker >/dev/null 2>&1 || { echo >&2 "docker не найден в PATH."; exit 1; } ;; \ podman*) command -v podman >/dev/null 2>&1 || { echo >&2 "podman не найден в PATH."; exit 1; } ;; \ esac @$(COMPOSE) version >/dev/null 2>&1 || { echo >&2 "Команда «$(COMPOSE) version» недоступна."; exit 1; } @echo "$(COMPOSE): OK" # kubectl и kind в образе; kubeconfig в томе /work/clusters//kubeconfig — kubectl на хосте не нужен. kubectl: _require_runtime ## (с docker/podman) kubectl в контейнере: CLUSTER=имя [KUBECTL_ARGS="get pods -A"] @if [ -z "$(CLUSTER)" ]; then \ echo >&2 "Задайте CLUSTER=<имя_кластера> (каталог в ./clusters/)."; \ echo >&2 "Пример: make docker kubectl CLUSTER=dev"; \ echo >&2 "Свои подкоманды: make docker kubectl CLUSTER=dev KUBECTL_ARGS=\"get pods -A\""; \ exit 1; \ fi cd "$(KIND_K8S_DIR)" && $(COMPOSE) exec kind-k8s-web kubectl --kubeconfig=/work/clusters/$(CLUSTER)/kubeconfig $(KUBECTL_ARGS) build: _require_runtime clusters-dir ## (с docker/podman) Собрать образ kind-k8s-tools:local cd "$(KIND_K8S_DIR)" && $(COMPOSE) build $(COMPOSE_BUILD_FLAGS) rebuild: _require_runtime clusters-dir ## (с docker/podman) Пересобрать образ без кэша и пересоздать контейнер kind-k8s-web cd "$(KIND_K8S_DIR)" && $(COMPOSE) build --no-cache $(COMPOSE_BUILD_FLAGS) && $(COMPOSE) up -d --force-recreate kind-k8s-web