8.3 KiB
Решения и обоснования
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.
Причина: Упрощение первой итерации.
2026-03-07 — DockerHub вместо внутреннего registry
Решение: Образы функций и runtime базовые образы публикуются на DockerHub (user naeel).
Причина: Namespace registry в кластере — это Apache NiFi Registry (NOT Docker). Отдельный Docker registry не поднят. DockerHub доступен и достаточен для разработки.
2026-03-07 — Terraform провайдер sless — отдельный модуль в той же репе
Решение: terraform/provider/ — независимый Go-модуль внутри репы sless.
Причина: Удобно держать рядом. Код провайдера писался с прицелом на перенос в nubes провайдер (/home/naeel/remote_dev/terraform). Клиент (internal/client/) → internal/core/ nubes, ресурсы → internal/resources_gen/.
2026-03-07 — WaitReady в Terraform провайдере при создании функции
Решение: После UploadCode провайдер ждёт phase=Ready (polling каждые 5 сек, таймаут 5 мин).
Причина: Kaniko-сборка занимает ~1 минуту. Без ожидания terraform apply завершился бы с phase=Building в state, что неверно отображало бы реальное состояние ресурса.
2026-03-07 — code_hash для детектирования изменений кода функции
Решение: Атрибут code_hash в sless_function — пользователь задаёт через filemd5("./handler.zip"). Изменение hash → провайдер перезагружает zip и запускает пересборку.
Причина: Terraform не отслеживает содержимое файлов автоматически. Это стандартный паттерн (аналогично aws_lambda_function.source_code_hash).
2026-03-07 — Scale-to-zero откладываем до v2
Решение: В v1 функции работают как Deployment с постоянно живым подом (always-on). Scale-to-zero — в v2 через KEDA HTTP Add-on.
Причина: Scale-to-zero меняет архитектуру контроллера и routing. Для MVP это несоразмерная сложность. Пользователь может управлять ресурсами вручную через replicas = 0/1/N (планируется в v1.1).
v2 план: Заменить Deployment на HTTPScaledObject (KEDA), минимальные реплики = 0. KEDA буферизует запросы во время cold start (~1-3 сек).
2026-03-07 — replicas как ручное управление масштабом (TODO v1.1)
Решение: Добавить поле replicas *int32 в FunctionSpec. Пользователь задаёт через Terraform: replicas = 0 (выключить), replicas = 1 (включить), replicas = N (масштабировать).
Причина: Без этого функция жрёт ресурсы 24/7 даже если не нужна. Это минимальный механизм контроля потребления до реализации scale-to-zero.
2026-03-07 — PostgreSQL опционален для базового Function Hosting
Решение: Postgres нужен только для логов вызовов (invocations). Для базового деплоя функций — не нужен. Оператор работает без него (просто не пишет логи).
Минимальные зависимости для production: k8s кластер + S3 + Docker registry + Ingress.
2026-03-07 — Версионированные теги для runtime образов (не :latest)
Решение: Runtime базовые образы (sless-runtime-python3.11, sless-runtime-nodejs20) и образ оператора (sless-operator) тегируются по схеме v<major>.<minor>.<patch>. :latest не используется.
Причина:
:latestприводит к непредсказуемому поведению: kaniko может взять старый кешированный образ, pod не перезапускается еслиimagePullPolicy: IfNotPresent.- Версионированные теги дают явный контроль: при изменении runtime нужно обновить тег в
upload.go→ это принудительно пересобирает все функции с новым базовым образом. - Аудит и откат: можно пинить конкретную версию runtime.
Соглашение:
- Runtime образы:
naeel/sless-runtime-{lang}:v{версия}(напримерv0.1.0) - Оператор:
naeel/sless-operator:v{версия} - При изменении runtime — инкрементировать минорную версию образа и обновить константу в
upload.go
2026-03-07 — nodejs20 как второй поддерживаемый runtime
Решение: Добавлен nodejs20 runtime (node:20-alpine base, server.js HTTP wrapper, exports.handle(event)).
Причина: Node.js — стандарт для serverless (AWS Lambda, Vercel). Покрывает JS/TypeScript аудиторию. Паттерн идентичен python3.11: runtime image → kaniko → Deployment.
Детали реализации:
runtimes/nodejs20/server.js—http.createServer, динамическийrequire(HANDLER_PATH)- Зависимости через
package.json→npm install --omit=dev(аналогrequirements.txt→pip install) entrypointв HCL игнорируется для Node.js (всегдаhandler.js+exports.handle) — TODO: поддержать произвольный entrypoint в v1.1