@@ -2,8 +2,10 @@ package main
22
33import (
44 "context"
5+ "errors"
56 "flag"
67 "fmt"
8+ "net/http"
79 "os"
810
911 "github.com/cilium/ebpf"
@@ -32,16 +34,20 @@ type Config struct {
3234 enableLearning bool
3335 nriSocketPath string
3436 nriPluginIdx string
37+ probeAddr string
3538}
3639
3740// +kubebuilder:rbac:groups=security.rancher.io,resources=workloadpolicies,verbs=get;list;watch
3841
39- func newControllerManager () (manager.Manager , error ) {
42+ func newControllerManager (config Config ) (manager.Manager , error ) {
4043 scheme := runtime .NewScheme ()
4144 utilruntime .Must (v1alpha1 .AddToScheme (scheme ))
4245 utilruntime .Must (clientgoscheme .AddToScheme (scheme ))
4346 utilruntime .Must (securityv1alpha1 .AddToScheme (scheme ))
44- controllerOptions := ctrl.Options {Scheme : scheme }
47+ controllerOptions := ctrl.Options {
48+ Scheme : scheme ,
49+ HealthProbeBindAddress : config .probeAddr ,
50+ }
4551 mgr , err := ctrl .NewManager (ctrl .GetConfigOrDie (), controllerOptions )
4652 if err != nil {
4753 return nil , fmt .Errorf ("unable to start manager: %w" , err )
@@ -55,7 +61,7 @@ func startAgent(ctx context.Context, logger *slog.Logger, config Config) error {
5561 //////////////////////
5662 // Create controller manager
5763 //////////////////////
58- ctrlMgr , err := newControllerManager ()
64+ ctrlMgr , err := newControllerManager (config )
5965 if err != nil {
6066 return fmt .Errorf ("cannot create manager: %w" , err )
6167 }
@@ -118,6 +124,12 @@ func startAgent(ctx context.Context, logger *slog.Logger, config Config) error {
118124 return fmt .Errorf ("failed to add NRI handler to controller manager: %w" , err )
119125 }
120126
127+ // controller-runtime doesn't support a separate startup probe, so we use the readiness probe instead.
128+ // See https://github.com/kubernetes-sigs/controller-runtime/issues/2644 for more details.
129+ if err = ctrlMgr .AddReadyzCheck ("resolver readyz" , resolver .Ping ); err != nil {
130+ return fmt .Errorf ("failed to add resolver's readiness probe: %w" , err )
131+ }
132+
121133 //////////////////////
122134 // Create the scraper
123135 //////////////////////
@@ -139,7 +151,23 @@ func startAgent(ctx context.Context, logger *slog.Logger, config Config) error {
139151 if err != nil {
140152 return fmt .Errorf ("cannot get workload policy informer: %w" , err )
141153 }
142- _ , _ = workloadPolicyInformer .AddEventHandler (resolver .PolicyEventHandlers ())
154+ handlerRegistration , err := workloadPolicyInformer .AddEventHandler (resolver .PolicyEventHandlers ())
155+ if err != nil {
156+ return fmt .Errorf ("failed to add event handler for workload policy: %w" , err )
157+ }
158+
159+ if err = ctrlMgr .AddReadyzCheck ("policy readyz" , func (_ * http.Request ) error {
160+ // Instead of informer.HasSynced(), which checks if the internal storage is synced,
161+ // we use ResourceEventHandlerRegistration.HasSynced() to ensure that
162+ // the event handlers have been synced.
163+ if ! handlerRegistration .HasSynced () {
164+ logger .Warn ("workload policy informer has not yet synced" )
165+ return errors .New ("workload policy informer has not yet synced" )
166+ }
167+ return nil
168+ }); err != nil {
169+ return fmt .Errorf ("failed to add NRI handler's readiness probe: %w" , err )
170+ }
143171
144172 logger .InfoContext (ctx , "starting manager" )
145173 if err = ctrlMgr .Start (ctx ); err != nil {
@@ -167,6 +195,7 @@ func main() {
167195 flag .BoolVar (& config .enableLearning , "enable-learning" , false , "Enable learning mode" )
168196 flag .StringVar (& config .nriSocketPath , "nri-socket-path" , "/var/run/nri/nri.sock" , "NRI socket path" )
169197 flag .StringVar (& config .nriPluginIdx , "nri-plugin-index" , "00" , "NRI plugin index" )
198+ flag .StringVar (& config .probeAddr , "health-probe-bind-address" , ":8081" , "The address the probe endpoint binds to." )
170199
171200 flag .Parse ()
172201
0 commit comments