fix: FunctionJob зависал в Running — добавлен RequeueAfter polling
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// Изменено: 2026-03-08
|
||||
// Изменено: 2026-03-08 (fix: RequeueAfter для poll статуса Job)
|
||||
// FunctionJobReconciler — контроллер одноразовых запусков функций.
|
||||
// При создании FunctionJob:
|
||||
// 1. Ждёт пока Function станет Ready
|
||||
@@ -14,6 +14,7 @@ package controllers
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
@@ -180,6 +181,8 @@ func (r *FunctionJobReconciler) Reconcile(ctx context.Context, req ctrl.Request)
|
||||
}
|
||||
|
||||
// syncJobStatus читает статус k8s Job и обновляет FunctionJob.Status.
|
||||
// Если Job ещё выполняется — запрашивает повторный reconcile через 5 сек
|
||||
// (Owns не работает кросс-неймспейсно, поэтому используем polling).
|
||||
func (r *FunctionJobReconciler) syncJobStatus(ctx context.Context, fj *slessv1alpha1.FunctionJob, job *batchv1.Job) (ctrl.Result, error) {
|
||||
if job.Status.Succeeded > 0 {
|
||||
now := metav1.Now()
|
||||
@@ -191,8 +194,13 @@ func (r *FunctionJobReconciler) syncJobStatus(ctx context.Context, fj *slessv1al
|
||||
fj.Status.Phase = slessv1alpha1.FunctionJobPhaseFailed
|
||||
fj.Status.CompletionTime = &now
|
||||
fj.Status.Message = "job failed, check pod logs: kubectl logs -n sless-fn-" + fj.Namespace + " -l functionjob=" + fj.Name
|
||||
} else {
|
||||
// Job ещё выполняется — перечитаем через 5 секунд
|
||||
if err := r.Status().Update(ctx, fj); err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("sync job status: %w", err)
|
||||
}
|
||||
return ctrl.Result{RequeueAfter: 5 * time.Second}, nil
|
||||
}
|
||||
// Running — ничего не меняем, перечитаем при следующем reconcile
|
||||
if err := r.Status().Update(ctx, fj); err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("sync job status: %w", err)
|
||||
}
|
||||
@@ -251,10 +259,12 @@ func fnEnvVars(fn *slessv1alpha1.Function) []corev1.EnvVar {
|
||||
|
||||
func int32Ptr(i int32) *int32 { return &i }
|
||||
|
||||
// SetupWithManager регистрирует контроллер и настраивает watch на k8s Job.
|
||||
// SetupWithManager регистрирует контроллер.
|
||||
// Owns(&batchv1.Job{}) намеренно убрано: Job создаётся в другом namespace
|
||||
// (sless-fn-*), где OwnerReference кросс-неймспейсно не работают.
|
||||
// Вместо этого используется RequeueAfter-polling в syncJobStatus.
|
||||
func (r *FunctionJobReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewControllerManagedBy(mgr).
|
||||
For(&slessv1alpha1.FunctionJob{}).
|
||||
Owns(&batchv1.Job{}).
|
||||
Complete(r)
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ spec:
|
||||
containers:
|
||||
- name: operator
|
||||
# При обновлении версии оператора — менять тег здесь (не latest!)
|
||||
image: naeel/sless-operator:v0.1.8
|
||||
image: naeel/sless-operator:v0.1.10
|
||||
# Always — чтобы всегда тянуть по точному тегу (не кешировать старый)
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
|
||||
@@ -38,9 +38,10 @@ rules:
|
||||
resources: ["services", "namespaces"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
# Secrets — pull-секрет копируется в sless-fn-* namespace при создании функций
|
||||
# list/watch нужны для controller-runtime cache (информер на secrets)
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get", "create"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch"]
|
||||
- apiGroups: ["networking.k8s.io"]
|
||||
resources: ["ingresses"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
|
||||
@@ -5,3 +5,4 @@ exports.handle = async (event) => {
|
||||
const name = event.name || 'World';
|
||||
return { message: `Hello, ${name}!` };
|
||||
};
|
||||
|
||||
|
||||
@@ -7,3 +7,4 @@ exports.handle = async (event) => {
|
||||
const sum = numbers.reduce((acc, n) => acc + n, 0);
|
||||
return { input: numbers, sum, count: numbers.length };
|
||||
};
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -33,7 +33,7 @@ func runtimeBaseImage(runtime string) (string, error) {
|
||||
case "python3.11":
|
||||
return "naeel/sless-runtime-python3.11:v0.1.0", nil
|
||||
case "nodejs20":
|
||||
return "naeel/sless-runtime-nodejs20:v0.1.0", nil
|
||||
return "naeel/sless-runtime-nodejs20:v0.1.1", nil
|
||||
default:
|
||||
return "", fmt.Errorf("unsupported runtime: %q (supported: python3.11, nodejs20)", runtime)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user