Files
fission-console/doc/thinking/2026-04-25-plan.md

11 KiB
Raw Permalink Blame History

План доработки Fission Console — 2026-04-25

Для нового чата. Масштаб: ~20 одновременных пользователей. Текущая версия: naeel/fission-console:v0.8.8 Ветка: feat/namespace-isolation


Контекст (кратко)

  • Go-бэкенд console/main.go + embedded UI console/ui/index.html
  • Каждый пользователь → отдельный K8s namespace fission-<hash(sub)>
  • Fission core один на кластер, namespace регистрируется через NSReconciler
  • Terraform provider: низкоуровневый (Environment + Package + Function + HTTPTrigger)
  • API: https://fission.kube5s.ru/console/api, тест: X-Test-Sub: livetest@test.local
  • SSH: ssh -i ~/.ssh/naeel_vm_id_ed25519 naeel@5.172.178.213
  • sshfs: /home/naeel/remote_dev/fission/ = ~/terra/fission/ на VM

Задача 1: ResourceQuota + LimitRange на user namespace (ПРИОРИТЕТ 1)

Зачем: без квот одна функция может съесть весь CPU/RAM кластера.

Где делать: console/main.go, функция ensureUserNamespace.

Что добавить: при создании namespace применять два объекта:

# ResourceQuota
apiVersion: v1
kind: ResourceQuota
metadata:
  name: user-quota
  namespace: fission-<hash>
spec:
  hard:
    requests.cpu: "2"
    requests.memory: "2Gi"
    limits.cpu: "4"
    limits.memory: "4Gi"
    pods: "20"
    count/functions.fission.io: "20"
    count/packages.fission.io: "40"
# LimitRange
apiVersion: v1
kind: LimitRange
metadata:
  name: user-limits
  namespace: fission-<hash>
spec:
  limits:
  - type: Container
    default:
      cpu: "500m"
      memory: "256Mi"
    defaultRequest:
      cpu: "100m"
      memory: "64Mi"
    max:
      cpu: "2"
      memory: "1Gi"

Детали реализации:

  • Применять через k8s dynamic client или core client (уже есть в main.go)
  • Idempotent: если уже есть — не ошибаться, просто пропустить (patch или get+create)
  • Значения вынести в константы (или env vars) для удобной настройки

Файлы: console/main.go

Тест: создать нового пользователя, проверить kubectl get resourcequota,limitrange -n fission-<hash>


Задача 2: NetworkPolicy на user namespace (ПРИОРИТЕТ 2)

Зачем: без NetworkPolicy функции разных юзеров могут напрямую обращаться друг к другу по cluster IP.

Где делать: console/main.go, функция ensureUserNamespace (вместе с задачей 1).

Что создать: два правила:

# Deny all ingress from other namespaces (кроме fission core)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-cross-tenant
  namespace: fission-<hash>
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: fission   # fission core может
    - podSelector: {}                             # внутри namespace — OK

Осторожно: проверить что fission router/executor/fetcher namespace правильно лейблован. Если нет — добавить лейбл на namespace fission через kubectl.

Тест: поднять функцию в namespace A, попробовать curl из пода namespace B — должен fail.


Задача 3: fission_simple_function Terraform ресурс (ПРИОРИТЕТ 3)

Зачем: сейчас юзер пишет 4 ресурса вместо одного. Это неудобно и error-prone.

Ветка: feat/simple-function-resource (создана, код не написан)

Файл: terraform/provider/internal/resources/simple_function_resource.go

Целевой синтаксис для пользователя:

resource "fission_simple_function" "health" {
  name     = "health"
  runtime  = "nodejs"
  code_dir = "./code/health"
  url      = "/ecom/health"
  methods  = ["GET"]
}

Что провайдер делает внутри:

  1. Ищет существующий fission_environment для runtime → переиспользует или создаёт
  2. Zip-архивирует code_dir → создаёт fission_package (с ESM wrap для nodejs)
  3. Создаёт fission_function
  4. Создаёт fission_http_trigger (если указан url)

Атрибуты ресурса:

name        string  — имя функции
runtime     string  — nodejs / python / go / ruby / perl / php
code_dir    string  — путь к директории с кодом
url         string  — HTTP route (опционально)
methods     []string — ["GET","POST"] (опционально, default GET)
entrypoint  string  — имя точки входа (опционально, default "Handler")
min_scale   int     — минимальный масштаб (опционально, default 0)
max_scale   int     — максимальный масштаб (опционально, default 1)
ttl         int     — TTL в секундах (опционально)

Computed атрибуты:

invoke_url  string  — полный URL для вызова
status      string  — статус package (building / succeeded / failed)

Особенности реализации:

  • nodejs: ESM wrapper (export default { Handler }) — проверить формат как в Console
  • Go: нужен archive package (zip), не literal. BuildStatus polling.
  • Идемпотентность: Read → если уже есть все 3 ресурса, не пересоздавать
  • Delete: удалить trigger + function + package. Environment — только если unused.

Регистрация: добавить в terraform/provider/internal/provider/provider.go в Resources()

Примеры: обновить examples/big-suite/ после реализации

Тест: terraform applyterraform plan должен показать "no changes"


Задача 4: Улучшение поверхности ошибок (ПРИОРИТЕТ 4)

Зачем: сейчас при провале specialization пользователь видит "timeout after 20s: function specialization likely failed" — не информативно.

Что делать:

4.1 Package build status в API response

При создании функции и при GET /console/api/functions/:name — тянуть и возвращать:

{
  "name": "myfunc",
  "status": "building",   // или "ready" / "failed"
  "buildError": "compilation failed: undefined reference to..."
}

buildError брать из package.status.info (Fission заполняет это поле).

4.2 Specialization error в invoke response

Сейчас invoke возвращает timeout. Надо после timeout:

  1. Проверить статус package → если failed, вернуть buildError
  2. Проверить поды namespace → если CrashLoopBackOff, вернуть причину
  3. Иначе — вернуть "specialization timeout, function pod not ready"

4.3 UI polling для build status

После создания Go-функции (или любой с builder) — polling /console/api/functions/:name каждые 3s, показывать статус:

  • "Сборка..." → "Готово" / "Ошибка сборки: "

Файлы: console/main.go (API), console/ui/index.html (UI polling)


Задача 5: Cleanup и housekeeping (ПРИОРИТЕТ 5)

Что сделать:

5.1 Reaper для пустых namespace

Если namespace не имеет ни одной функции и не обращался больше N дней → удалить namespace + все ресурсы. Параметр: NAMESPACE_TTL_DAYS (env var, default 30).

5.2 Orphan package cleanup

При удалении функции — проверить все packages namespace, удалить те, на которые нет ни одной функции. Сейчас cleanupEnvironmentIfUnused есть, нужен аналог для packages.

5.3 Soft limit на функции на пользователя

MAX_FUNCTIONS_PER_USER (env var). При превышении → HTTP 429 с сообщением. Защита от случайного создания 1000 функций в loop.


Порядок выполнения (рекомендованный)

1. Задача 1 (ResourceQuota + LimitRange)  — ~2-3 часа, высокий риск если не сделать
2. Задача 2 (NetworkPolicy)               — ~1-2 часа, вместе с задачей 1
3. Задача 3 (fission_simple_function)     — ~1-2 дня, основная фича
4. Задача 4 (ошибки)                      — ~4-6 часов, UX improvement
5. Задача 5 (cleanup)                     — ~3-4 часа, housekeeping

Команды для нового чата

# Текущий образ
naeel/fission-console:v0.8.8

# Сборка нового образа (ОБЯЗАТЕЛЬНО сначала поменять тег в deploy/console.yaml!)
ssh -i ~/.ssh/naeel_vm_id_ed25519 naeel@5.172.178.213 \
  'cd ~/terra/fission && docker build -t naeel/fission-console:v0.8.9 -f console/Dockerfile console/ && docker push naeel/fission-console:v0.8.9'

# Deploy
ssh -i ~/.ssh/naeel_vm_id_ed25519 naeel@5.172.178.213 \
  'kubectl set image deployment/fission-console fission-console=naeel/fission-console:v0.8.9 -n fission'

# Тест после деплоя
ssh -i ~/.ssh/naeel_vm_id_ed25519 naeel@5.172.178.213 \
  'bash ~/terra/fission/tests_v2.sh 2>&1 | tail -5'

# Проверка quota (после задачи 1)
ssh -i ~/.ssh/naeel_vm_id_ed25519 naeel@5.172.178.213 \
  'kubectl get resourcequota,limitrange -n fission-c3fce59430e41b0f'

Файлы проекта (ключевые)

Файл Назначение
console/main.go Основная логика бэкенда
console/ui/index.html Embedded UI
console/deploy/console.yaml K8s deployment (тег образа)
console/deploy/rbac/console-ns-manager.yaml RBAC для fission-console SA
terraform/provider/internal/resources/ Terraform ресурсы
terraform/provider/internal/provider/provider.go Регистрация ресурсов
tests_v2.sh Регресс-тесты (73 блока, все PASS)
doc/thinking/2026-04-25-ai-opinions.md Мнения AI моделей