docs(cron): document full auth chain fix and push URL bug 2026-04-29
CRON/CRON_TIMER_FIX_2026-04-29.md: - moved from doc/cron/ to CRON/ (correct location) CRON/FISSION_CRON_NOTES.md: - added section on timer->router 401 and resolution via console-gateway - documented push URL bug (missing :8090 -> timeout) - documented full working chain with timestamps - added reminder: console service port is 8090, not 80 doc/report-2026-04-29-cron-fix.md: - new session report: symptoms, diagnosis, all 3 problems fixed, architecture diagram, affected components table, lessons learned
This commit is contained in:
@@ -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 <jwt>`. 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/<ns>/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
|
||||
|
||||
@@ -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 <jwt>`. Результат — 401.
|
||||
|
||||
**Ключевые факты:**
|
||||
- `timer` читает URL **только** из CLI-аргумента `--routerUrl` (env `FISSION_ROUTER_URL` игнорируется)
|
||||
- Pod `timer` distroless — нет shell, env инспектируется через `jsonpath`
|
||||
- Сервис `fission-console` слушает на **порту 8090**, не 80
|
||||
|
||||
**Решение:** console-gateway — публичный endpoint `/fission-function/<ns>/<fn>/`,
|
||||
который сам получает 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/<ns>/croned/
|
||||
└─► console gateway: getRouterToken() + proxy
|
||||
└─► POST http://router.fission/fission-function/<ns>/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 нужно удалить старые поды.
|
||||
Reference in New Issue
Block a user