docs: initial project documentation
- architecture overview and stack - project structure and development order - API design (endpoints, models, runtimes) - infrastructure overview (k8s cluster, S3, registry) - decisions log with rationale - progress tracker v1/v2
This commit is contained in:
@@ -0,0 +1,95 @@
|
|||||||
|
# API Design
|
||||||
|
|
||||||
|
## Базовый URL
|
||||||
|
|
||||||
|
```
|
||||||
|
https://sless.api.ngcloud.ru/v1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Аутентификация
|
||||||
|
|
||||||
|
```
|
||||||
|
Authorization: Bearer <cloud-token>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Ресурсы
|
||||||
|
|
||||||
|
### Functions
|
||||||
|
|
||||||
|
| Метод | Путь | Описание |
|
||||||
|
|-------|------|----------|
|
||||||
|
| GET | /functions | Список функций |
|
||||||
|
| POST | /functions | Создать функцию |
|
||||||
|
| GET | /functions/{id} | Получить функцию |
|
||||||
|
| PUT | /functions/{id} | Обновить функцию |
|
||||||
|
| DELETE | /functions/{id} | Удалить функцию |
|
||||||
|
|
||||||
|
### Versions (код функции)
|
||||||
|
|
||||||
|
| Метод | Путь | Описание |
|
||||||
|
|-------|------|----------|
|
||||||
|
| GET | /functions/{id}/versions | Список версий |
|
||||||
|
| POST | /functions/{id}/versions | Загрузить новый код (multipart zip) |
|
||||||
|
| GET | /functions/{id}/versions/{ver} | Получить версию |
|
||||||
|
| POST | /functions/{id}/versions/{ver}/activate | Активировать версию |
|
||||||
|
|
||||||
|
### Triggers
|
||||||
|
|
||||||
|
| Метод | Путь | Описание |
|
||||||
|
|-------|------|----------|
|
||||||
|
| GET | /functions/{id}/triggers | Список триггеров |
|
||||||
|
| POST | /functions/{id}/triggers | Создать триггер (HTTP/Cron) |
|
||||||
|
| DELETE | /functions/{id}/triggers/{tid} | Удалить триггер |
|
||||||
|
|
||||||
|
### Invocations (вызов и логи)
|
||||||
|
|
||||||
|
| Метод | Путь | Описание |
|
||||||
|
|-------|------|----------|
|
||||||
|
| POST | /functions/{id}/invoke | Синхронный вызов |
|
||||||
|
| GET | /functions/{id}/invocations | История вызовов |
|
||||||
|
| GET | /functions/{id}/invocations/{iid} | Детали вызова + логи |
|
||||||
|
|
||||||
|
## Поддерживаемые runtime (v1)
|
||||||
|
|
||||||
|
- `go1.21`
|
||||||
|
- `python3.11`
|
||||||
|
- `nodejs20`
|
||||||
|
|
||||||
|
## Модель Function
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "fn-uuid",
|
||||||
|
"name": "my-function",
|
||||||
|
"description": "...",
|
||||||
|
"runtime": "python3.11",
|
||||||
|
"entrypoint": "handler.handle",
|
||||||
|
"memory_mb": 128,
|
||||||
|
"timeout_sec": 30,
|
||||||
|
"env_vars": {"KEY": "value"},
|
||||||
|
"active_version": "1",
|
||||||
|
"status": "active",
|
||||||
|
"created_at": "...",
|
||||||
|
"updated_at": "..."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Модель Trigger
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "tr-uuid",
|
||||||
|
"type": "http",
|
||||||
|
"url": "https://sless.api.ngcloud.ru/invoke/fn-uuid",
|
||||||
|
"created_at": "..."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "tr-uuid",
|
||||||
|
"type": "cron",
|
||||||
|
"schedule": "0 * * * *",
|
||||||
|
"created_at": "..."
|
||||||
|
}
|
||||||
|
```
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
# Архитектура системы
|
||||||
|
|
||||||
|
## Общее описание
|
||||||
|
|
||||||
|
Managed Serverless Functions Service для облачного провайдера nubes.ru.
|
||||||
|
Пользователь загружает код, сервис его собирает и запускает по HTTP-триггеру или расписанию.
|
||||||
|
|
||||||
|
## Стек
|
||||||
|
|
||||||
|
| Компонент | Технология | Где запущен |
|
||||||
|
|-----------|-----------|-------------|
|
||||||
|
| API сервер | Go | Kubernetes, namespace `sless` |
|
||||||
|
| PostgreSQL | PostgreSQL | Kubernetes, namespace `sless` |
|
||||||
|
| Redis | Redis | Kubernetes, namespace `sless` |
|
||||||
|
| RabbitMQ | RabbitMQ | Kubernetes, namespace `sless` (позже) |
|
||||||
|
| S3 | Ceph (облачный) | `ceph.tst.nubes.ru` |
|
||||||
|
| Container Registry | Внутренний registry кластера | namespace `registry` |
|
||||||
|
| Функции пользователей | k8s Jobs/Deployments | namespace `sless-fn-{id}` |
|
||||||
|
|
||||||
|
## Схема
|
||||||
|
|
||||||
|
```
|
||||||
|
Пользователь
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
REST API (Go) ←── Terraform provider
|
||||||
|
│
|
||||||
|
├── PostgreSQL — метаданные функций, версии, логи вызовов
|
||||||
|
├── S3 (Ceph) — хранение кода (zip архивы)
|
||||||
|
├── Redis — кеш, rate limiting
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Builder — получает zip из S3, собирает Docker образ, пушит в registry
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Runner (k8s) — деплоит функцию как Job/Deployment в k8s
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
RabbitMQ — async вызовы, cron triggers (v2)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Аутентификация
|
||||||
|
|
||||||
|
Используется токен облака (Bearer token), который пользователь получает в UI облака.
|
||||||
|
Terraform provider передаёт его в заголовке `Authorization: Bearer <token>`.
|
||||||
|
Keycloak не используется.
|
||||||
|
|
||||||
|
## Мониторинг
|
||||||
|
|
||||||
|
Метрики функций → Victoria Metrics / Grafana (уже есть в облаке).
|
||||||
|
Grafana: https://grafana.ngcloud.ru/dashboards/...
|
||||||
|
|
||||||
|
## Kubernetes кластер
|
||||||
|
|
||||||
|
Сейчас используется существующий кластер (временно).
|
||||||
|
Планируется переезд на новый кластер — манифесты переносятся без изменений.
|
||||||
|
|
||||||
|
Ноды существующего кластера:
|
||||||
|
- `wheel-control-plane-fm9sr` — control-plane
|
||||||
|
- `wheel-workers-tv4qr-r45xs` — worker
|
||||||
|
- `wheel-workers-tv4qr-x8xw7` — worker
|
||||||
|
|
||||||
|
Ingress: nginx, external IP `5.172.178.182`
|
||||||
|
Storage: rawfile CSI (local-path, default)
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
# Структура проекта
|
||||||
|
|
||||||
|
## Репозиторий
|
||||||
|
|
||||||
|
`gitea-naeel.giteak8s.services.ngcloud.ru/naeel/sless`
|
||||||
|
|
||||||
|
## Директории
|
||||||
|
|
||||||
|
```
|
||||||
|
sless/
|
||||||
|
├── cmd/
|
||||||
|
│ └── api/
|
||||||
|
│ └── main.go # точка входа API сервера
|
||||||
|
├── internal/
|
||||||
|
│ ├── api/
|
||||||
|
│ │ ├── handler/ # HTTP хендлеры (functions, versions, triggers)
|
||||||
|
│ │ ├── middleware/ # auth, logging, rate limit
|
||||||
|
│ │ └── router.go # регистрация маршрутов
|
||||||
|
│ ├── model/ # доменные модели: Function, Version, Trigger, Invocation
|
||||||
|
│ ├── storage/
|
||||||
|
│ │ ├── postgres/ # CRUD функций, версий, логов вызовов
|
||||||
|
│ │ └── s3/ # загрузка/скачивание zip архивов кода
|
||||||
|
│ ├── builder/ # сборка Docker образа из кода пользователя
|
||||||
|
│ ├── runner/ # запуск функций в k8s (Jobs / Deployments)
|
||||||
|
│ └── config/ # конфиг из env переменных
|
||||||
|
├── migrations/ # SQL миграции (numbered: 001_, 002_, ...)
|
||||||
|
├── deployments/
|
||||||
|
│ └── k8s/ # манифесты: Deployment, Service, Ingress, RBAC
|
||||||
|
├── api/
|
||||||
|
│ └── openapi.yaml # OpenAPI 3.0 спецификация
|
||||||
|
├── doc/ # документация проекта (эта папка)
|
||||||
|
└── docker-compose.yml # локальная разработка: postgres, redis, minio
|
||||||
|
```
|
||||||
|
|
||||||
|
## Go module
|
||||||
|
|
||||||
|
```
|
||||||
|
module gitea-naeel.giteak8s.services.ngcloud.ru/naeel/sless
|
||||||
|
```
|
||||||
|
|
||||||
|
## Порядок разработки
|
||||||
|
|
||||||
|
1. `internal/config` + `internal/model` — базовые структуры данных
|
||||||
|
2. `migrations/` + `internal/storage/postgres` — схема БД и CRUD
|
||||||
|
3. `internal/api` — HTTP хендлеры, роутер, middleware
|
||||||
|
4. `internal/storage/s3` — загрузка кода функций
|
||||||
|
5. `internal/builder` — сборка Docker образов
|
||||||
|
6. `internal/runner` — запуск функций в k8s
|
||||||
|
7. `deployments/k8s` — манифесты для деплоя
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# Решения и обоснования
|
||||||
|
|
||||||
|
## 2026-03-06 — Отдельная репа для сервиса
|
||||||
|
|
||||||
|
**Решение:** Serverless service в отдельной репе, не вместе с Terraform provider.
|
||||||
|
|
||||||
|
**Причина:** Разные зоны ответственности, разные релизы, потенциально разные команды.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2026-03-06 — Один бинарник для v1
|
||||||
|
|
||||||
|
**Решение:** Один Go бинарник вместо микросервисов.
|
||||||
|
|
||||||
|
**Причина:** Нагрузки изначально нет. Проще деплоить, проще отлаживать. Разделим при необходимости.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2026-03-06 — Аутентификация через облачный токен
|
||||||
|
|
||||||
|
**Решение:** Использовать Bearer token облака, без Keycloak.
|
||||||
|
|
||||||
|
**Причина:** Terraform provider уже работает с токенами облака. Keycloak — лишняя зависимость для v1.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2026-03-06 — S3 облачный, остальное в кубере
|
||||||
|
|
||||||
|
**Решение:** S3 (Ceph) использовать облачный (`ceph.tst.nubes.ru`), PostgreSQL/Redis — в кластере.
|
||||||
|
|
||||||
|
**Причина:** S3 имеет внешний доступ и уже готов. Для PostgreSQL/Redis сетевого связывания с облаком пока нет — настраивается через devops облака.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2026-03-06 — Текущий кластер для разработки
|
||||||
|
|
||||||
|
**Решение:** Использовать существующий k8s кластер (namespace `sless`), потом перенести на новый.
|
||||||
|
|
||||||
|
**Причина:** Новый кластер ещё не готов. Изоляция через namespace — безопасно для существующих сервисов.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2026-03-06 — RabbitMQ откладываем
|
||||||
|
|
||||||
|
**Решение:** В v1 только HTTP и Cron триггеры. RabbitMQ/event triggers — в v2.
|
||||||
|
|
||||||
|
**Причина:** Упрощение первой итерации.
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Ошибки и решения
|
||||||
|
|
||||||
|
> Сюда записываем проблемы с которыми столкнулись и как их решили.
|
||||||
|
|
||||||
|
## Шаблон записи
|
||||||
|
|
||||||
|
```
|
||||||
|
## YYYY-MM-DD — Короткое описание проблемы
|
||||||
|
|
||||||
|
**Проблема:** ...
|
||||||
|
|
||||||
|
**Причина:** ...
|
||||||
|
|
||||||
|
**Решение:** ...
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
# Инфраструктура
|
||||||
|
|
||||||
|
## Kubernetes кластер (существующий, временный)
|
||||||
|
|
||||||
|
- **Version:** v1.33.1
|
||||||
|
- **Ноды:** 1 control-plane + 2 workers
|
||||||
|
- **CNI:** Cilium
|
||||||
|
- **Ingress:** nginx, external IP `5.172.178.182`
|
||||||
|
- **Storage:** rawfile CSI (OpenEBS), StorageClass `local-path` (default)
|
||||||
|
- **cert-manager:** есть
|
||||||
|
- **Kyverno:** есть (политики — проверить при деплое)
|
||||||
|
|
||||||
|
## Namespace'ы для sless
|
||||||
|
|
||||||
|
| Namespace | Что там |
|
||||||
|
|-----------|---------|
|
||||||
|
| `sless` | API сервер, PostgreSQL, Redis |
|
||||||
|
| `sless-fn-{id}` | Функции пользователей (Jobs/Deployments) |
|
||||||
|
|
||||||
|
## S3
|
||||||
|
|
||||||
|
- **URL:** `http://ceph.tst.nubes.ru/`
|
||||||
|
- **Тип:** Ceph S3 compatible
|
||||||
|
- Доступ: внешний, через access/secret key
|
||||||
|
- Бакет для кода функций: `sless-functions`
|
||||||
|
|
||||||
|
## Container Registry
|
||||||
|
|
||||||
|
- Внутренний registry кластера в namespace `registry`
|
||||||
|
- Service: `registry.registry.svc.cluster.local:18080`
|
||||||
|
|
||||||
|
## Мониторинг
|
||||||
|
|
||||||
|
- Victoria Metrics — в кластере
|
||||||
|
- Grafana: `https://grafana.ngcloud.ru`
|
||||||
|
|
||||||
|
## Будущий кластер
|
||||||
|
|
||||||
|
Новый кластер готовится. После переезда:
|
||||||
|
- Манифесты переносятся без изменений
|
||||||
|
- Меняются только конфиги подключения к S3/PostgreSQL если нужно
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
# Прогресс разработки
|
||||||
|
|
||||||
|
## Статусы: ✅ готово | 🔄 в процессе | ⏳ не начато
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## v1 — Базовый сервис
|
||||||
|
|
||||||
|
| # | Компонент | Статус | Заметки |
|
||||||
|
|---|-----------|--------|---------|
|
||||||
|
| 1 | Структура проекта, go mod init | ⏳ | |
|
||||||
|
| 2 | internal/config | ⏳ | |
|
||||||
|
| 3 | internal/model | ⏳ | |
|
||||||
|
| 4 | Миграции PostgreSQL | ⏳ | |
|
||||||
|
| 5 | internal/storage/postgres | ⏳ | |
|
||||||
|
| 6 | internal/api — роутер + хендлеры | ⏳ | |
|
||||||
|
| 7 | internal/storage/s3 | ⏳ | |
|
||||||
|
| 8 | internal/builder | ⏳ | |
|
||||||
|
| 9 | internal/runner (k8s) | ⏳ | |
|
||||||
|
| 10 | docker-compose.yml (local dev) | ⏳ | |
|
||||||
|
| 11 | deployments/k8s манифесты | ⏳ | |
|
||||||
|
|
||||||
|
## v2 — Расширения
|
||||||
|
|
||||||
|
| # | Компонент | Статус | Заметки |
|
||||||
|
|---|-----------|--------|---------|
|
||||||
|
| 1 | RabbitMQ event triggers | ⏳ | |
|
||||||
|
| 2 | Keycloak / облачный auth | ⏳ | |
|
||||||
|
| 3 | Метрики → Victoria Metrics | ⏳ | |
|
||||||
|
| 4 | Интеграция с облачными PostgreSQL/Redis | ⏳ | |
|
||||||
|
| 5 | Мониторинг UI | ⏳ | |
|
||||||
Reference in New Issue
Block a user