- Дашборд (Jinja2 + static), управление кластерами kind, задания и kubeconfig. - API: health, stats, clusters CRUD, versions, jobs; документация app/docs/api_routes.md. - Docker Compose: том app, uvicorn reload, KIND_K8S_PATCH_KUBECONFIG по умолчанию 1. - setup_env_interactive.py: список переменных в скрипте, удалён env.example. - Makefile: явный префикс docker/podman; прочие правки CLI и ядра кластеров.
6.6 KiB
Описание REST API веб-интерфейса kind-k8s-develop
Базовый префикс: /api/v1
Автор: Сергей Антропов — devops.org.ru
Интерактивная документация OpenAPI: после запуска make docker up откройте http://127.0.0.1:6000/docs.
GET /api/v1/health
Проверка: kind/kubectl в PATH и ответ движка контейнеров (docker info / podman info по CONTAINER_CLI).
status: ok — всё готово к созданию кластеров; degraded — чего-то не хватает (см. поля ниже).
Пример ответа 200 (JSON):
{
"status": "ok",
"kind_in_path": true,
"kubectl_in_path": true,
"container_cli": "docker",
"container_engine_ok": true,
"container_engine_detail": null
}
Если сокет Docker недоступен:
{
"status": "degraded",
"kind_in_path": true,
"kubectl_in_path": true,
"container_cli": "docker",
"container_engine_ok": false,
"container_engine_detail": "Cannot connect to the Docker daemon..."
}
GET /api/v1/versions
Список стабильных тегов kindest/node с Docker Hub (для выпадающего списка в UI).
При KIND_K8S_SKIP_VERSION_LIST=1 список пустой.
Пример ответа 200:
{
"tags": ["v1.32.0", "v1.31.4"],
"skipped": false
}
Пример при пропуске загрузки:
{
"tags": [],
"skipped": true,
"reason": "KIND_K8S_SKIP_VERSION_LIST"
}
GET /api/v1/stats
Сводная статистика для дашборда.
Пример ответа 200:
{
"kind_clusters_count": 2,
"local_cluster_dirs_count": 2,
"total_workers_from_meta": 4,
"jobs_total": 5,
"jobs_recent_failed": 1
}
Поле total_workers_from_meta может быть null, если ни в одном meta.json нет worker_nodes.
GET /api/v1/clusters
Список имён: объединение kind get clusters и подкаталогов clusters/*.
Пример ответа 200 (массив):
[
{
"name": "dev",
"registered_in_kind": true,
"has_local_kubeconfig": true,
"meta": {
"cluster_name": "dev",
"kubernetes_version_tag": "v1.29.4",
"node_image": "kindest/node:v1.29.4",
"worker_nodes": 2,
"kubeconfig_patched_for_host": true
}
}
]
GET /api/v1/jobs
Список последних фоновых заданий (создание кластера), от новых к старым. Данные только в памяти процесса.
Query: limit (1–200, по умолчанию 30).
Пример ответа 200 (массив JobView):
[
{
"job_id": "abc123",
"kind": "create_cluster",
"status": "success",
"cluster_name": "dev",
"created_at_utc": "2026-04-04T12:00:00+00:00",
"message": "Кластер создан",
"result": { "cluster_name": "dev", "kubernetes_version_tag": "v1.29.4" }
}
]
GET /api/v1/clusters/{name}/kubeconfig
Скачать файл kubeconfig (ответ — тело файла, Content-Disposition с именем kubeconfig-{name}.yaml).
Ошибка 404: файла нет в clusters/{name}/.
GET /api/v1/clusters/{name}/workloads
kubectl get nodes -o wide и kubectl get pods -A по сохранённому kubeconfig.
Пример ответа 200:
{
"cluster_name": "dev",
"nodes_rc": 0,
"nodes_output": "NAME STATUS ROLES ...",
"pods_rc": 0,
"pods_output": "NAMESPACE NAME READY STATUS ...",
"error": null
}
Если kubeconfig нет: "error": "Нет сохранённого kubeconfig...", остальные поля подов/узлов — null.
GET /api/v1/clusters/{name}
Детали и попытка kubectl get nodes -o wide с сохранённого clusters/{name}/kubeconfig (если файл есть).
Пример ответа 200:
{
"name": "dev",
"registered_in_kind": true,
"has_local_kubeconfig": true,
"kubeconfig_path": "/work/clusters/dev/kubeconfig",
"meta": { "worker_nodes": 2 },
"kubectl_get_nodes_rc": 0,
"kubectl_get_nodes": "NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME\n..."
}
POST /api/v1/clusters
Создание кластера в фоне (ответ 202).
Тело запроса (JSON):
{
"name": "dev",
"kubernetes_version": "1.29.4",
"workers": 2
}
Пример ответа 202:
{
"job_id": "a1b2c3d4e5f6...",
"status": "queued",
"message": "Создание кластера выполняется в фоне; опросите GET /api/v1/jobs/{job_id}"
}
Ошибка 409 (кластер уже есть в kind):
{
"detail": "Кластер с таким именем уже есть в kind"
}
GET /api/v1/jobs/{job_id}
Статус фонового задания создания.
В процессе (пример 200):
{
"job_id": "a1b2...",
"kind": "create_cluster",
"status": "running",
"cluster_name": "dev",
"created_at_utc": "2026-04-04T12:00:00+00:00",
"message": null,
"result": null
}
Успех (пример 200):
{
"job_id": "a1b2...",
"kind": "create_cluster",
"status": "success",
"cluster_name": "dev",
"created_at_utc": "2026-04-04T12:00:00+00:00",
"message": "Кластер создан",
"result": {
"cluster_name": "dev",
"kubernetes_version_tag": "v1.29.4",
"node_image": "kindest/node:v1.29.4",
"workers": 2,
"kubeconfig_path": "/work/clusters/dev/kubeconfig",
"kubeconfig_patched_for_host": true,
"nodes_ready": true,
"nodes_ready_message": "..."
}
}
Ошибка 404:
{
"detail": "Задание не найдено"
}
DELETE /api/v1/clusters/{name}
kind delete cluster и удаление каталога clusters/{name}/.
Пример ответа 200:
{
"name": "dev",
"kind_delete_ok": true,
"summary": "kind delete: OK; удалена папка /work/clusters/dev"
}
GET /
HTML-дашборд (не JSON): форма создания, таблица кластеров, ссылки на Swagger.