Files
KindClustersDashboard/Makefile
Sergey Antropoff 5b5844289e docs: публичный образ inecs/kind-cluster-dashboard:v1.0.0 в быстром старте и hub-compose
Синхронизация с дефолтами Makefile (DOCKERHUB_REPO, RELEASE_TAG).
Исправлен пробел в DOCKERHUB_REPO ?=.
2026-04-05 00:40:14 +03:00

192 lines
14 KiB
Makefile
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 — образ без кэша и пересоздание контейнера
# make docker restart / make podman restart — перезапуск сервиса kind-k8s-web
# Без префикса docker/podman цели up/down/restart/logs/ps/build/rebuild/check-docker/kubectl завершатся с подсказкой.
#
# Автор: Сергей Антропов — https://devops.org.ru
KIND_K8S_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
SETUP_ENV_SCRIPT := $(KIND_K8S_DIR)/scripts/setup_env_interactive.py
PYTHON ?= python3
ifneq (,$(filter podman,$(MAKECMDGOALS)))
COMPOSE := podman compose
# Сокет Podman на хосте (перекрывает CONTAINER_SOCKET из .env, если там путь Docker).
PODMAN_HOST_SOCK := $(shell $(PYTHON) "$(KIND_K8S_DIR)/scripts/detect_podman_socket.py")
# docker-compose из podman compose часто подставляет том из .env, игнорируя префикс VAR= в командной строке.
# Файл .env.podman.override (см. цель _podman_env_override) задаёт CONTAINER_SOCKET после .env.
PODMAN_COMPOSE_ENV_FILE := --env-file .env.podman.override
# user: в контейнере для доступа к смонтированному podman.sock:
# «podman compose» на macOS часто дергает docker-compose к API Podman — keep-id не срабатывает, uid с сокета даёт EACCES.
# По умолчанию 0:0 (как у типичного docker.sock); переопределение: KIND_K8S_PODMAN_CONTAINER_UIDGID=501:20
# или KIND_K8S_PODMAN_USE_SOCKET_OWNER=1 (владелец по stat, как detect_podman_socket.py --print-owner).
ifneq (,$(KIND_K8S_PODMAN_USE_SOCKET_OWNER))
_PODMAN_UIDGID := $(shell $(PYTHON) "$(KIND_K8S_DIR)/scripts/detect_podman_socket.py" --print-owner)
else
ifneq (,$(KIND_K8S_PODMAN_CONTAINER_UIDGID))
_PODMAN_UIDGID := $(KIND_K8S_PODMAN_CONTAINER_UIDGID)
else
_PODMAN_UIDGID := 0:0
endif
endif
_PODMAN_UID_FIRST := $(word 1,$(subst :, ,$(_PODMAN_UIDGID)))
_PODMAN_HOME := $(if $(filter 0,$(_PODMAN_UID_FIRST)),/root,/tmp)
ifneq (,$(findstring var/folders,$(PODMAN_HOST_SOCK)))
$(error PODMAN_HOST_SOCK содержит /var/folders/ — этот API-сокет нельзя смонтировать в compose. Обновите репозиторий (scripts/detect_podman_socket.py) и удалите такой путь из .env)
endif
# Внутри контейнера — путь podman, не docker.sock; DOCKER_HOST должен указывать на тот же путь (API совместим).
COMPOSE_PODMAN_ENV := KIND_K8S_CONTAINER_UIDGID=$(_PODMAN_UIDGID) KIND_K8S_CONTAINER_HOME=$(_PODMAN_HOME) CONTAINER_SOCKET=$(PODMAN_HOST_SOCK) CONTAINER_SOCKET_MOUNT_TARGET=/run/podman/podman.sock KIND_K8S_REMOTE_SOCKET_URI=unix:///run/podman/podman.sock
COMPOSE_FILE_ARGS := -f docker-compose.yml -f docker-compose.podman.yml
else ifneq (,$(filter docker,$(MAKECMDGOALS)))
COMPOSE := docker compose
# Сброс путей от Podman в .env: сокет в контейнере снова /var/run/docker.sock.
COMPOSE_DOCKER_OVERRIDES := CONTAINER_SOCKET_MOUNT_TARGET=/var/run/docker.sock KIND_K8S_REMOTE_SOCKET_URI=unix:///var/run/docker.sock
endif
COMPOSE_PODMAN_ENV ?=
COMPOSE_DOCKER_OVERRIDES ?=
COMPOSE_FILE_ARGS ?=
PODMAN_COMPOSE_ENV_FILE ?=
.PHONY: help docker podman _require_runtime _podman_env_override up down restart logs ps setup clusters-dir check-docker build rebuild kubectl probe-sockets release
# При «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
# Сборка и push в Docker Hub (make release): linux/amd64 (x86_64) и linux/arm64 (Apple Silicon и др.).
# linux/386 для kind в образе не поддерживается официальными бинарниками.
# Перед push make release вызывает docker login docker.io (сохранение в ~/.docker/config.json). Строка [auth] … token у BuildKit — нормальный обмен по протоколу реестра после входа.
# CI без интерактива: SKIP_RELEASE_DOCKER_LOGIN=1, если docker login уже выполнен или настроен credential helper.
RELEASE_PLATFORMS ?= linux/amd64,linux/arm64
RELEASE_TAG ?= v1.0.0
DOCKERHUB_REPO ?= inecs/kind-cluster-dashboard
KIND_VERSION ?= 0.24.0
HELM_VERSION ?= v3.16.3
KUBECTL_VERSION ?=
SKIP_RELEASE_DOCKER_LOGIN ?=
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 restart / make podman restart (перезапуск kind-k8s-web)"
@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 " make release — multi-arch buildx и push (по умолчанию DOCKERHUB_REPO=inecs/kind-cluster-dashboard, RELEASE_TAG=v1.0.0; см. README)"
@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 restart | 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
# Только для make podman …: перекрыть CONTAINER_SOCKET из .env (устаревший /var/folders/… ломает volume).
_podman_env_override:
@if [ -n "$(COMPOSE_PODMAN_ENV)" ]; then \
printf '%s\n' \
"CONTAINER_SOCKET=$(PODMAN_HOST_SOCK)" \
"KIND_K8S_CONTAINER_UIDGID=$(_PODMAN_UIDGID)" \
"KIND_K8S_CONTAINER_HOME=$(_PODMAN_HOME)" \
"CONTAINER_SOCKET_MOUNT_TARGET=/run/podman/podman.sock" \
"KIND_K8S_REMOTE_SOCKET_URI=unix:///run/podman/podman.sock" \
> "$(KIND_K8S_DIR)/.env.podman.override"; \
fi
up: _require_runtime _podman_env_override clusters-dir build ## (с docker/podman) Поднять веб-UI в фоне
cd "$(KIND_K8S_DIR)" && $(COMPOSE_PODMAN_ENV) $(COMPOSE_DOCKER_OVERRIDES) $(COMPOSE) $(COMPOSE_FILE_ARGS) $(PODMAN_COMPOSE_ENV_FILE) up -d kind-k8s-web
down: _require_runtime _podman_env_override ## (с docker/podman) Остановить compose в этом каталоге
cd "$(KIND_K8S_DIR)" && $(COMPOSE_PODMAN_ENV) $(COMPOSE_DOCKER_OVERRIDES) $(COMPOSE) $(COMPOSE_FILE_ARGS) $(PODMAN_COMPOSE_ENV_FILE) down
restart: _require_runtime _podman_env_override ## (с docker/podman) Перезапустить контейнер kind-k8s-web
cd "$(KIND_K8S_DIR)" && $(COMPOSE_PODMAN_ENV) $(COMPOSE_DOCKER_OVERRIDES) $(COMPOSE) $(COMPOSE_FILE_ARGS) $(PODMAN_COMPOSE_ENV_FILE) restart kind-k8s-web
logs: _require_runtime _podman_env_override ## (с docker/podman) Логи kind-k8s-web (follow -f)
cd "$(KIND_K8S_DIR)" && $(COMPOSE_PODMAN_ENV) $(COMPOSE_DOCKER_OVERRIDES) $(COMPOSE) $(COMPOSE_FILE_ARGS) $(PODMAN_COMPOSE_ENV_FILE) logs -f kind-k8s-web
ps: _require_runtime _podman_env_override ## (с docker/podman) Статус контейнеров compose-проекта
cd "$(KIND_K8S_DIR)" && $(COMPOSE_PODMAN_ENV) $(COMPOSE_DOCKER_OVERRIDES) $(COMPOSE) $(COMPOSE_FILE_ARGS) $(PODMAN_COMPOSE_ENV_FILE) ps
probe-sockets: ## Проверить сокеты Docker/Podman (доступ без permission denied)
@$(PYTHON) "$(KIND_K8S_DIR)/scripts/probe_container_sockets.py"
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 _podman_env_override ## (с 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_PODMAN_ENV) $(COMPOSE_DOCKER_OVERRIDES) $(COMPOSE) $(COMPOSE_FILE_ARGS) $(PODMAN_COMPOSE_ENV_FILE) version >/dev/null 2>&1 || { echo >&2 "Команда «$(COMPOSE) version» недоступна."; exit 1; }
@echo "$(COMPOSE): OK"
# kubectl в образе; путь к kubeconfig — как у веб-UI (подстановка server через host.docker.internal, см. kubeconfig_patch.py).
kubectl: _require_runtime _podman_env_override ## (с 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)" && KC=$$($(COMPOSE_PODMAN_ENV) $(COMPOSE_DOCKER_OVERRIDES) $(COMPOSE) $(COMPOSE_FILE_ARGS) $(PODMAN_COMPOSE_ENV_FILE) exec -T kind-k8s-web python3 scripts/effective_kubeconfig_path.py $(CLUSTER) | tr -d '\r') && \
$(COMPOSE_PODMAN_ENV) $(COMPOSE_DOCKER_OVERRIDES) $(COMPOSE) $(COMPOSE_FILE_ARGS) $(PODMAN_COMPOSE_ENV_FILE) exec kind-k8s-web kubectl --kubeconfig="$$KC" $(KUBECTL_ARGS)
build: _require_runtime _podman_env_override clusters-dir ## (с docker/podman) Собрать образ kind-k8s-tools:local
cd "$(KIND_K8S_DIR)" && $(COMPOSE_PODMAN_ENV) $(COMPOSE_DOCKER_OVERRIDES) $(COMPOSE) $(COMPOSE_FILE_ARGS) $(PODMAN_COMPOSE_ENV_FILE) build $(COMPOSE_BUILD_FLAGS)
rebuild: _require_runtime _podman_env_override clusters-dir ## (с docker/podman) Пересобрать образ без кэша и пересоздать контейнер kind-k8s-web
cd "$(KIND_K8S_DIR)" && $(COMPOSE_PODMAN_ENV) $(COMPOSE_DOCKER_OVERRIDES) $(COMPOSE) $(COMPOSE_FILE_ARGS) $(PODMAN_COMPOSE_ENV_FILE) build --no-cache $(COMPOSE_BUILD_FLAGS) && $(COMPOSE_PODMAN_ENV) $(COMPOSE_DOCKER_OVERRIDES) $(COMPOSE) $(COMPOSE_FILE_ARGS) $(PODMAN_COMPOSE_ENV_FILE) up -d --force-recreate kind-k8s-web
# Публикация образа в Docker Hub (buildx, --push). Сначала интерактивный docker login (или SKIP_RELEASE_DOCKER_LOGIN=1).
release: ## Multi-arch (amd64+arm64) сборка и push [DOCKERHUB_REPO=inecs/kind-cluster-dashboard] [RELEASE_TAG=v1.0.0] … [SKIP_RELEASE_DOCKER_LOGIN=1]
@if [ -z "$(strip $(DOCKERHUB_REPO))" ]; then \
echo >&2 "Задайте DOCKERHUB_REPO=<namespace>/<имя_репозитория> (в Makefile задано по умолчанию inecs/kind-cluster-dashboard)."; \
echo >&2 "Платформы: $(RELEASE_PLATFORMS) (amd64 — ПК x86_64, arm64 — Apple Silicon и серверы ARM)."; \
echo >&2 "Перед push make release выполнит: docker login docker.io (или задайте SKIP_RELEASE_DOCKER_LOGIN=1)."; \
exit 1; \
fi
@command -v docker >/dev/null 2>&1 || { echo >&2 "Нужен docker в PATH."; exit 1; }
@docker buildx version >/dev/null 2>&1 || { echo >&2 "Нужен Docker Buildx (docker buildx version)."; exit 1; }
@if [ "$(strip $(SKIP_RELEASE_DOCKER_LOGIN))" != "1" ]; then \
echo "Вход в Docker Hub: docker login docker.io (учётные данные в ~/.docker/config.json; дальше BuildKit получит token у реестра — это норма)."; \
docker login docker.io || { echo >&2 "docker login docker.io завершился с ошибкой."; exit 1; }; \
fi
@docker buildx inspect kind-k8s-release >/dev/null 2>&1 || docker buildx create --name kind-k8s-release --driver docker-container --use
@docker buildx use kind-k8s-release
cd "$(KIND_K8S_DIR)" && docker buildx build \
--platform "$(RELEASE_PLATFORMS)" \
--push \
-t "$(DOCKERHUB_REPO):$(RELEASE_TAG)" \
--build-arg "KIND_VERSION=$(KIND_VERSION)" \
--build-arg "HELM_VERSION=$(HELM_VERSION)" \
--build-arg "KUBECTL_VERSION=$(KUBECTL_VERSION)" \
-f Dockerfile \
.