mirror of
https://github.com/kubernetes-sigs/descheduler.git
synced 2026-08-23 22:46:35 +00:00
refactor(pkg/descheduler): start factory informers and other descheduler parts during bootstrap
This will help with testing as the initDescheduler function under descheduler_test.go is now much closer to the production invocation.
This commit is contained in:
@@ -552,6 +552,7 @@ func bootstrapDescheduler(
|
||||
rs *options.DeschedulerServer,
|
||||
deschedulerPolicy *api.DeschedulerPolicy,
|
||||
evictionPolicyGroupVersion string,
|
||||
metricProviderTokenReconciliation tokenReconciliation,
|
||||
sharedInformerFactory, namespacedSharedInformerFactory informers.SharedInformerFactory,
|
||||
eventRecorder events.EventRecorder,
|
||||
) (*descheduler, error) {
|
||||
@@ -585,6 +586,53 @@ func bootstrapDescheduler(
|
||||
}
|
||||
}
|
||||
|
||||
// init is responsible for starting all informer factories, metrics providers
|
||||
// and other parts that require to start before a first descheduling cycle is run
|
||||
deschedulerInitFnc := func(ctx context.Context) error {
|
||||
// In dry run mode, start and sync the fake shared informer factory so it can mirror
|
||||
// events from the real factory. Reliable propagation depends on both factories being
|
||||
// fully synced (see WaitForCacheSync calls below), not solely on startup order.
|
||||
if rs.DryRun {
|
||||
descheduler.kubeClientSandbox.fakeSharedInformerFactory().Start(ctx.Done())
|
||||
descheduler.kubeClientSandbox.fakeSharedInformerFactory().WaitForCacheSync(ctx.Done())
|
||||
}
|
||||
sharedInformerFactory.Start(ctx.Done())
|
||||
if metricProviderTokenReconciliation == secretReconciliation {
|
||||
namespacedSharedInformerFactory.Start(ctx.Done())
|
||||
}
|
||||
|
||||
sharedInformerFactory.WaitForCacheSync(ctx.Done())
|
||||
if metricProviderTokenReconciliation == secretReconciliation {
|
||||
namespacedSharedInformerFactory.WaitForCacheSync(ctx.Done())
|
||||
}
|
||||
|
||||
descheduler.podEvictor.WaitForEventHandlersSync(ctx)
|
||||
|
||||
if descheduler.metricsCollector != nil {
|
||||
go func() {
|
||||
klog.V(2).Infof("Starting metrics collector")
|
||||
descheduler.metricsCollector.Run(ctx)
|
||||
klog.V(2).Infof("Stopped metrics collector")
|
||||
}()
|
||||
klog.V(2).Infof("Waiting for metrics collector to sync")
|
||||
if err := wait.PollWithContext(ctx, time.Second, time.Minute, func(context.Context) (done bool, err error) {
|
||||
return descheduler.metricsCollector.HasSynced(), nil
|
||||
}); err != nil {
|
||||
return fmt.Errorf("unable to wait for metrics collector to sync: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if metricProviderTokenReconciliation == secretReconciliation {
|
||||
go descheduler.promClientCtrl.runAuthenticationSecretReconciler(ctx)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := deschedulerInitFnc(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return descheduler, nil
|
||||
}
|
||||
|
||||
@@ -622,49 +670,12 @@ func RunDeschedulerStrategies(ctx context.Context, rs *options.DeschedulerServer
|
||||
}
|
||||
}
|
||||
|
||||
descheduler, err := bootstrapDescheduler(ctx, rs, deschedulerPolicy, evictionPolicyGroupVersion, sharedInformerFactory, namespacedSharedInformerFactory, eventRecorder)
|
||||
descheduler, err := bootstrapDescheduler(ctx, rs, deschedulerPolicy, evictionPolicyGroupVersion, metricProviderTokenReconciliation, sharedInformerFactory, namespacedSharedInformerFactory, eventRecorder)
|
||||
if err != nil {
|
||||
span.AddEvent("Failed to bootstrap a descheduler", trace.WithAttributes(attribute.String("err", err.Error())))
|
||||
return err
|
||||
}
|
||||
|
||||
// In dry run mode, start and sync the fake shared informer factory so it can mirror
|
||||
// events from the real factory. Reliable propagation depends on both factories being
|
||||
// fully synced (see WaitForCacheSync calls below), not solely on startup order.
|
||||
if rs.DryRun {
|
||||
descheduler.kubeClientSandbox.fakeSharedInformerFactory().Start(ctx.Done())
|
||||
descheduler.kubeClientSandbox.fakeSharedInformerFactory().WaitForCacheSync(ctx.Done())
|
||||
}
|
||||
sharedInformerFactory.Start(ctx.Done())
|
||||
if metricProviderTokenReconciliation == secretReconciliation {
|
||||
namespacedSharedInformerFactory.Start(ctx.Done())
|
||||
}
|
||||
|
||||
sharedInformerFactory.WaitForCacheSync(ctx.Done())
|
||||
if metricProviderTokenReconciliation == secretReconciliation {
|
||||
namespacedSharedInformerFactory.WaitForCacheSync(ctx.Done())
|
||||
}
|
||||
|
||||
descheduler.podEvictor.WaitForEventHandlersSync(ctx)
|
||||
|
||||
if descheduler.metricsCollector != nil {
|
||||
go func() {
|
||||
klog.V(2).Infof("Starting metrics collector")
|
||||
descheduler.metricsCollector.Run(ctx)
|
||||
klog.V(2).Infof("Stopped metrics collector")
|
||||
}()
|
||||
klog.V(2).Infof("Waiting for metrics collector to sync")
|
||||
if err := wait.PollWithContext(ctx, time.Second, time.Minute, func(context.Context) (done bool, err error) {
|
||||
return descheduler.metricsCollector.HasSynced(), nil
|
||||
}); err != nil {
|
||||
return fmt.Errorf("unable to wait for metrics collector to sync: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if metricProviderTokenReconciliation == secretReconciliation {
|
||||
go descheduler.promClientCtrl.runAuthenticationSecretReconciler(ctx)
|
||||
}
|
||||
|
||||
wait.NonSlidingUntil(func() {
|
||||
if metricProviderTokenReconciliation == inClusterReconciliation {
|
||||
// Read the sa token and assume it has the sufficient permissions to authenticate
|
||||
|
||||
@@ -220,20 +220,12 @@ func initDescheduler(t *testing.T, ctx context.Context, featureGates featuregate
|
||||
eventBroadcaster, eventRecorder := utils.GetRecorderAndBroadcaster(ctx, client)
|
||||
|
||||
// Always create descheduler with real client/factory first to register all informers
|
||||
descheduler, err := bootstrapDescheduler(ctx, rs, internalDeschedulerPolicy, "v1", sharedInformerFactory, nil, eventRecorder)
|
||||
descheduler, err := bootstrapDescheduler(ctx, rs, internalDeschedulerPolicy, "v1", noReconciliation, sharedInformerFactory, nil, eventRecorder)
|
||||
if err != nil {
|
||||
eventBroadcaster.Shutdown()
|
||||
t.Fatalf("Failed to bootstrap a descheduler: %v", err)
|
||||
}
|
||||
|
||||
// Start the real shared informer factory after creating the descheduler
|
||||
if dryRun {
|
||||
descheduler.kubeClientSandbox.fakeSharedInformerFactory().Start(ctx.Done())
|
||||
descheduler.kubeClientSandbox.fakeSharedInformerFactory().WaitForCacheSync(ctx.Done())
|
||||
}
|
||||
sharedInformerFactory.Start(ctx.Done())
|
||||
sharedInformerFactory.WaitForCacheSync(ctx.Done())
|
||||
|
||||
if dryRun {
|
||||
if err := wait.PollUntilContextTimeout(ctx, 100*time.Millisecond, 5*time.Second, true, func(ctx context.Context) (bool, error) {
|
||||
for _, obj := range objects {
|
||||
|
||||
Reference in New Issue
Block a user