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
4.6 KiB
Фикс: 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/
Диагностика
- Fission
timerпри каждом тике делаетPOSTна URL из аргумента--routerUrl. --routerUrlбылhttp://router.fission— напрямую в Fission router.- Fission router требует JWT-токен в
Authorization: Bearer. Timer его не предоставляет. - Результат: 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:
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:
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):
{
"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_URLenv — только--routerUrlCLI arg. - Pod timer distroless — нет shell/printenv, инспектировать через jsonpath.
- Console Service port: 8090, не 80 — без явного порта в URL будет timeout.