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:
@@ -0,0 +1,118 @@
|
||||
# Фикс: cron-функции не выполнялись из-за auth-цепочки timer→router
|
||||
|
||||
**Дата:** 2026-04-29
|
||||
**Образ после фикса:** `naeel/fission-console:v1.3.9`
|
||||
|
||||
---
|
||||
|
||||
## Симптом
|
||||
|
||||
Cron-триггер `croned` (namespace `fission-ffd1f598c169b0ae`, schedule `*/1 * * * *`) не выполнял функцию. В логах `timer`:
|
||||
|
||||
```
|
||||
status_code: 401, body: "unauthorized: malformed token"
|
||||
url: http://router.fission/fission-function/fission-ffd1f598c169b0ae/croned/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Диагностика
|
||||
|
||||
1. **Fission `timer`** при каждом тике делает `POST` на URL из аргумента `--routerUrl`.
|
||||
2. `--routerUrl` был `http://router.fission` — напрямую в Fission router.
|
||||
3. Fission router требует JWT-токен в `Authorization: Bearer`. Timer его не предоставляет.
|
||||
4. Результат: 401 на каждый тик.
|
||||
|
||||
**Ключевое открытие:** timer читает URL _исключительно_ из CLI-аргумента `--routerUrl`, а не из переменной окружения `FISSION_ROUTER_URL`. Патч env-переменных в Deployment не помогает.
|
||||
|
||||
---
|
||||
|
||||
## Решение
|
||||
|
||||
### Шаг 1: Console-gateway
|
||||
|
||||
В `console/internal/api/handlers.go` добавлен handler `handleFissionFunctionGateway`:
|
||||
|
||||
- Принимает `POST /fission-function/<namespace>/<function>[/subpath]` **без** auth-проверки.
|
||||
- Получает router JWT через `getRouterToken()` (POST `/auth/login` с кредами из Helm-секрета `router`).
|
||||
- Проксирует запрос в upstream router с нужным токеном.
|
||||
- Кэширует JWT до истечения срока действия.
|
||||
|
||||
Роуты зарегистрированы как публичные (без `authMiddleware`) в `server.go`:
|
||||
|
||||
```go
|
||||
mux.HandleFunc("/fission-function", s.handleFissionFunctionGateway)
|
||||
mux.HandleFunc("/fission-function/", s.handleFissionFunctionGateway)
|
||||
```
|
||||
|
||||
### Шаг 2: Патч timer Deployment
|
||||
|
||||
Перенаправлен `--routerUrl` с `http://router.fission` на `http://fission-console.fission.svc.cluster.local:8090`:
|
||||
|
||||
```bash
|
||||
kubectl -n fission get deploy timer -o json | python3 -c "
|
||||
import json,sys
|
||||
d=json.load(sys.stdin)
|
||||
cs=d['spec']['template']['spec']['containers']
|
||||
for c in cs:
|
||||
args=c.get('args',[])
|
||||
for i,a in enumerate(args):
|
||||
if 'router.fission' in a:
|
||||
args[i]='http://fission-console.fission.svc.cluster.local:8090'
|
||||
c['args']=args
|
||||
print(json.dumps(d))
|
||||
" | kubectl apply -f -
|
||||
```
|
||||
|
||||
### Шаг 3: Пересборка образа
|
||||
|
||||
Console v1.3.8 был собран до добавления `/fission-function/` роута → возвращал 404.
|
||||
Собран и задеплоен `naeel/fission-console:v1.3.9`.
|
||||
|
||||
---
|
||||
|
||||
## Подтверждение
|
||||
|
||||
Лог timer после фикса (06:19:10):
|
||||
|
||||
```json
|
||||
{
|
||||
"msg": "making HTTP POST request",
|
||||
"url": "http://fission-console.fission.svc.cluster.local:8090/fission-function/fission-ffd1f598c169b0ae/croned/",
|
||||
"status_code": 200,
|
||||
"body": "{\"invoke_url\":\"http://router.fission.svc.cluster.local/fission-function/...\",\"latency_ms\":10177,\"response_raw\":\"{\\\"status\\\":200,...}\"}"
|
||||
}
|
||||
```
|
||||
|
||||
Функция вернула JSON с метриками системы (CPU/RAM/disk). Тик подтверждён.
|
||||
|
||||
---
|
||||
|
||||
## Новая архитектура вызова cron
|
||||
|
||||
```
|
||||
timer (каждую минуту)
|
||||
└─► POST http://fission-console:8090/fission-function/<ns>/<fn>/
|
||||
└─► console gateway (getRouterToken + proxy)
|
||||
└─► POST http://router.fission/fission-function/<ns>/<fn>/ [Authorization: Bearer <jwt>]
|
||||
└─► function pod
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Затронутые файлы
|
||||
|
||||
| Файл | Изменение |
|
||||
|------|-----------|
|
||||
| `console/internal/api/handlers.go` | Добавлены `handleFissionFunctionGateway`, `invokeInternalFunction`, `getRouterToken`, `buildInternalInvokeURL` |
|
||||
| `console/internal/api/server.go` | Зарегистрированы публичные роуты `/fission-function` и `/fission-function/` |
|
||||
| `console/deploy/console.yaml` | Тег образа `v1.3.8` → `v1.3.9` |
|
||||
| Live k8s: `fission/deploy/timer` | `--routerUrl` изменён на `http://fission-console.fission.svc.cluster.local:8090` |
|
||||
|
||||
---
|
||||
|
||||
## Уроки
|
||||
|
||||
- Fission `timer` игнорирует `FISSION_ROUTER_URL` env — только `--routerUrl` CLI arg.
|
||||
- Pod timer distroless — нет shell/printenv, инспектировать через jsonpath.
|
||||
- Console Service port: **8090**, не 80 — без явного порта в URL будет timeout.
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user