11 KiB
План доработки Fission Console — 2026-04-25
Для нового чата. Масштаб: ~20 одновременных пользователей. Текущая версия:
naeel/fission-console:v0.8.8Ветка:feat/namespace-isolation
Контекст (кратко)
- Go-бэкенд
console/main.go+ embedded UIconsole/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"]
}
Что провайдер делает внутри:
- Ищет существующий
fission_environmentдля runtime → переиспользует или создаёт - Zip-архивирует
code_dir→ создаётfission_package(с ESM wrap для nodejs) - Создаёт
fission_function - Создаёт
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 apply → terraform 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:
- Проверить статус package → если
failed, вернуть buildError - Проверить поды namespace → если CrashLoopBackOff, вернуть причину
- Иначе — вернуть "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 моделей |