From 5b5844289ef221a40c5b07c12eb1be7ae26b6874 Mon Sep 17 00:00:00 2001 From: Sergey Antropoff Date: Sun, 5 Apr 2026 00:40:14 +0300 Subject: [PATCH] =?UTF-8?q?docs:=20=D0=BF=D1=83=D0=B1=D0=BB=D0=B8=D1=87?= =?UTF-8?q?=D0=BD=D1=8B=D0=B9=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B7=20inecs/kin?= =?UTF-8?q?d-cluster-dashboard:v1.0.0=20=D0=B2=20=D0=B1=D1=8B=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=BE=D0=BC=20=D1=81=D1=82=D0=B0=D1=80=D1=82=D0=B5=20?= =?UTF-8?q?=D0=B8=20hub-compose?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Синхронизация с дефолтами Makefile (DOCKERHUB_REPO, RELEASE_TAG). Исправлен пробел в DOCKERHUB_REPO ?=. --- Makefile | 41 +++++++- README.md | 133 ++++++++++++++++++++++++++ compose/docker-compose.hub.docker.yml | 52 ++++++++++ compose/docker-compose.hub.podman.yml | 56 +++++++++++ 4 files changed, 281 insertions(+), 1 deletion(-) create mode 100644 compose/docker-compose.hub.docker.yml create mode 100644 compose/docker-compose.hub.podman.yml diff --git a/Makefile b/Makefile index 5c28d13..44eee48 100644 --- a/Makefile +++ b/Makefile @@ -53,13 +53,25 @@ 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 +.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}" @@ -71,6 +83,7 @@ help: ## Справка по целям @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}' @@ -150,3 +163,29 @@ build: _require_runtime _podman_env_override clusters-dir ## (с docker/podman) 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=/<имя_репозитория> (в 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 \ + . diff --git a/README.md b/README.md index 1712787..8cad362 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,139 @@ ## Быстрый старт +### Готовый образ с Docker Hub (без сборки, без файла `.env`) + +**Опубликованный образ:** **`inecs/kind-cluster-dashboard:v1.0.0`** (соответствует значениям по умолчанию в `Makefile`: `DOCKERHUB_REPO=inecs/kind-cluster-dashboard`, `RELEASE_TAG=v1.0.0`). Все теги: [hub.docker.com/r/inecs/kind-cluster-dashboard/tags](https://hub.docker.com/r/inecs/kind-cluster-dashboard/tags). + +Сборка и отправка в Docker Hub (для сопровождения образа): **linux/amd64** (ПК **x86_64**) и **linux/arm64** (**Apple Silicon** и прочий ARM). Образ **linux/386** (32-bit x86) для **kind** официальными бинарниками не поставляется, поэтому в релиз не входит. + +```bash +docker login +# По умолчанию пушит inecs/kind-cluster-dashboard:v1.0.0 (см. Makefile): +make release +# Или явно: make release DOCKERHUB_REPO=inecs/kind-cluster-dashboard RELEASE_TAG=v1.0.0 +# Необязательно: KIND_VERSION=0.24.0 HELM_VERSION=v3.16.3 KUBECTL_VERSION=v1.32.0 +``` + +Другой образ/тег задайте в shell: **`KIND_K8S_HUB_IMAGE=логин/репозиторий:тег`** при вызове compose (в YAML ниже то же через подстановку). + +```bash +mkdir -p clusters +# Docker (файл в репозитории: compose/docker-compose.hub.docker.yml; образ по умолчанию — v1.0.0): +docker compose -f compose/docker-compose.hub.docker.yml up -d + +# Другой тег: KIND_K8S_HUB_IMAGE=inecs/kind-cluster-dashboard:latest docker compose -f compose/docker-compose.hub.docker.yml up -d + +# Podman — путь к API-сокету только через переменные окружения (не через .env): +export CONTAINER_SOCKET="${XDG_RUNTIME_DIR}/podman/podman.sock" +podman compose -f compose/docker-compose.hub.podman.yml up -d +``` + +Браузер: **http://127.0.0.1:8080** (в примерах ниже публикация **8080:6000**; при необходимости поменяйте в YAML). + +Ниже — **полные** примеры `docker-compose`: все переменные **`environment`** заданы явно теми же значениями, что использует приложение по умолчанию (см. `docker-compose.yml`, `app/core/*.py`, `app/kubeconfig_patch.py`). **`.env` не нужен**. Актуальные копии — в [`compose/docker-compose.hub.docker.yml`](compose/docker-compose.hub.docker.yml) и [`compose/docker-compose.hub.podman.yml`](compose/docker-compose.hub.podman.yml). + +**Docker** — вставьте в `docker-compose.yml` (или сохраните как отдельный файл): + +```yaml +services: + kind-k8s-web: + image: ${KIND_K8S_HUB_IMAGE:-inecs/kind-cluster-dashboard:v1.0.0} + container_name: kind-clusters-dashboard + user: "0:0" + volumes: + - ${KIND_K8S_CLUSTERS_DIR:-./clusters}:/work/clusters + - ${CONTAINER_SOCKET:-/var/run/docker.sock}:/var/run/docker.sock + ports: + - "8080:6000" + extra_hosts: + - "host.docker.internal:host-gateway" + environment: + HOME: /root + DOCKER_HOST: unix:///var/run/docker.sock + KIND_K8S_IN_CONTAINER: "1" + KIND_K8S_WORKDIR: /work + KIND_K8S_PATCH_KUBECONFIG: "1" + KIND_K8S_KUBECONFIG_CLIENT_HOST: localhost + KIND_K8S_KUBECONFIG_TLS_SERVER_NAME: localhost + KIND_K8S_APISERVER_GATEWAY_HOST: host.docker.internal + CONTAINER_CLI: docker + KIND_K8S_SKIP_VERSION_LIST: "0" + KIND_K8S_VERSION_LIST_DISPLAY: "50" + KIND_K8S_HUB_TAGS_MAX_PAGES: "120" + KIND_K8S_DEBUG: "0" + KIND_K8S_JOB_LOG_MAX_LINES: "2500" + KIND_K8S_STREAM_PTY: "1" + KIND_K8S_DOCKER_PULL_PLAIN: "1" + KIND_K8S_JOB_API_LOG_MAX_LINES: "5000" + KIND_K8S_JOBS_JSON: /work/clusters/kind_k8s_jobs.json + KIND_K8S_README_PATH: /opt/kind-k8s/README.md + KIND_K8S_WAIT_NODES: "1" + KIND_K8S_WAIT_NODES_TIMEOUT_SEC: "300" + KIND_K8S_HELM_TIMEOUT_SEC: "900" + KIND_K8S_HELM_VERSIONS_CACHE_SEC: "600" + KIND_K8S_HELM_VERSIONS_MAX: "80" + KIND_K8S_CLUSTER_JOURNAL_MAX_ENTRIES: "500" + KIND_K8S_CLUSTER_JOURNAL_MAX_LOG_LINES: "2000" + KIND_K8S_HELM_ADDON_LOG_MAX_ENTRIES: "500" + KIND_K8S_APP_TITLE: "Kind Clusters Dashboard" + KIND_K8S_UVICORN_RELOAD: "0" + working_dir: /opt/kind-k8s/app + command: ["/opt/kind-k8s/run_uvicorn.sh"] +``` + +**Podman** — перед запуском: **`export CONTAINER_SOCKET="$XDG_RUNTIME_DIR/podman/podman.sock"`** (или фактический путь к `podman.sock`). При **EACCES** на сокет подберите **`user`** / **UID:GID** как в основном [`docker-compose.yml`](docker-compose.yml) и [`Makefile`](Makefile) для `make podman up`. + +```yaml +services: + kind-k8s-web: + image: ${KIND_K8S_HUB_IMAGE:-inecs/kind-cluster-dashboard:v1.0.0} + container_name: kind-clusters-dashboard + userns_mode: keep-id + user: "0:0" + volumes: + - ${KIND_K8S_CLUSTERS_DIR:-./clusters}:/work/clusters + - ${CONTAINER_SOCKET}:/run/podman/podman.sock + ports: + - "8080:6000" + extra_hosts: + - "host.docker.internal:host-gateway" + environment: + HOME: /tmp + DOCKER_HOST: unix:///run/podman/podman.sock + KIND_K8S_IN_CONTAINER: "1" + KIND_K8S_WORKDIR: /work + KIND_K8S_PATCH_KUBECONFIG: "1" + KIND_K8S_KUBECONFIG_CLIENT_HOST: localhost + KIND_K8S_KUBECONFIG_TLS_SERVER_NAME: localhost + KIND_K8S_APISERVER_GATEWAY_HOST: host.docker.internal + CONTAINER_CLI: podman + KIND_K8S_SKIP_VERSION_LIST: "0" + KIND_K8S_VERSION_LIST_DISPLAY: "50" + KIND_K8S_HUB_TAGS_MAX_PAGES: "120" + KIND_K8S_DEBUG: "0" + KIND_K8S_JOB_LOG_MAX_LINES: "2500" + KIND_K8S_STREAM_PTY: "1" + KIND_K8S_DOCKER_PULL_PLAIN: "1" + KIND_K8S_JOB_API_LOG_MAX_LINES: "5000" + KIND_K8S_JOBS_JSON: /work/clusters/kind_k8s_jobs.json + KIND_K8S_README_PATH: /opt/kind-k8s/README.md + KIND_K8S_WAIT_NODES: "1" + KIND_K8S_WAIT_NODES_TIMEOUT_SEC: "300" + KIND_K8S_HELM_TIMEOUT_SEC: "900" + KIND_K8S_HELM_VERSIONS_CACHE_SEC: "600" + KIND_K8S_HELM_VERSIONS_MAX: "80" + KIND_K8S_CLUSTER_JOURNAL_MAX_ENTRIES: "500" + KIND_K8S_CLUSTER_JOURNAL_MAX_LOG_LINES: "2000" + KIND_K8S_HELM_ADDON_LOG_MAX_ENTRIES: "500" + KIND_K8S_APP_TITLE: "Kind Clusters Dashboard" + KIND_K8S_UVICORN_RELOAD: "0" + working_dir: /opt/kind-k8s/app + command: ["/opt/kind-k8s/run_uvicorn.sh"] +``` + +### Запуск из репозитория (локальная сборка образа) + ```bash # Из корня клонированного репозитория Kind Clusters Dashboard (рядом с Makefile): make setup # опционально: интерактивно создать .env (Enter — дефолты из скрипта) diff --git a/compose/docker-compose.hub.docker.yml b/compose/docker-compose.hub.docker.yml new file mode 100644 index 0000000..d8cc589 --- /dev/null +++ b/compose/docker-compose.hub.docker.yml @@ -0,0 +1,52 @@ +# Запуск готового образа с Docker Hub без .env и без сборки (только Docker). +# Образ по умолчанию: inecs/kind-cluster-dashboard:v1.0.0 (см. Makefile RELEASE_TAG / DOCKERHUB_REPO). +# Создайте каталог: mkdir -p clusters +# Запуск: docker compose -f compose/docker-compose.hub.docker.yml up -d +# +# Автор: Сергей Антропов — https://devops.org.ru + +services: + kind-k8s-web: + image: ${KIND_K8S_HUB_IMAGE:-inecs/kind-cluster-dashboard:v1.0.0} + container_name: kind-clusters-dashboard + user: "0:0" + volumes: + - ${KIND_K8S_CLUSTERS_DIR:-./clusters}:/work/clusters + - ${CONTAINER_SOCKET:-/var/run/docker.sock}:/var/run/docker.sock + ports: + - "8080:6000" + extra_hosts: + - "host.docker.internal:host-gateway" + environment: + # Значения как у дефолтов в docker-compose.yml и в коде приложения (без пустых строк). + HOME: /root + DOCKER_HOST: unix:///var/run/docker.sock + KIND_K8S_IN_CONTAINER: "1" + KIND_K8S_WORKDIR: /work + KIND_K8S_PATCH_KUBECONFIG: "1" + KIND_K8S_KUBECONFIG_CLIENT_HOST: localhost + KIND_K8S_KUBECONFIG_TLS_SERVER_NAME: localhost + KIND_K8S_APISERVER_GATEWAY_HOST: host.docker.internal + CONTAINER_CLI: docker + KIND_K8S_SKIP_VERSION_LIST: "0" + KIND_K8S_VERSION_LIST_DISPLAY: "50" + KIND_K8S_HUB_TAGS_MAX_PAGES: "120" + KIND_K8S_DEBUG: "0" + KIND_K8S_JOB_LOG_MAX_LINES: "2500" + KIND_K8S_STREAM_PTY: "1" + KIND_K8S_DOCKER_PULL_PLAIN: "1" + KIND_K8S_JOB_API_LOG_MAX_LINES: "5000" + KIND_K8S_JOBS_JSON: /work/clusters/kind_k8s_jobs.json + KIND_K8S_README_PATH: /opt/kind-k8s/README.md + KIND_K8S_WAIT_NODES: "1" + KIND_K8S_WAIT_NODES_TIMEOUT_SEC: "300" + KIND_K8S_HELM_TIMEOUT_SEC: "900" + KIND_K8S_HELM_VERSIONS_CACHE_SEC: "600" + KIND_K8S_HELM_VERSIONS_MAX: "80" + KIND_K8S_CLUSTER_JOURNAL_MAX_ENTRIES: "500" + KIND_K8S_CLUSTER_JOURNAL_MAX_LOG_LINES: "2000" + KIND_K8S_HELM_ADDON_LOG_MAX_ENTRIES: "500" + KIND_K8S_APP_TITLE: "Kind Clusters Dashboard" + KIND_K8S_UVICORN_RELOAD: "0" + working_dir: /opt/kind-k8s/app + command: ["/opt/kind-k8s/run_uvicorn.sh"] diff --git a/compose/docker-compose.hub.podman.yml b/compose/docker-compose.hub.podman.yml new file mode 100644 index 0000000..1945c7d --- /dev/null +++ b/compose/docker-compose.hub.podman.yml @@ -0,0 +1,56 @@ +# Запуск готового образа с Docker Hub под Podman (без .env и без сборки). +# Перед запуском задайте путь к сокету в shell (без файла .env): +# export CONTAINER_SOCKET="$XDG_RUNTIME_DIR/podman/podman.sock" +# Образ по умолчанию: inecs/kind-cluster-dashboard:v1.0.0 (переопределение: KIND_K8S_HUB_IMAGE). +# +# mkdir -p clusters +# podman compose -f compose/docker-compose.hub.podman.yml up -d +# +# Автор: Сергей Антропов — https://devops.org.ru + +services: + kind-k8s-web: + image: ${KIND_K8S_HUB_IMAGE:-inecs/kind-cluster-dashboard:v1.0.0} + container_name: kind-clusters-dashboard + userns_mode: keep-id + user: "0:0" + volumes: + - ${KIND_K8S_CLUSTERS_DIR:-./clusters}:/work/clusters + - ${CONTAINER_SOCKET}:/run/podman/podman.sock + ports: + - "8080:6000" + extra_hosts: + - "host.docker.internal:host-gateway" + environment: + # Значения как у дефолтов в docker-compose.yml и в коде приложения (без пустых строк). + HOME: /tmp + DOCKER_HOST: unix:///run/podman/podman.sock + KIND_K8S_IN_CONTAINER: "1" + KIND_K8S_WORKDIR: /work + KIND_K8S_PATCH_KUBECONFIG: "1" + KIND_K8S_KUBECONFIG_CLIENT_HOST: localhost + KIND_K8S_KUBECONFIG_TLS_SERVER_NAME: localhost + KIND_K8S_APISERVER_GATEWAY_HOST: host.docker.internal + CONTAINER_CLI: podman + KIND_K8S_SKIP_VERSION_LIST: "0" + KIND_K8S_VERSION_LIST_DISPLAY: "50" + KIND_K8S_HUB_TAGS_MAX_PAGES: "120" + KIND_K8S_DEBUG: "0" + KIND_K8S_JOB_LOG_MAX_LINES: "2500" + KIND_K8S_STREAM_PTY: "1" + KIND_K8S_DOCKER_PULL_PLAIN: "1" + KIND_K8S_JOB_API_LOG_MAX_LINES: "5000" + KIND_K8S_JOBS_JSON: /work/clusters/kind_k8s_jobs.json + KIND_K8S_README_PATH: /opt/kind-k8s/README.md + KIND_K8S_WAIT_NODES: "1" + KIND_K8S_WAIT_NODES_TIMEOUT_SEC: "300" + KIND_K8S_HELM_TIMEOUT_SEC: "900" + KIND_K8S_HELM_VERSIONS_CACHE_SEC: "600" + KIND_K8S_HELM_VERSIONS_MAX: "80" + KIND_K8S_CLUSTER_JOURNAL_MAX_ENTRIES: "500" + KIND_K8S_CLUSTER_JOURNAL_MAX_LOG_LINES: "2000" + KIND_K8S_HELM_ADDON_LOG_MAX_ENTRIES: "500" + KIND_K8S_APP_TITLE: "Kind Clusters Dashboard" + KIND_K8S_UVICORN_RELOAD: "0" + working_dir: /opt/kind-k8s/app + command: ["/opt/kind-k8s/run_uvicorn.sh"]