Files
fission-console/doc/cron/CRON_TIMER_FIX_2026-04-29.md
T

119 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Фикс: 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.