@@ -38,6 +38,7 @@ import (
3838 "k8s.io/apimachinery/pkg/util/sets"
3939 "k8s.io/apimachinery/pkg/util/uuid"
4040 "k8s.io/apimachinery/pkg/util/wait"
41+ "k8s.io/apiserver/pkg/server"
4142 "k8s.io/apiserver/pkg/server/healthz"
4243 "k8s.io/apiserver/pkg/server/mux"
4344 utilfeature "k8s.io/apiserver/pkg/util/feature"
@@ -152,7 +153,9 @@ controller, and serviceaccounts controller.`,
152153 // add feature enablement metrics
153154 fg := s .ComponentGlobalsRegistry .FeatureGateFor (featuregate .DefaultKubeComponent )
154155 fg .(featuregate.MutableFeatureGate ).AddMetrics ()
155- return Run (context .Background (), c .Complete ())
156+
157+ stopCh := server .SetupSignalHandler ()
158+ return Run (context .Background (), c .Complete (), stopCh )
156159 },
157160 Args : func (cmd * cobra.Command , args []string ) error {
158161 for _ , arg := range args {
@@ -189,9 +192,9 @@ func ResyncPeriod(c *config.CompletedConfig) func() time.Duration {
189192}
190193
191194// Run runs the KubeControllerManagerOptions.
192- func Run (ctx context.Context , c * config.CompletedConfig ) error {
195+ func Run (ctx context.Context , c * config.CompletedConfig , stopCh2 <- chan struct {} ) error {
193196 logger := klog .FromContext (ctx )
194- stopCh := ctx .Done ()
197+ stopCh := mergeCh ( ctx .Done (), stopCh2 )
195198
196199 // To help debugging, immediately log version
197200 logger .Info ("Starting" , "version" , utilversion .Get ())
@@ -348,10 +351,18 @@ func Run(ctx context.Context, c *config.CompletedConfig) error {
348351 run (ctx , controllerDescriptors )
349352 },
350353 OnStoppedLeading : func () {
351- logger .Error (nil , "leaderelection lost" )
352- klog .FlushAndExit (klog .ExitFlushTimeout , 1 )
354+ select {
355+ case <- stopCh :
356+ // We were asked to terminate. Exit 0.
357+ klog .Info ("Requested to terminate. Exiting." )
358+ os .Exit (0 )
359+ default :
360+ // We lost the lock.
361+ logger .Error (nil , "leaderelection lost" )
362+ klog .FlushAndExit (klog .ExitFlushTimeout , 1 )
363+ }
353364 },
354- })
365+ }, stopCh )
355366
356367 // If Leader Migration is enabled, proceed to attempt the migration lock.
357368 if leaderMigrator != nil {
@@ -375,10 +386,18 @@ func Run(ctx context.Context, c *config.CompletedConfig) error {
375386 run (ctx , controllerDescriptors )
376387 },
377388 OnStoppedLeading : func () {
378- logger .Error (nil , "migration leaderelection lost" )
379- klog .FlushAndExit (klog .ExitFlushTimeout , 1 )
389+ select {
390+ case <- stopCh :
391+ // We were asked to terminate. Exit 0.
392+ klog .Info ("Requested to terminate. Exiting." )
393+ os .Exit (0 )
394+ default :
395+ // We lost the lock.
396+ logger .Error (nil , "migration leaderelection lost" )
397+ klog .FlushAndExit (klog .ExitFlushTimeout , 1 )
398+ }
380399 },
381- })
400+ }, stopCh )
382401 }
383402
384403 <- stopCh
@@ -886,7 +905,7 @@ func createClientBuilders(c *config.CompletedConfig) (clientBuilder clientbuilde
886905
887906// leaderElectAndRun runs the leader election, and runs the callbacks once the leader lease is acquired.
888907// TODO: extract this function into staging/controller-manager
889- func leaderElectAndRun (ctx context.Context , c * config.CompletedConfig , lockIdentity string , electionChecker * leaderelection.HealthzAdaptor , resourceLock string , leaseName string , callbacks leaderelection.LeaderCallbacks ) {
908+ func leaderElectAndRun (ctx context.Context , c * config.CompletedConfig , lockIdentity string , electionChecker * leaderelection.HealthzAdaptor , resourceLock string , leaseName string , callbacks leaderelection.LeaderCallbacks , stopCh <- chan struct {} ) {
890909 logger := klog .FromContext (ctx )
891910 rl , err := resourcelock .NewFromKubeconfig (resourceLock ,
892911 c .ComponentConfig .Generic .LeaderElection .ResourceNamespace ,
@@ -902,7 +921,13 @@ func leaderElectAndRun(ctx context.Context, c *config.CompletedConfig, lockIdent
902921 klog .FlushAndExit (klog .ExitFlushTimeout , 1 )
903922 }
904923
905- leaderelection .RunOrDie (ctx , leaderelection.LeaderElectionConfig {
924+ leCtx , cancel := context .WithCancel (ctx )
925+ defer cancel ()
926+ go func () {
927+ <- stopCh
928+ cancel ()
929+ }()
930+ leaderelection .RunOrDie (leCtx , leaderelection.LeaderElectionConfig {
906931 Lock : rl ,
907932 LeaseDuration : c .ComponentConfig .Generic .LeaderElection .LeaseDuration .Duration ,
908933 RenewDeadline : c .ComponentConfig .Generic .LeaderElection .RenewDeadline .Duration ,
0 commit comments