Kubey: веб-дашборд для Kubernetes без kubectl

Все ваши Kubernetes-кластеры в одном месте. Без kubectl.

Kubey — веб-дашборд для Kubernetes, который открывает всей команде доступ к инфраструктуре, не требуя от каждого настраивать kubectl, управлять файлами kubeconfig или учить команды CLI.


Зачем нужен Kubey?

Проблема

Команда управляет несколькими Kubernetes-кластерами в разных окружениях: dev, staging, production, возможно — в нескольких регионах. Когда что-то идёт не так или деплой выглядит неожиданно, начинаются вопросы:

  • «Та же ли версия крутится в проде, что и на стейджинге?»

  • «Может кто-нибудь с доступом к кластеру проверить, живы ли поды?»

  • «Почему у этого деплоя разное количество реплик в EU и US?»

Все судорожно добывают доступ к kubectl, жонглируют файлами kubeconfig и постоянно переключаются между терминалами. Разработчики без доступа к кластеру просто ждут, пока кто-то другой проверит.

Решение

Kubey переносит ваши кластеры в браузер. Поделитесь одной ссылкой с командой — и каждый сможет:

  • Оценить состояние кластера с первого взгляда — ноды, поды, деплойменты, сервисы во всех кластерах сразу.

  • Сравнивать деплойменты между окружениями — мгновенно замечать расхождения в конфигурации между dev, staging и prod.

  • Просматривать логи подов — разбираться в проблемах без SSH-доступа и kubectl.

  • Не требовать локальной настройки — работает из любого браузера на любом устройстве.

Один инженер настраивает кластеры один раз. Вся команда получает видимость навсегда.


Ключевые возможности

Сравнение деплойментов между кластерами

Главная фишка. Выберите любой деплоймент и сравните его сразу во всех кластерах:

  • Смотрите, какие версии образов запущены в каких кластерах.

  • Замечайте разницу в количестве реплик между окружениями.

  • Выявляйте отсутствующие переменные окружения и изменения конфигурации.

  • Сравнивайте лимиты и запросы ресурсов.

«Почему в проде версия v2.3.1, а на стейджинге — v2.4.0?» — ответ займёт секунды, а не минуты.

Веб-доступ для всех

  • Разработчики — проверяют статус деплоя без учётных данных кластера.

  • QA-команды — убеждаются, какая версия задеплоена куда.

  • Дежурные инженеры (on-call) — быстрый обзор кластера с телефона в 2 ночи.

  • Менеджеры продукта — видят, что реально запущено в production.

Никакого kubectl. Никакого kubeconfig. Никаких VPN-манипуляций. Просто открываете ссылку.

Встроенная командная аутентификация

  • Вход через Google или GitHub.

  • Администратор управляет доступом к кластерам.

  • Ограничение регистрации по домену компании (@yourcompany.com).

  • Режим только по приглашениям для жёсткого контроля доступа.

Мониторинг кластера в реальном времени

  • Метрики CPU и памяти для нод и подов в режиме реального времени.

  • Статус подов и счётчики перезапусков.

  • Обзор сервисов и ингрессов (ingress).

  • Представление ресурсов, организованное по пространствам имён (namespace).

Self-hosted и безопасность

  • Работает в вашей инфраструктуре — данные никогда не покидают сеть.

  • Единый бинарный файл со встроенной базой данных — никаких внешних зависимостей.

  • Монтируйте существующий kubeconfig — подходит для любого кластера, к которому у вас уже есть доступ.

  • Достаточно лёгок для Raspberry Pi, достаточно мощен для корпоративного использования.


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

Docker (рекомендуется)

# Режим одного пользователя (без аутентификации)
docker run -d \
  --name kubey \
  -p 8080:8080 \
  -v ~/.kube/config:/home/kubey/.kube/config:ro \
  -v kubey-data:/data \
  jboocodes/kubey:latest

Откройте http://localhost:8080 в браузере.

Docker с командной аутентификацией

docker run -d \
  --name kubey \
  -p 8080:8080 \
  -v ~/.kube/config:/home/kubey/.kube/config:ro \
  -v kubey-data:/data \
  -e AUTH_MODE=shared \
  -e JWT_SECRET=your-secure-secret-key \
  -e GITHUB_CLIENT_ID=your-github-client-id \
  -e GITHUB_CLIENT_SECRET=your-github-secret \
  jboocodes/kubey:latest

Установка

Docker Compose

Создайте файл docker-compose.yml:

version: '3.8'

services:
  kubey:
    image: jboocodes/kubey:latest
    container_name: kubey
    ports:
      - "8080:8080"
    volumes:
      - ~/.kube/config:/home/kubey/.kube/config:ro
      - kubey-data:/data
    environment:
      - AUTH_MODE=single
      # Для командного режима раскомментируйте:
      # - AUTH_MODE=shared
      # - JWT_SECRET=your-secure-secret
      # - GITHUB_CLIENT_ID=xxx
      # - GITHUB_CLIENT_SECRET=xxx
    restart: unless-stopped

volumes:
  kubey-data:
docker-compose up -d

Kubernetes

Задеплойте Kubey в ваш кластер:

# kubey.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: kubey
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: kubey
  namespace: kubey
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubey-viewer
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: view
subjects:
  - kind: ServiceAccount
    name: kubey
    namespace: kubey
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: kubey-data
  namespace: kubey
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kubey
  namespace: kubey
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kubey
  template:
    metadata:
      labels:
        app: kubey
    spec:
      serviceAccountName: kubey
      containers:
        - name: kubey
          image: jboocodes/kubey:latest
          ports:
            - containerPort: 8080
          env:
            - name: AUTH_MODE
              value: "single"
          volumeMounts:
            - name: data
              mountPath: /data
          resources:
            requests:
              memory: "128Mi"
              cpu: "100m"
            limits:
              memory: "512Mi"
              cpu: "500m"
          livenessProbe:
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 30
          readinessProbe:
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 10
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: kubey-data
---
apiVersion: v1
kind: Service
metadata:
  name: kubey
  namespace: kubey
spec:
  selector:
    app: kubey
  ports:
    - port: 80
      targetPort: 8080
  type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubey
  namespace: kubey
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  ingressClassName: nginx
  rules:
    - host: kubey.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: kubey
                port:
                  number: 80
  tls:
    - hosts:
        - kubey.example.com
      secretName: kubey-tls
kubectl apply -f kubey.yaml

Helm

# Установка с настройками по умолчанию (режим одного пользователя)
helm install kubey oci://ghcr.io/justinbehncodes/charts/kubey --version 0.1.0 -n kubey

# Установка с командной аутентификацией
helm install kubey kubey/kubey \
  --set auth.mode=shared \
  --set auth.jwtSecret=your-secure-secret \
  --set auth.github.clientId=xxx \
  --set auth.github.clientSecret=xxx

Конфигурация

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

Переменная По умолчанию Описание

AUTH_MODE

single

Режим аутентификации: single, shared или hybrid

JWT_SECRET

(генерируется)

Секретный ключ для JWT-токенов (обязателен в production)

PORT

8080

Порт сервера

HOST

localhost

Хост сервера

DATABASE_PATH

./data/kubey.db

Путь к базе данных SQLite

KUBECONFIG

~/.kube/config

Путь к файлу kubeconfig

STATIC_PATH

(встроен)

Путь к статическим файлам (для Docker)

Настройка OAuth

Переменная Описание

GITHUB_CLIENT_ID

Client ID GitHub OAuth App

GITHUB_CLIENT_SECRET

Client Secret GitHub OAuth App

GOOGLE_CLIENT_ID

Client ID Google OAuth

GOOGLE_CLIENT_SECRET

Client Secret Google OAuth

OAUTH_CALLBACK_URL

Базовый URL для OAuth-коллбэков (например, https://kubey.example.com)

ADMIN_EMAIL

Заранее назначить администратора по email

Настройки администратора

Переменная Описание

ALLOWED_DOMAINS

Список разрешённых email-доменов для регистрации через запятую

INVITE_ONLY

При значении true пользователей может создавать только администратор


Режимы аутентификации

Kubey поддерживает три режима аутентификации.

Режим одного пользователя (AUTH_MODE=single)

  • Аутентификация не требуется.

  • Идеально для личного использования или локальной разработки.

  • Все кластеры доступны любому, кто имеет доступ к дашборду.

Общий режим (AUTH_MODE=shared)

  • Требуется OAuth-аутентификация (GitHub/Google).

  • Администратор централизованно управляет всеми кластерами.

  • Первый вошедший становится администратором (или задайте ADMIN_EMAIL).

  • Кластеры, смонтированные при запуске, доступны всем пользователям.

  • Администратор может ограничить регистрацию по домену или включить режим только по приглашениям.

Гибридный режим (AUTH_MODE=hybrid)

  • Требуется OAuth-аутентификация.

  • Общие кластеры под управлением администратора плюс личные кластеры пользователей.

  • Пользователи могут добавлять собственные kubeconfig.

  • Сочетает централизованное управление с личной гибкостью.


Настройка OAuth

GitHub OAuth

  1. Перейдите в GitHub Settings > Developer settings > OAuth Apps > New OAuth App.

  2. Укажите Homepage URL: https://kubey.example.com.

  3. Укажите Authorization callback URL: https://kubey.example.com/auth/callback/github.

  4. Скопируйте Client ID и Client Secret.

Google OAuth

  1. Перейдите в Google Cloud Console > APIs & Services > Credentials.

  2. Создайте OAuth 2.0 Client ID (тип — Web application).

  3. Добавьте Authorized redirect URI: https://kubey.example.com/auth/callback/google.

  4. Скопируйте Client ID и Client Secret.


Справочник по API

Публичные эндпоинты

Метод Эндпоинт Описание

GET

/health

Проверка работоспособности

GET

/api/mode

Получить режим аутентификации

Защищённые эндпоинты

Метод Эндпоинт Описание

GET

/api/me

Получить текущего пользователя

GET

/api/clusters

Список всех кластеров

GET

/api/clusters/:id

Детали кластера

GET

/api/clusters/:id/nodes

Ноды кластера

GET

/api/clusters/:id/pods

Все поды

GET

/api/clusters/:id/services

Все сервисы

GET

/api/clusters/:id/deployments

Все деплойменты

GET

/api/clusters/:id/namespaces

Пространства имён с ресурсами

GET

/api/clusters/:id/pods/:ns/:name/logs

Логи пода

GET

/api/compare/deployments

Сравнение деплойментов между кластерами

Административные эндпоинты

Метод Эндпоинт Описание

GET

/api/admin/users

Список всех пользователей

POST

/api/admin/users

Создать пользователя

PATCH

/api/admin/users/:id

Обновить пользователя

DELETE

/api/admin/users/:id

Удалить пользователя

GET

/api/admin/clusters

Список всех кластеров

PATCH

/api/admin/clusters/:id

Обновить кластер

DELETE

/api/admin/clusters/:id

Удалить кластер

GET

/api/admin/settings

Получить настройки

PATCH

/api/admin/settings

Обновить настройки


Разработка

Требования

  • Go 1.24+

  • Node.js 20+

  • npm или bun

Клонирование и настройка

git clone https://github.com/justinbehncodes/kubey.git
cd kubey

Разработка фронтенда

cd web
npm install
npm run dev      # http://localhost:5173

Разработка бэкенда

cd api
go mod download
go run cmd/api/main.go

Запуск обоих компонентов одновременно

make dev

Сборка Docker-образа

docker build -t kubey:local .

Запуск тестов

# Тесты бэкенда
cd api && go test ./...

# С gotestsum для более читаемого вывода
make test

Архитектура

kubey/
├── api/                    # Go-бэкенд
│   ├── cmd/api/            # Точка входа
│   ├── internal/
│   │   ├── auth/           # Аутентификация (JWT, OAuth)
│   │   ├── database/       # SQLite + миграции
│   │   ├── handlers/       # HTTP-обработчики
│   │   ├── middlewares/    # Логирование, CORS, восстановление после паник
│   │   └── services/       # Kubernetes-клиент
│   └── go.mod
├── web/                    # React-фронтенд
│   ├── src/
│   │   ├── components/     # UI-компоненты
│   │   ├── pages/          # Компоненты страниц
│   │   ├── services/       # API-клиенты
│   │   └── contexts/       # React-контексты
│   └── package.json
├── Dockerfile              # Многоэтапная сборка
└── docker-compose.yml

Технологический стек

Бэкенд:

  • Go с веб-фреймворком Gin

  • SQLite на чистом Go (без CGO)

  • client-go для Kubernetes API

  • JWT-аутентификация

Фронтенд:

  • React 19 с TypeScript

  • Vite для сборки

  • Tailwind CSS v4

  • Компоненты shadcn/ui


Устранение неполадок

Нет подключения к кластерам

  1. Убедитесь, что kubeconfig смонтирован корректно.

  2. Проверьте доступность кластера: kubectl cluster-info.

  3. Проверьте RBAC-права сервисного аккаунта.

OAuth не работает

  1. Убедитесь, что callback URL-адреса совпадают точно.

  2. Проверьте правильность Client ID и Client Secret.

  3. Убедитесь, что OAUTH_CALLBACK_URL задан корректно.

Ошибки базы данных

  1. Проверьте, что том /data доступен для записи.

  2. Убедитесь, что достаточно места на диске.

  3. Попробуйте удалить базу данных для сброса: rm /data/kubey.db.


Участие в разработке

Мы рады любым вкладам! Прочитайте руководство по участию перед отправкой PR.

  1. Сделайте форк репозитория.

  2. Создайте ветку для фичи: git checkout -b feature/amazing-feature.

  3. Зафиксируйте изменения: git commit -m 'Add amazing feature'.

  4. Отправьте ветку: git push origin feature/amazing-feature.

  5. Откройте Pull Request.


Лицензия

Проект распространяется под лицензией Apache License 2.0 — подробности в файле LICENSE.


Поддержка

  • GitHub Issues — сообщения об ошибках и запросы функций.

  • Discussions — вопросы и общение с сообществом.

© 2026 meganuke