# Function Env Vars — ПОЛНАЯ ДОКУМЕНТАЦИЯ (v1.3.77+) ## ПРОБЛЕМА (обнаружена 2026-05-09) Env vars хранились только в аннотации `fission-console/env-vars` на Function CRD. Это работало для UI (хранение/отображение), но переменные **не попадали в pod функции**. ### Почему не попадали Fission `poolmgr` создаёт warm pool подов **заранее**, до того как знает какая функция будет запущена. Pod уже работает в момент первого вызова функции. `spec.podspec.containers[].env` из Function CRD при poolmgr **игнорируется** — pod уже запущен. При специализации (загрузке кода функции) fetcher передаёт в pod только: - путь к файлу с кодом - имя entrypoint функции - секреты и configmaps (как файлы в `/userfunc/...`) Переменные окружения через `poolmgr` можно установить только на уровне Environment deployment — одинаковые для ВСЕХ функций этого окружения. Индивидуально для функции — невозможно. ### Отвергнутые варианты | Вариант | Почему нет | |---------|-----------| | `spec.podspec.containers[].env` + poolmgr | Pod уже запущен до специализации | | `spec.configmaps` → файлы `/userfunc/configs/` | Нужно читать файл в коде — не универсально | | Патч python-env server | Только Python, другие языки сломаны | | PostgreSQL/отдельное хранилище | Оверкилл, не официальный путь | --- ## РЕШЕНИЕ (v1.3.77+) **Автоматическое переключение ExecutorType в зависимости от наличия env vars.** - Функция **без env vars** → `ExecutorType: poolmgr` → warm pool, быстрый cold start (~0.5 сек) - Функция **с env vars** → `ExecutorType: newdeploy` → dedicated Deployment, env vars в OS (~2-5 сек) Пользователь ничего не настраивает — переключение происходит автоматически. ### Почему newdeploy работает При `newdeploy` Fission создаёт отдельный Kubernetes `Deployment` для функции. В этот Deployment попадает `spec.podspec` из Function CRD **включая** `containers[0].env`. Kubernetes ставит переменные на уровне ОС процесса контейнера при старте пода. ### Почему это универсально для всех языков Переменные окружения ОС — стандарт POSIX. Любой язык читает без изменений в env-сервере: ```python os.getenv("MY_VAR") # Python os.Getenv("MY_VAR") # Go ENV["MY_VAR"] # Ruby getenv("MY_VAR") # PHP process.env.MY_VAR # Node.js ``` ### Нет дублирования подов Warm pool принадлежит **Environment**, не функции. Переключение конкретной функции на `newdeploy` не трогает pool — другие функции без env vars продолжают использовать его. --- ## РЕАЛИЗАЦИЯ ### Backend: `handlePutFunctionEnvVars` (function_crud.go) При `PUT /functions/:name/envvars`: 1. Сохраняет env vars в аннотацию `fission-console/env-vars` (для UI) 2. Если env vars **непустые**: - Выставляет `spec.podspec.containers[0].env` (стандартный Kubernetes EnvVar) - Переключает `spec.InvokeStrategy.ExecutionStrategy.ExecutorType` = `"newdeploy"` - MinScale=0, MaxScale=1 3. Если env vars **пустые** (очищены): - Удаляет `spec.podspec` - Возвращает `ExecutorType` = `"poolmgr"` ### Двойное хранение | Где | Зачем | |-----|-------| | Аннотация `fission-console/env-vars` | UI: отображение, редактирование | | `spec.podspec.containers[0].env` | Fission/Kubernetes: реальное применение в pod | ### Структура Function CRD с env vars ```yaml spec: InvokeStrategy: ExecutionStrategy: ExecutorType: newdeploy MinScale: 0 MaxScale: 1 StrategyType: execution podspec: containers: - name: env: - name: p1 value: "envv1" metadata: annotations: fission-console/env-vars: '[{"name":"p1","value":"envv1"}]' ``` ### Структура Function CRD без env vars ```yaml spec: InvokeStrategy: ExecutionStrategy: ExecutorType: poolmgr StrategyType: execution # нет podspec ``` --- ## ОГРАНИЧЕНИЯ - `newdeploy` медленнее cold start (~2-5 сек vs ~0.5 сек) — выбор пользователя, добавившего env vars - MinScale=0: при отсутствии трафика pod удаляется → cold start при первом вызове - Имена переменных: только `[A-Za-z_][A-Za-z0-9_]*` — стандарт POSIX, проверяется на UI - TF-функции (`tf-*`) — env vars read-only, изменение запрещено через UI