diff --git a/doc/cron/CRON_TIMER_FIX_2026-04-29.md b/CRON/CRON_TIMER_FIX_2026-04-29.md similarity index 100% rename from doc/cron/CRON_TIMER_FIX_2026-04-29.md rename to CRON/CRON_TIMER_FIX_2026-04-29.md diff --git a/CRON/FISSION_CRON_NOTES.md b/CRON/FISSION_CRON_NOTES.md index d7ce435..47889c7 100644 --- a/CRON/FISSION_CRON_NOTES.md +++ b/CRON/FISSION_CRON_NOTES.md @@ -44,3 +44,53 @@ - snapshot не сохранился в `cron_metrics` - Console не запускает shell-команды в Kubernetes и не исполняет cron сама. - Console только создает CRD, а дальше работает штатный Fission controller path. + +--- + +## Дополнение 2026-04-29 — auth-цепочка и push URL + +### Проблема 1: timer → router → 401 + +Fission `timer` по умолчанию шлёт invoke прямо на `http://router.fission`, но router +требует `Authorization: Bearer `. Timer токен не предоставляет → 401 на каждый тик. + +**Решение:** перенаправить `--routerUrl` timer-а через console-gateway: +``` +http://fission-console.fission.svc.cluster.local:8090 +``` +Console-gateway принимает запрос без auth, сам получает JWT у router и проксирует. + +**Важно:** Timer читает URL **только** из CLI-аргумента `--routerUrl`. Переменная окружения +`FISSION_ROUTER_URL` игнорируется. Патч нужно делать через `kubectl patch deployment timer`. + +### Проблема 2: push метрик без порта → timeout + +Python-функция пушит снимок метрик на: +``` +http://fission-console.fission.svc.cluster.local/cron/api/metrics +``` +Сервис `fission-console` слушает на порту **8090**, не 80. Без явного `:8090` — timeout. + +**Решение:** обновить `croned-pkg` (поле `spec.deployment.literal`) — заменить URL на: +``` +http://fission-console.fission.svc.cluster.local:8090/cron/api/metrics +``` +После обновления package — удалить кэшированные pool-поды функции, чтобы они перезагрузили код. + +### Полная рабочая цепочка (с 06:31 2026-04-29) + +``` +timer (*/1 * * * *) + └─► POST :8090/fission-function//croned/ console gateway + └─► router.fission [Bearer jwt] + └─► python pod → собирает метрики + └─► POST :8090/cron/api/metrics ← ранее без :8090, timeout + └─► cron_metrics.go сохраняет в память + └─► GET /cron → cron.html рендерит таблицу +``` + +### Порт 8090 — критично помнить + +- `kubectl -n fission get svc fission-console` → `8090/TCP` +- Любой internal URL к console должен включать `:8090` +- Без порта HTTP-клиент идёт на 80 → i/o timeout diff --git a/doc/report-2026-04-29-cron-fix.md b/doc/report-2026-04-29-cron-fix.md new file mode 100644 index 0000000..bdc582d --- /dev/null +++ b/doc/report-2026-04-29-cron-fix.md @@ -0,0 +1,122 @@ +# Отчёт 2026-04-29 — Cron auth-цепочка, push URL, образ v1.3.9 + +## Цель сессии + +Починить cron-триггер `croned`: функция не выполнялась по расписанию — 401 на каждый тик. +Добиться полной цепочки: timer → function → сохранение метрик → отображение на `/cron`. + +--- + +## Симптом + +В логах `timer` каждую минуту: +``` +status_code: 401, body: "unauthorized: malformed token" +url: http://router.fission/fission-function/fission-ffd1f598c169b0ae/croned/ +``` + +Страница `https://fission.kube5s.ru/cron` пустая — данных нет. + +--- + +## Диагностика и устранение + +### Проблема 1: timer → router без JWT + +Fission `timer` делает HTTP POST на `--routerUrl` без какой-либо аутентификации. +Router требует `Authorization: Bearer `. Результат — 401. + +**Ключевые факты:** +- `timer` читает URL **только** из CLI-аргумента `--routerUrl` (env `FISSION_ROUTER_URL` игнорируется) +- Pod `timer` distroless — нет shell, env инспектируется через `jsonpath` +- Сервис `fission-console` слушает на **порту 8090**, не 80 + +**Решение:** console-gateway — публичный endpoint `/fission-function///`, +который сам получает JWT у router и проксирует запрос. + +Добавлено в `console/internal/api/handlers.go`: +- `handleFissionFunctionGateway` — точка входа, парсит path +- `invokeInternalFunction` — проксирует с Bearer-токеном +- `getRouterToken` — получает JWT через `/auth/login` (с кэшем) +- `buildInternalInvokeURL` — строит URL к router + +Зарегистрировано в `server.go` как **публичные** роуты (без `authMiddleware`): +```go +mux.HandleFunc("/fission-function", s.handleFissionFunctionGateway) +mux.HandleFunc("/fission-function/", s.handleFissionFunctionGateway) +``` + +Timer Deployment пропатчен: `--routerUrl` → `http://fission-console.fission.svc.cluster.local:8090` + +Образ пересобран: `naeel/fission-console:v1.3.9` (v1.3.8 был до добавления gateway-роута → 404). + +### Проблема 2: push метрик без порта → timeout + +Python-функция `croned` в конце отправляет снимок метрик: +```python +target = os.getenv("CRON_TARGET_URL", + "http://fission-console.fission.svc.cluster.local/cron/api/metrics") +``` +URL без `:8090` — service на 80 не слушает → `urlopen error timed out`. +Метрики не сохранялись, `/cron` пустой. + +**Решение:** обновлён package `croned-pkg` на кластере (поле `spec.deployment.literal`): +заменён default URL на `http://fission-console.fission.svc.cluster.local:8090/cron/api/metrics`. + +После обновления package удалены кэшированные pool-поды функции — подхватили новый код. + +### Проблема 3: container name в Deployment + +При первом `kubectl set image` использовалось имя контейнера `fission-console` → ошибка. +Реальное имя контейнера в Deployment `fission-console` — `console`. + +--- + +## Результат (подтверждён в логах) + +``` +06:31:00 POST /fission-function/fission-ffd1f598c169b0ae/croned/ [status 200] +06:31:00 POST /cron/api/metrics [функция запушила] +06:31:11 GET /cron/api/metrics [UI читает] +``` + +API `https://fission.kube5s.ru/cron/api/metrics` вернул `count: 2` и полные метрики. + +--- + +## Итоговая архитектура cron + +``` +timer (*/1 * * * *) + └─► POST http://fission-console.fission.svc.cluster.local:8090/fission-function//croned/ + └─► console gateway: getRouterToken() + proxy + └─► POST http://router.fission/fission-function//croned/ [Bearer jwt] + └─► python pod: собирает /proc метрики + └─► POST :8090/cron/api/metrics + └─► cron_metrics.go: сохраняет в cronMetricHistory + └─► GET /cron → cron.html: рендерит карточки + таблицу +``` + +--- + +## Затронутые компоненты + +| Компонент | Изменение | +|-----------|-----------| +| `console/internal/api/handlers.go` | Добавлен gateway: `handleFissionFunctionGateway`, `invokeInternalFunction`, `getRouterToken`, `buildInternalInvokeURL` | +| `console/internal/api/server.go` | Публичные роуты `/fission-function` и `/fission-function/` | +| `console/deploy/console.yaml` | Тег `v1.3.8` → `v1.3.9` | +| `CRON/CRON_TIMER_FIX_2026-04-29.md` | Детальная документация фикса | +| `CRON/FISSION_CRON_NOTES.md` | Дополнен разделом про auth-цепочку и порт 8090 | +| Live k8s: `fission/deploy/timer` | `--routerUrl` → `http://fission-console.fission.svc.cluster.local:8090` | +| Live k8s: `fission-ffd1f598c169b0ae/package/croned-pkg` | URL push метрик добавлен `:8090` | + +--- + +## Уроки + +- `timer` читает `--routerUrl` только из CLI-аргумента, env-переменная игнорируется. +- Сервис `fission-console` на порту **8090** — без него любой internal HTTP-запрос timeout. +- Container name в Deployment `fission-console` — `console`, не `fission-console`. +- Distroless pod — нет shell, env/args читать только через `kubectl get -o jsonpath`. +- Pool-поды функций кэшируют код — после обновления package нужно удалить старые поды.