diff --git a/cmd/hubble/daemon_linux.go b/cmd/hubble/daemon_linux.go index 58c281a4a5..2bb3b1ae25 100644 --- a/cmd/hubble/daemon_linux.go +++ b/cmd/hubble/daemon_linux.go @@ -25,6 +25,7 @@ import ( "github.com/cilium/cilium/pkg/k8s/watchers" monitoragent "github.com/cilium/cilium/pkg/monitor/agent" "github.com/cilium/cilium/pkg/node" + "github.com/cilium/hive" "github.com/cilium/hive/cell" "github.com/cilium/workerpool" @@ -72,14 +73,29 @@ var ( }), // Start the controller manager - cell.Invoke(func(l *slog.Logger, lifecycle cell.Lifecycle, ctrlManager ctrl.Manager) { + cell.Invoke(func(l *slog.Logger, lifecycle cell.Lifecycle, shutdowner hive.Shutdowner, ctrlManager ctrl.Manager) { var wp *workerpool.WorkerPool lifecycle.Append( cell.Hook{ OnStart: func(cell.HookContext) error { wp = workerpool.New(1) l.Info("starting controller-runtime manager") - if err := wp.Submit("controller-runtime manager", ctrlManager.Start); err != nil { + if err := wp.Submit("controller-runtime manager", func(ctx context.Context) error { + // Shut down immediately if the manager exits unexpectedly to avoid running without reconciliation. + if err := ctrlManager.Start(ctx); err != nil { + l.Error("controller-runtime manager exited with error; node reconciler is no longer running", "error", err) + shutdowner.Shutdown(hive.ShutdownWithError(err)) + return errors.Wrap(err, "running controller-runtime manager") + } + if ctx.Err() == nil { + // Start returned early while the agent context is still active. + err := errors.New("controller-runtime manager stopped unexpectedly") + l.Error("controller-runtime manager stopped unexpectedly; node reconciler is no longer running") + shutdowner.Shutdown(hive.ShutdownWithError(err)) + return err + } + return nil + }); err != nil { return errors.Wrap(err, "failed to submit controller-runtime manager to workerpool") } return nil