k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/cmd/kube-controller-manager/app/controllermanager.go (about)

     1  /*
     2  Copyright 2014 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  // Package app implements a server that runs a set of active
    18  // components.  This includes replication controllers, service endpoints and
    19  // nodes.
    20  package app
    21  
    22  import (
    23  	"context"
    24  	"fmt"
    25  	"k8s.io/apimachinery/pkg/runtime/schema"
    26  	"math/rand"
    27  	"net/http"
    28  	"os"
    29  	"sort"
    30  	"time"
    31  
    32  	"github.com/spf13/cobra"
    33  
    34  	"k8s.io/apimachinery/pkg/api/meta"
    35  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    36  	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
    37  	"k8s.io/apimachinery/pkg/util/sets"
    38  	"k8s.io/apimachinery/pkg/util/uuid"
    39  	"k8s.io/apimachinery/pkg/util/wait"
    40  	"k8s.io/apiserver/pkg/server/healthz"
    41  	"k8s.io/apiserver/pkg/server/mux"
    42  	utilfeature "k8s.io/apiserver/pkg/util/feature"
    43  	cacheddiscovery "k8s.io/client-go/discovery/cached/memory"
    44  	"k8s.io/client-go/informers"
    45  	v1core "k8s.io/client-go/kubernetes/typed/core/v1"
    46  	"k8s.io/client-go/metadata"
    47  	"k8s.io/client-go/metadata/metadatainformer"
    48  	restclient "k8s.io/client-go/rest"
    49  	"k8s.io/client-go/restmapper"
    50  	"k8s.io/client-go/tools/leaderelection"
    51  	"k8s.io/client-go/tools/leaderelection/resourcelock"
    52  	certutil "k8s.io/client-go/util/cert"
    53  	"k8s.io/client-go/util/keyutil"
    54  	cloudprovider "k8s.io/cloud-provider"
    55  	cliflag "k8s.io/component-base/cli/flag"
    56  	"k8s.io/component-base/cli/globalflag"
    57  	"k8s.io/component-base/configz"
    58  	"k8s.io/component-base/featuregate"
    59  	"k8s.io/component-base/logs"
    60  	logsapi "k8s.io/component-base/logs/api/v1"
    61  	metricsfeatures "k8s.io/component-base/metrics/features"
    62  	controllersmetrics "k8s.io/component-base/metrics/prometheus/controllers"
    63  	"k8s.io/component-base/metrics/prometheus/slis"
    64  	"k8s.io/component-base/term"
    65  	"k8s.io/component-base/version"
    66  	"k8s.io/component-base/version/verflag"
    67  	genericcontrollermanager "k8s.io/controller-manager/app"
    68  	"k8s.io/controller-manager/controller"
    69  	"k8s.io/controller-manager/pkg/clientbuilder"
    70  	controllerhealthz "k8s.io/controller-manager/pkg/healthz"
    71  	"k8s.io/controller-manager/pkg/informerfactory"
    72  	"k8s.io/controller-manager/pkg/leadermigration"
    73  	"k8s.io/klog/v2"
    74  	"k8s.io/kubernetes/cmd/kube-controller-manager/app/config"
    75  	"k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
    76  	"k8s.io/kubernetes/cmd/kube-controller-manager/names"
    77  	kubectrlmgrconfig "k8s.io/kubernetes/pkg/controller/apis/config"
    78  	garbagecollector "k8s.io/kubernetes/pkg/controller/garbagecollector"
    79  	serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
    80  	"k8s.io/kubernetes/pkg/serviceaccount"
    81  )
    82  
    83  func init() {
    84  	utilruntime.Must(logsapi.AddFeatureGates(utilfeature.DefaultMutableFeatureGate))
    85  	utilruntime.Must(metricsfeatures.AddFeatureGates(utilfeature.DefaultMutableFeatureGate))
    86  }
    87  
    88  const (
    89  	// ControllerStartJitter is the Jitter used when starting controller managers
    90  	ControllerStartJitter = 1.0
    91  	// ConfigzName is the name used for register kube-controller manager /configz, same with GroupName.
    92  	ConfigzName = "kubecontrollermanager.config.k8s.io"
    93  )
    94  
    95  // ControllerLoopMode is the kube-controller-manager's mode of running controller loops that are cloud provider dependent
    96  type ControllerLoopMode int
    97  
    98  const (
    99  	// IncludeCloudLoops means the kube-controller-manager include the controller loops that are cloud provider dependent
   100  	IncludeCloudLoops ControllerLoopMode = iota
   101  	// ExternalLoops means the kube-controller-manager exclude the controller loops that are cloud provider dependent
   102  	ExternalLoops
   103  )
   104  
   105  // NewControllerManagerCommand creates a *cobra.Command object with default parameters
   106  func NewControllerManagerCommand() *cobra.Command {
   107  	s, err := options.NewKubeControllerManagerOptions()
   108  	if err != nil {
   109  		klog.Background().Error(err, "Unable to initialize command options")
   110  		klog.FlushAndExit(klog.ExitFlushTimeout, 1)
   111  	}
   112  
   113  	cmd := &cobra.Command{
   114  		Use: "kube-controller-manager",
   115  		Long: `The Kubernetes controller manager is a daemon that embeds
   116  the core control loops shipped with Kubernetes. In applications of robotics and
   117  automation, a control loop is a non-terminating loop that regulates the state of
   118  the system. In Kubernetes, a controller is a control loop that watches the shared
   119  state of the cluster through the apiserver and makes changes attempting to move the
   120  current state towards the desired state. Examples of controllers that ship with
   121  Kubernetes today are the replication controller, endpoints controller, namespace
   122  controller, and serviceaccounts controller.`,
   123  		PersistentPreRunE: func(*cobra.Command, []string) error {
   124  			// silence client-go warnings.
   125  			// kube-controller-manager generically watches APIs (including deprecated ones),
   126  			// and CI ensures it works properly against matching kube-apiserver versions.
   127  			restclient.SetDefaultWarningHandler(restclient.NoWarnings{})
   128  			return nil
   129  		},
   130  		RunE: func(cmd *cobra.Command, args []string) error {
   131  			verflag.PrintAndExitIfRequested()
   132  
   133  			// Activate logging as soon as possible, after that
   134  			// show flags with the final logging configuration.
   135  			if err := logsapi.ValidateAndApply(s.Logs, utilfeature.DefaultFeatureGate); err != nil {
   136  				return err
   137  			}
   138  			cliflag.PrintFlags(cmd.Flags())
   139  
   140  			c, err := s.Config(KnownControllers(), ControllersDisabledByDefault(), ControllerAliases())
   141  			if err != nil {
   142  				return err
   143  			}
   144  			// add feature enablement metrics
   145  			utilfeature.DefaultMutableFeatureGate.AddMetrics()
   146  			return Run(context.Background(), c.Complete())
   147  		},
   148  		Args: func(cmd *cobra.Command, args []string) error {
   149  			for _, arg := range args {
   150  				if len(arg) > 0 {
   151  					return fmt.Errorf("%q does not take any arguments, got %q", cmd.CommandPath(), args)
   152  				}
   153  			}
   154  			return nil
   155  		},
   156  	}
   157  
   158  	fs := cmd.Flags()
   159  	namedFlagSets := s.Flags(KnownControllers(), ControllersDisabledByDefault(), ControllerAliases())
   160  	verflag.AddFlags(namedFlagSets.FlagSet("global"))
   161  	globalflag.AddGlobalFlags(namedFlagSets.FlagSet("global"), cmd.Name(), logs.SkipLoggingConfigurationFlags())
   162  	for _, f := range namedFlagSets.FlagSets {
   163  		fs.AddFlagSet(f)
   164  	}
   165  
   166  	cols, _, _ := term.TerminalSize(cmd.OutOrStdout())
   167  	cliflag.SetUsageAndHelpFunc(cmd, namedFlagSets, cols)
   168  
   169  	return cmd
   170  }
   171  
   172  // ResyncPeriod returns a function which generates a duration each time it is
   173  // invoked; this is so that multiple controllers don't get into lock-step and all
   174  // hammer the apiserver with list requests simultaneously.
   175  func ResyncPeriod(c *config.CompletedConfig) func() time.Duration {
   176  	return func() time.Duration {
   177  		factor := rand.Float64() + 1
   178  		return time.Duration(float64(c.ComponentConfig.Generic.MinResyncPeriod.Nanoseconds()) * factor)
   179  	}
   180  }
   181  
   182  // Run runs the KubeControllerManagerOptions.
   183  func Run(ctx context.Context, c *config.CompletedConfig) error {
   184  	logger := klog.FromContext(ctx)
   185  	stopCh := ctx.Done()
   186  
   187  	// To help debugging, immediately log version
   188  	logger.Info("Starting", "version", version.Get())
   189  
   190  	logger.Info("Golang settings", "GOGC", os.Getenv("GOGC"), "GOMAXPROCS", os.Getenv("GOMAXPROCS"), "GOTRACEBACK", os.Getenv("GOTRACEBACK"))
   191  
   192  	// Start events processing pipeline.
   193  	c.EventBroadcaster.StartStructuredLogging(0)
   194  	c.EventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: c.Client.CoreV1().Events("")})
   195  	defer c.EventBroadcaster.Shutdown()
   196  
   197  	if cfgz, err := configz.New(ConfigzName); err == nil {
   198  		cfgz.Set(c.ComponentConfig)
   199  	} else {
   200  		logger.Error(err, "Unable to register configz")
   201  	}
   202  
   203  	// Setup any healthz checks we will want to use.
   204  	var checks []healthz.HealthChecker
   205  	var electionChecker *leaderelection.HealthzAdaptor
   206  	if c.ComponentConfig.Generic.LeaderElection.LeaderElect {
   207  		electionChecker = leaderelection.NewLeaderHealthzAdaptor(time.Second * 20)
   208  		checks = append(checks, electionChecker)
   209  	}
   210  	healthzHandler := controllerhealthz.NewMutableHealthzHandler(checks...)
   211  
   212  	// Start the controller manager HTTP server
   213  	// unsecuredMux is the handler for these controller *after* authn/authz filters have been applied
   214  	var unsecuredMux *mux.PathRecorderMux
   215  	if c.SecureServing != nil {
   216  		unsecuredMux = genericcontrollermanager.NewBaseHandler(&c.ComponentConfig.Generic.Debugging, healthzHandler)
   217  		slis.SLIMetricsWithReset{}.Install(unsecuredMux)
   218  
   219  		handler := genericcontrollermanager.BuildHandlerChain(unsecuredMux, &c.Authorization, &c.Authentication)
   220  		// TODO: handle stoppedCh and listenerStoppedCh returned by c.SecureServing.Serve
   221  		if _, _, err := c.SecureServing.Serve(handler, 0, stopCh); err != nil {
   222  			return err
   223  		}
   224  	}
   225  
   226  	clientBuilder, rootClientBuilder := createClientBuilders(logger, c)
   227  
   228  	saTokenControllerDescriptor := newServiceAccountTokenControllerDescriptor(rootClientBuilder)
   229  
   230  	run := func(ctx context.Context, controllerDescriptors map[string]*ControllerDescriptor) {
   231  		controllerContext, err := CreateControllerContext(ctx, c, rootClientBuilder, clientBuilder)
   232  		if err != nil {
   233  			logger.Error(err, "Error building controller context")
   234  			klog.FlushAndExit(klog.ExitFlushTimeout, 1)
   235  		}
   236  
   237  		if err := StartControllers(ctx, controllerContext, controllerDescriptors, unsecuredMux, healthzHandler); err != nil {
   238  			logger.Error(err, "Error starting controllers")
   239  			klog.FlushAndExit(klog.ExitFlushTimeout, 1)
   240  		}
   241  
   242  		controllerContext.InformerFactory.Start(stopCh)
   243  		controllerContext.ObjectOrMetadataInformerFactory.Start(stopCh)
   244  		close(controllerContext.InformersStarted)
   245  
   246  		<-ctx.Done()
   247  	}
   248  
   249  	// No leader election, run directly
   250  	if !c.ComponentConfig.Generic.LeaderElection.LeaderElect {
   251  		controllerDescriptors := NewControllerDescriptors()
   252  		controllerDescriptors[names.ServiceAccountTokenController] = saTokenControllerDescriptor
   253  		run(ctx, controllerDescriptors)
   254  		return nil
   255  	}
   256  
   257  	id, err := os.Hostname()
   258  	if err != nil {
   259  		return err
   260  	}
   261  
   262  	// add a uniquifier so that two processes on the same host don't accidentally both become active
   263  	id = id + "_" + string(uuid.NewUUID())
   264  
   265  	// leaderMigrator will be non-nil if and only if Leader Migration is enabled.
   266  	var leaderMigrator *leadermigration.LeaderMigrator = nil
   267  
   268  	// If leader migration is enabled, create the LeaderMigrator and prepare for migration
   269  	if leadermigration.Enabled(&c.ComponentConfig.Generic) {
   270  		logger.Info("starting leader migration")
   271  
   272  		leaderMigrator = leadermigration.NewLeaderMigrator(&c.ComponentConfig.Generic.LeaderMigration,
   273  			"kube-controller-manager")
   274  
   275  		// startSATokenControllerInit is the original InitFunc.
   276  		startSATokenControllerInit := saTokenControllerDescriptor.GetInitFunc()
   277  
   278  		// Wrap saTokenControllerDescriptor to signal readiness for migration after starting
   279  		//  the controller.
   280  		saTokenControllerDescriptor.initFunc = func(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
   281  			defer close(leaderMigrator.MigrationReady)
   282  			return startSATokenControllerInit(ctx, controllerContext, controllerName)
   283  		}
   284  	}
   285  
   286  	// Start the main lock
   287  	go leaderElectAndRun(ctx, c, id, electionChecker,
   288  		c.ComponentConfig.Generic.LeaderElection.ResourceLock,
   289  		c.ComponentConfig.Generic.LeaderElection.ResourceName,
   290  		leaderelection.LeaderCallbacks{
   291  			OnStartedLeading: func(ctx context.Context) {
   292  				controllerDescriptors := NewControllerDescriptors()
   293  				if leaderMigrator != nil {
   294  					// If leader migration is enabled, we should start only non-migrated controllers
   295  					//  for the main lock.
   296  					controllerDescriptors = filteredControllerDescriptors(controllerDescriptors, leaderMigrator.FilterFunc, leadermigration.ControllerNonMigrated)
   297  					logger.Info("leader migration: starting main controllers.")
   298  				}
   299  				controllerDescriptors[names.ServiceAccountTokenController] = saTokenControllerDescriptor
   300  				run(ctx, controllerDescriptors)
   301  			},
   302  			OnStoppedLeading: func() {
   303  				logger.Error(nil, "leaderelection lost")
   304  				klog.FlushAndExit(klog.ExitFlushTimeout, 1)
   305  			},
   306  		})
   307  
   308  	// If Leader Migration is enabled, proceed to attempt the migration lock.
   309  	if leaderMigrator != nil {
   310  		// Wait for Service Account Token Controller to start before acquiring the migration lock.
   311  		// At this point, the main lock must have already been acquired, or the KCM process already exited.
   312  		// We wait for the main lock before acquiring the migration lock to prevent the situation
   313  		//  where KCM instance A holds the main lock while KCM instance B holds the migration lock.
   314  		<-leaderMigrator.MigrationReady
   315  
   316  		// Start the migration lock.
   317  		go leaderElectAndRun(ctx, c, id, electionChecker,
   318  			c.ComponentConfig.Generic.LeaderMigration.ResourceLock,
   319  			c.ComponentConfig.Generic.LeaderMigration.LeaderName,
   320  			leaderelection.LeaderCallbacks{
   321  				OnStartedLeading: func(ctx context.Context) {
   322  					logger.Info("leader migration: starting migrated controllers.")
   323  					controllerDescriptors := NewControllerDescriptors()
   324  					controllerDescriptors = filteredControllerDescriptors(controllerDescriptors, leaderMigrator.FilterFunc, leadermigration.ControllerMigrated)
   325  					// DO NOT start saTokenController under migration lock
   326  					delete(controllerDescriptors, names.ServiceAccountTokenController)
   327  					run(ctx, controllerDescriptors)
   328  				},
   329  				OnStoppedLeading: func() {
   330  					logger.Error(nil, "migration leaderelection lost")
   331  					klog.FlushAndExit(klog.ExitFlushTimeout, 1)
   332  				},
   333  			})
   334  	}
   335  
   336  	<-stopCh
   337  	return nil
   338  }
   339  
   340  // ControllerContext defines the context object for controller
   341  type ControllerContext struct {
   342  	// ClientBuilder will provide a client for this controller to use
   343  	ClientBuilder clientbuilder.ControllerClientBuilder
   344  
   345  	// InformerFactory gives access to informers for the controller.
   346  	InformerFactory informers.SharedInformerFactory
   347  
   348  	// ObjectOrMetadataInformerFactory gives access to informers for typed resources
   349  	// and dynamic resources by their metadata. All generic controllers currently use
   350  	// object metadata - if a future controller needs access to the full object this
   351  	// would become GenericInformerFactory and take a dynamic client.
   352  	ObjectOrMetadataInformerFactory informerfactory.InformerFactory
   353  
   354  	// ComponentConfig provides access to init options for a given controller
   355  	ComponentConfig kubectrlmgrconfig.KubeControllerManagerConfiguration
   356  
   357  	// DeferredDiscoveryRESTMapper is a RESTMapper that will defer
   358  	// initialization of the RESTMapper until the first mapping is
   359  	// requested.
   360  	RESTMapper *restmapper.DeferredDiscoveryRESTMapper
   361  
   362  	// Cloud is the cloud provider interface for the controllers to use.
   363  	// It must be initialized and ready to use.
   364  	Cloud cloudprovider.Interface
   365  
   366  	// Control for which control loops to be run
   367  	// IncludeCloudLoops is for a kube-controller-manager running all loops
   368  	// ExternalLoops is for a kube-controller-manager running with a cloud-controller-manager
   369  	LoopMode ControllerLoopMode
   370  
   371  	// InformersStarted is closed after all of the controllers have been initialized and are running.  After this point it is safe,
   372  	// for an individual controller to start the shared informers. Before it is closed, they should not.
   373  	InformersStarted chan struct{}
   374  
   375  	// ResyncPeriod generates a duration each time it is invoked; this is so that
   376  	// multiple controllers don't get into lock-step and all hammer the apiserver
   377  	// with list requests simultaneously.
   378  	ResyncPeriod func() time.Duration
   379  
   380  	// ControllerManagerMetrics provides a proxy to set controller manager specific metrics.
   381  	ControllerManagerMetrics *controllersmetrics.ControllerManagerMetrics
   382  
   383  	// GraphBuilder gives an access to dependencyGraphBuilder which keeps tracks of resources in the cluster
   384  	GraphBuilder *garbagecollector.GraphBuilder
   385  }
   386  
   387  // IsControllerEnabled checks if the context's controllers enabled or not
   388  func (c ControllerContext) IsControllerEnabled(controllerDescriptor *ControllerDescriptor) bool {
   389  	controllersDisabledByDefault := sets.NewString()
   390  	if controllerDescriptor.IsDisabledByDefault() {
   391  		controllersDisabledByDefault.Insert(controllerDescriptor.Name())
   392  	}
   393  	return genericcontrollermanager.IsControllerEnabled(controllerDescriptor.Name(), controllersDisabledByDefault, c.ComponentConfig.Generic.Controllers)
   394  }
   395  
   396  // InitFunc is used to launch a particular controller. It returns a controller
   397  // that can optionally implement other interfaces so that the controller manager
   398  // can support the requested features.
   399  // The returned controller may be nil, which will be considered an anonymous controller
   400  // that requests no additional features from the controller manager.
   401  // Any error returned will cause the controller process to `Fatal`
   402  // The bool indicates whether the controller was enabled.
   403  type InitFunc func(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller controller.Interface, enabled bool, err error)
   404  
   405  type ControllerDescriptor struct {
   406  	name                      string
   407  	initFunc                  InitFunc
   408  	requiredFeatureGates      []featuregate.Feature
   409  	aliases                   []string
   410  	isDisabledByDefault       bool
   411  	isCloudProviderController bool
   412  	requiresSpecialHandling   bool
   413  }
   414  
   415  func (r *ControllerDescriptor) Name() string {
   416  	return r.name
   417  }
   418  
   419  func (r *ControllerDescriptor) GetInitFunc() InitFunc {
   420  	return r.initFunc
   421  }
   422  
   423  func (r *ControllerDescriptor) GetRequiredFeatureGates() []featuregate.Feature {
   424  	return append([]featuregate.Feature(nil), r.requiredFeatureGates...)
   425  }
   426  
   427  // GetAliases returns aliases to ensure backwards compatibility and should never be removed!
   428  // Only addition of new aliases is allowed, and only when a canonical name is changed (please see CHANGE POLICY of controller names)
   429  func (r *ControllerDescriptor) GetAliases() []string {
   430  	return append([]string(nil), r.aliases...)
   431  }
   432  
   433  func (r *ControllerDescriptor) IsDisabledByDefault() bool {
   434  	return r.isDisabledByDefault
   435  }
   436  
   437  func (r *ControllerDescriptor) IsCloudProviderController() bool {
   438  	return r.isCloudProviderController
   439  }
   440  
   441  // RequiresSpecialHandling should return true only in a special non-generic controllers like ServiceAccountTokenController
   442  func (r *ControllerDescriptor) RequiresSpecialHandling() bool {
   443  	return r.requiresSpecialHandling
   444  }
   445  
   446  // KnownControllers returns all known controllers's name
   447  func KnownControllers() []string {
   448  	return sets.StringKeySet(NewControllerDescriptors()).List()
   449  }
   450  
   451  // ControllerAliases returns a mapping of aliases to canonical controller names
   452  func ControllerAliases() map[string]string {
   453  	aliases := map[string]string{}
   454  	for name, c := range NewControllerDescriptors() {
   455  		for _, alias := range c.GetAliases() {
   456  			aliases[alias] = name
   457  		}
   458  	}
   459  	return aliases
   460  }
   461  
   462  func ControllersDisabledByDefault() []string {
   463  	var controllersDisabledByDefault []string
   464  
   465  	for name, c := range NewControllerDescriptors() {
   466  		if c.IsDisabledByDefault() {
   467  			controllersDisabledByDefault = append(controllersDisabledByDefault, name)
   468  		}
   469  	}
   470  
   471  	sort.Strings(controllersDisabledByDefault)
   472  
   473  	return controllersDisabledByDefault
   474  }
   475  
   476  // NewControllerDescriptors is a public map of named controller groups (you can start more than one in an init func)
   477  // paired to their ControllerDescriptor wrapper object that includes InitFunc.
   478  // This allows for structured downstream composition and subdivision.
   479  func NewControllerDescriptors() map[string]*ControllerDescriptor {
   480  	controllers := map[string]*ControllerDescriptor{}
   481  	aliases := sets.NewString()
   482  
   483  	// All the controllers must fulfil common constraints, or else we will explode.
   484  	register := func(controllerDesc *ControllerDescriptor) {
   485  		if controllerDesc == nil {
   486  			panic("received nil controller for a registration")
   487  		}
   488  		name := controllerDesc.Name()
   489  		if len(name) == 0 {
   490  			panic("received controller without a name for a registration")
   491  		}
   492  		if _, found := controllers[name]; found {
   493  			panic(fmt.Sprintf("controller name %q was registered twice", name))
   494  		}
   495  		if controllerDesc.GetInitFunc() == nil {
   496  			panic(fmt.Sprintf("controller %q does not have an init function", name))
   497  		}
   498  
   499  		for _, alias := range controllerDesc.GetAliases() {
   500  			if aliases.Has(alias) {
   501  				panic(fmt.Sprintf("controller %q has a duplicate alias %q", name, alias))
   502  			}
   503  			aliases.Insert(alias)
   504  		}
   505  
   506  		controllers[name] = controllerDesc
   507  	}
   508  
   509  	// First add "special" controllers that aren't initialized normally. These controllers cannot be initialized
   510  	// in the main controller loop initialization, so we add them here only for the metadata and duplication detection.
   511  	// app.ControllerDescriptor#RequiresSpecialHandling should return true for such controllers
   512  	// The only known special case is the ServiceAccountTokenController which *must* be started
   513  	// first to ensure that the SA tokens for future controllers will exist. Think very carefully before adding new
   514  	// special controllers.
   515  	register(newServiceAccountTokenControllerDescriptor(nil))
   516  
   517  	register(newEndpointsControllerDescriptor())
   518  	register(newEndpointSliceControllerDescriptor())
   519  	register(newEndpointSliceMirroringControllerDescriptor())
   520  	register(newReplicationControllerDescriptor())
   521  	register(newPodGarbageCollectorControllerDescriptor())
   522  	register(newResourceQuotaControllerDescriptor())
   523  	register(newNamespaceControllerDescriptor())
   524  	register(newServiceAccountControllerDescriptor())
   525  	register(newGarbageCollectorControllerDescriptor())
   526  	register(newDaemonSetControllerDescriptor())
   527  	register(newJobControllerDescriptor())
   528  	register(newDeploymentControllerDescriptor())
   529  	register(newReplicaSetControllerDescriptor())
   530  	register(newHorizontalPodAutoscalerControllerDescriptor())
   531  	register(newDisruptionControllerDescriptor())
   532  	register(newStatefulSetControllerDescriptor())
   533  	register(newCronJobControllerDescriptor())
   534  	register(newCertificateSigningRequestSigningControllerDescriptor())
   535  	register(newCertificateSigningRequestApprovingControllerDescriptor())
   536  	register(newCertificateSigningRequestCleanerControllerDescriptor())
   537  	register(newTTLControllerDescriptor())
   538  	register(newBootstrapSignerControllerDescriptor())
   539  	register(newTokenCleanerControllerDescriptor())
   540  	register(newNodeIpamControllerDescriptor())
   541  	register(newNodeLifecycleControllerDescriptor())
   542  
   543  	register(newServiceLBControllerDescriptor())          // cloud provider controller
   544  	register(newNodeRouteControllerDescriptor())          // cloud provider controller
   545  	register(newCloudNodeLifecycleControllerDescriptor()) // cloud provider controller
   546  	// TODO: persistent volume controllers into the IncludeCloudLoops only set as a cloud provider controller.
   547  
   548  	register(newPersistentVolumeBinderControllerDescriptor())
   549  	register(newPersistentVolumeAttachDetachControllerDescriptor())
   550  	register(newPersistentVolumeExpanderControllerDescriptor())
   551  	register(newClusterRoleAggregrationControllerDescriptor())
   552  	register(newPersistentVolumeClaimProtectionControllerDescriptor())
   553  	register(newPersistentVolumeProtectionControllerDescriptor())
   554  	register(newTTLAfterFinishedControllerDescriptor())
   555  	register(newRootCACertificatePublisherControllerDescriptor())
   556  	register(newEphemeralVolumeControllerDescriptor())
   557  
   558  	// feature gated
   559  	register(newStorageVersionGarbageCollectorControllerDescriptor())
   560  	register(newResourceClaimControllerDescriptor())
   561  	register(newLegacyServiceAccountTokenCleanerControllerDescriptor())
   562  	register(newValidatingAdmissionPolicyStatusControllerDescriptor())
   563  	register(newTaintEvictionControllerDescriptor())
   564  	register(newServiceCIDRsControllerDescriptor())
   565  	register(newStorageVersionMigratorControllerDescriptor())
   566  
   567  	for _, alias := range aliases.UnsortedList() {
   568  		if _, ok := controllers[alias]; ok {
   569  			panic(fmt.Sprintf("alias %q conflicts with a controller name", alias))
   570  		}
   571  	}
   572  
   573  	return controllers
   574  }
   575  
   576  // CreateControllerContext creates a context struct containing references to resources needed by the
   577  // controllers such as the cloud provider and clientBuilder. rootClientBuilder is only used for
   578  // the shared-informers client and token controller.
   579  func CreateControllerContext(ctx context.Context, s *config.CompletedConfig, rootClientBuilder, clientBuilder clientbuilder.ControllerClientBuilder) (ControllerContext, error) {
   580  	// Informer transform to trim ManagedFields for memory efficiency.
   581  	trim := func(obj interface{}) (interface{}, error) {
   582  		if accessor, err := meta.Accessor(obj); err == nil {
   583  			if accessor.GetManagedFields() != nil {
   584  				accessor.SetManagedFields(nil)
   585  			}
   586  		}
   587  		return obj, nil
   588  	}
   589  
   590  	versionedClient := rootClientBuilder.ClientOrDie("shared-informers")
   591  	sharedInformers := informers.NewSharedInformerFactoryWithOptions(versionedClient, ResyncPeriod(s)(), informers.WithTransform(trim))
   592  
   593  	metadataClient := metadata.NewForConfigOrDie(rootClientBuilder.ConfigOrDie("metadata-informers"))
   594  	metadataInformers := metadatainformer.NewSharedInformerFactoryWithOptions(metadataClient, ResyncPeriod(s)(), metadatainformer.WithTransform(trim))
   595  
   596  	// If apiserver is not running we should wait for some time and fail only then. This is particularly
   597  	// important when we start apiserver and controller manager at the same time.
   598  	if err := genericcontrollermanager.WaitForAPIServer(versionedClient, 10*time.Second); err != nil {
   599  		return ControllerContext{}, fmt.Errorf("failed to wait for apiserver being healthy: %v", err)
   600  	}
   601  
   602  	// Use a discovery client capable of being refreshed.
   603  	discoveryClient := rootClientBuilder.DiscoveryClientOrDie("controller-discovery")
   604  	cachedClient := cacheddiscovery.NewMemCacheClient(discoveryClient)
   605  	restMapper := restmapper.NewDeferredDiscoveryRESTMapper(cachedClient)
   606  	go wait.Until(func() {
   607  		restMapper.Reset()
   608  	}, 30*time.Second, ctx.Done())
   609  
   610  	cloud, loopMode, err := createCloudProvider(klog.FromContext(ctx), s.ComponentConfig.KubeCloudShared.CloudProvider.Name, s.ComponentConfig.KubeCloudShared.ExternalCloudVolumePlugin,
   611  		s.ComponentConfig.KubeCloudShared.CloudProvider.CloudConfigFile, s.ComponentConfig.KubeCloudShared.AllowUntaggedCloud, sharedInformers)
   612  	if err != nil {
   613  		return ControllerContext{}, err
   614  	}
   615  
   616  	controllerContext := ControllerContext{
   617  		ClientBuilder:                   clientBuilder,
   618  		InformerFactory:                 sharedInformers,
   619  		ObjectOrMetadataInformerFactory: informerfactory.NewInformerFactory(sharedInformers, metadataInformers),
   620  		ComponentConfig:                 s.ComponentConfig,
   621  		RESTMapper:                      restMapper,
   622  		Cloud:                           cloud,
   623  		LoopMode:                        loopMode,
   624  		InformersStarted:                make(chan struct{}),
   625  		ResyncPeriod:                    ResyncPeriod(s),
   626  		ControllerManagerMetrics:        controllersmetrics.NewControllerManagerMetrics("kube-controller-manager"),
   627  	}
   628  
   629  	if controllerContext.ComponentConfig.GarbageCollectorController.EnableGarbageCollector &&
   630  		controllerContext.IsControllerEnabled(NewControllerDescriptors()[names.GarbageCollectorController]) {
   631  		ignoredResources := make(map[schema.GroupResource]struct{})
   632  		for _, r := range controllerContext.ComponentConfig.GarbageCollectorController.GCIgnoredResources {
   633  			ignoredResources[schema.GroupResource{Group: r.Group, Resource: r.Resource}] = struct{}{}
   634  		}
   635  
   636  		controllerContext.GraphBuilder = garbagecollector.NewDependencyGraphBuilder(
   637  			ctx,
   638  			metadataClient,
   639  			controllerContext.RESTMapper,
   640  			ignoredResources,
   641  			controllerContext.ObjectOrMetadataInformerFactory,
   642  			controllerContext.InformersStarted,
   643  		)
   644  	}
   645  
   646  	controllersmetrics.Register()
   647  	return controllerContext, nil
   648  }
   649  
   650  // StartControllers starts a set of controllers with a specified ControllerContext
   651  func StartControllers(ctx context.Context, controllerCtx ControllerContext, controllerDescriptors map[string]*ControllerDescriptor,
   652  	unsecuredMux *mux.PathRecorderMux, healthzHandler *controllerhealthz.MutableHealthzHandler) error {
   653  	var controllerChecks []healthz.HealthChecker
   654  
   655  	// Always start the SA token controller first using a full-power client, since it needs to mint tokens for the rest
   656  	// If this fails, just return here and fail since other controllers won't be able to get credentials.
   657  	if serviceAccountTokenControllerDescriptor, ok := controllerDescriptors[names.ServiceAccountTokenController]; ok {
   658  		check, err := StartController(ctx, controllerCtx, serviceAccountTokenControllerDescriptor, unsecuredMux)
   659  		if err != nil {
   660  			return err
   661  		}
   662  		if check != nil {
   663  			// HealthChecker should be present when controller has started
   664  			controllerChecks = append(controllerChecks, check)
   665  		}
   666  	}
   667  
   668  	// Initialize the cloud provider with a reference to the clientBuilder only after token controller
   669  	// has started in case the cloud provider uses the client builder.
   670  	if controllerCtx.Cloud != nil {
   671  		controllerCtx.Cloud.Initialize(controllerCtx.ClientBuilder, ctx.Done())
   672  	}
   673  
   674  	// Each controller is passed a context where the logger has the name of
   675  	// the controller set through WithName. That name then becomes the prefix of
   676  	// of all log messages emitted by that controller.
   677  	//
   678  	// In StartController, an explicit "controller" key is used instead, for two reasons:
   679  	// - while contextual logging is alpha, klog.LoggerWithName is still a no-op,
   680  	//   so we cannot rely on it yet to add the name
   681  	// - it allows distinguishing between log entries emitted by the controller
   682  	//   and those emitted for it - this is a bit debatable and could be revised.
   683  	for _, controllerDesc := range controllerDescriptors {
   684  		if controllerDesc.RequiresSpecialHandling() {
   685  			continue
   686  		}
   687  
   688  		check, err := StartController(ctx, controllerCtx, controllerDesc, unsecuredMux)
   689  		if err != nil {
   690  			return err
   691  		}
   692  		if check != nil {
   693  			// HealthChecker should be present when controller has started
   694  			controllerChecks = append(controllerChecks, check)
   695  		}
   696  	}
   697  
   698  	healthzHandler.AddHealthChecker(controllerChecks...)
   699  
   700  	return nil
   701  }
   702  
   703  // StartController starts a controller with a specified ControllerContext
   704  // and performs required pre- and post- checks/actions
   705  func StartController(ctx context.Context, controllerCtx ControllerContext, controllerDescriptor *ControllerDescriptor,
   706  	unsecuredMux *mux.PathRecorderMux) (healthz.HealthChecker, error) {
   707  	logger := klog.FromContext(ctx)
   708  	controllerName := controllerDescriptor.Name()
   709  
   710  	for _, featureGate := range controllerDescriptor.GetRequiredFeatureGates() {
   711  		if !utilfeature.DefaultFeatureGate.Enabled(featureGate) {
   712  			logger.Info("Controller is disabled by a feature gate", "controller", controllerName, "requiredFeatureGates", controllerDescriptor.GetRequiredFeatureGates())
   713  			return nil, nil
   714  		}
   715  	}
   716  
   717  	if controllerDescriptor.IsCloudProviderController() && controllerCtx.LoopMode != IncludeCloudLoops {
   718  		logger.Info("Skipping a cloud provider controller", "controller", controllerName, "loopMode", controllerCtx.LoopMode)
   719  		return nil, nil
   720  	}
   721  
   722  	if !controllerCtx.IsControllerEnabled(controllerDescriptor) {
   723  		logger.Info("Warning: controller is disabled", "controller", controllerName)
   724  		return nil, nil
   725  	}
   726  
   727  	time.Sleep(wait.Jitter(controllerCtx.ComponentConfig.Generic.ControllerStartInterval.Duration, ControllerStartJitter))
   728  
   729  	logger.V(1).Info("Starting controller", "controller", controllerName)
   730  
   731  	initFunc := controllerDescriptor.GetInitFunc()
   732  	ctrl, started, err := initFunc(klog.NewContext(ctx, klog.LoggerWithName(logger, controllerName)), controllerCtx, controllerName)
   733  	if err != nil {
   734  		logger.Error(err, "Error starting controller", "controller", controllerName)
   735  		return nil, err
   736  	}
   737  	if !started {
   738  		logger.Info("Warning: skipping controller", "controller", controllerName)
   739  		return nil, nil
   740  	}
   741  
   742  	check := controllerhealthz.NamedPingChecker(controllerName)
   743  	if ctrl != nil {
   744  		// check if the controller supports and requests a debugHandler
   745  		// and it needs the unsecuredMux to mount the handler onto.
   746  		if debuggable, ok := ctrl.(controller.Debuggable); ok && unsecuredMux != nil {
   747  			if debugHandler := debuggable.DebuggingHandler(); debugHandler != nil {
   748  				basePath := "/debug/controllers/" + controllerName
   749  				unsecuredMux.UnlistedHandle(basePath, http.StripPrefix(basePath, debugHandler))
   750  				unsecuredMux.UnlistedHandlePrefix(basePath+"/", http.StripPrefix(basePath, debugHandler))
   751  			}
   752  		}
   753  		if healthCheckable, ok := ctrl.(controller.HealthCheckable); ok {
   754  			if realCheck := healthCheckable.HealthChecker(); realCheck != nil {
   755  				check = controllerhealthz.NamedHealthChecker(controllerName, realCheck)
   756  			}
   757  		}
   758  	}
   759  
   760  	logger.Info("Started controller", "controller", controllerName)
   761  	return check, nil
   762  }
   763  
   764  // serviceAccountTokenControllerStarter is special because it must run first to set up permissions for other controllers.
   765  // It cannot use the "normal" client builder, so it tracks its own.
   766  func newServiceAccountTokenControllerDescriptor(rootClientBuilder clientbuilder.ControllerClientBuilder) *ControllerDescriptor {
   767  	return &ControllerDescriptor{
   768  		name:    names.ServiceAccountTokenController,
   769  		aliases: []string{"serviceaccount-token"},
   770  		initFunc: func(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
   771  			return startServiceAccountTokenController(ctx, controllerContext, controllerName, rootClientBuilder)
   772  		},
   773  		// will make sure it runs first before other controllers
   774  		requiresSpecialHandling: true,
   775  	}
   776  }
   777  
   778  func startServiceAccountTokenController(ctx context.Context, controllerContext ControllerContext, controllerName string, rootClientBuilder clientbuilder.ControllerClientBuilder) (controller.Interface, bool, error) {
   779  	logger := klog.FromContext(ctx)
   780  	if len(controllerContext.ComponentConfig.SAController.ServiceAccountKeyFile) == 0 {
   781  		logger.Info("Controller is disabled because there is no private key", "controller", controllerName)
   782  		return nil, false, nil
   783  	}
   784  	privateKey, err := keyutil.PrivateKeyFromFile(controllerContext.ComponentConfig.SAController.ServiceAccountKeyFile)
   785  	if err != nil {
   786  		return nil, true, fmt.Errorf("error reading key for service account token controller: %v", err)
   787  	}
   788  
   789  	var rootCA []byte
   790  	if controllerContext.ComponentConfig.SAController.RootCAFile != "" {
   791  		if rootCA, err = readCA(controllerContext.ComponentConfig.SAController.RootCAFile); err != nil {
   792  			return nil, true, fmt.Errorf("error parsing root-ca-file at %s: %v", controllerContext.ComponentConfig.SAController.RootCAFile, err)
   793  		}
   794  	} else {
   795  		rootCA = rootClientBuilder.ConfigOrDie("tokens-controller").CAData
   796  	}
   797  
   798  	tokenGenerator, err := serviceaccount.JWTTokenGenerator(serviceaccount.LegacyIssuer, privateKey)
   799  	if err != nil {
   800  		return nil, false, fmt.Errorf("failed to build token generator: %v", err)
   801  	}
   802  	tokenController, err := serviceaccountcontroller.NewTokensController(
   803  		controllerContext.InformerFactory.Core().V1().ServiceAccounts(),
   804  		controllerContext.InformerFactory.Core().V1().Secrets(),
   805  		rootClientBuilder.ClientOrDie("tokens-controller"),
   806  		serviceaccountcontroller.TokensControllerOptions{
   807  			TokenGenerator: tokenGenerator,
   808  			RootCA:         rootCA,
   809  		},
   810  	)
   811  	if err != nil {
   812  		return nil, true, fmt.Errorf("error creating Tokens controller: %v", err)
   813  	}
   814  	go tokenController.Run(ctx, int(controllerContext.ComponentConfig.SAController.ConcurrentSATokenSyncs))
   815  
   816  	// start the first set of informers now so that other controllers can start
   817  	controllerContext.InformerFactory.Start(ctx.Done())
   818  
   819  	return nil, true, nil
   820  }
   821  
   822  func readCA(file string) ([]byte, error) {
   823  	rootCA, err := os.ReadFile(file)
   824  	if err != nil {
   825  		return nil, err
   826  	}
   827  	if _, err := certutil.ParseCertsPEM(rootCA); err != nil {
   828  		return nil, err
   829  	}
   830  
   831  	return rootCA, err
   832  }
   833  
   834  // createClientBuilders creates clientBuilder and rootClientBuilder from the given configuration
   835  func createClientBuilders(logger klog.Logger, c *config.CompletedConfig) (clientBuilder clientbuilder.ControllerClientBuilder, rootClientBuilder clientbuilder.ControllerClientBuilder) {
   836  	rootClientBuilder = clientbuilder.SimpleControllerClientBuilder{
   837  		ClientConfig: c.Kubeconfig,
   838  	}
   839  	if c.ComponentConfig.KubeCloudShared.UseServiceAccountCredentials {
   840  		if len(c.ComponentConfig.SAController.ServiceAccountKeyFile) == 0 {
   841  			// It's possible another controller process is creating the tokens for us.
   842  			// If one isn't, we'll timeout and exit when our client builder is unable to create the tokens.
   843  			logger.Info("Warning: --use-service-account-credentials was specified without providing a --service-account-private-key-file")
   844  		}
   845  
   846  		clientBuilder = clientbuilder.NewDynamicClientBuilder(
   847  			restclient.AnonymousClientConfig(c.Kubeconfig),
   848  			c.Client.CoreV1(),
   849  			metav1.NamespaceSystem)
   850  	} else {
   851  		clientBuilder = rootClientBuilder
   852  	}
   853  	return
   854  }
   855  
   856  // leaderElectAndRun runs the leader election, and runs the callbacks once the leader lease is acquired.
   857  // TODO: extract this function into staging/controller-manager
   858  func leaderElectAndRun(ctx context.Context, c *config.CompletedConfig, lockIdentity string, electionChecker *leaderelection.HealthzAdaptor, resourceLock string, leaseName string, callbacks leaderelection.LeaderCallbacks) {
   859  	logger := klog.FromContext(ctx)
   860  	rl, err := resourcelock.NewFromKubeconfig(resourceLock,
   861  		c.ComponentConfig.Generic.LeaderElection.ResourceNamespace,
   862  		leaseName,
   863  		resourcelock.ResourceLockConfig{
   864  			Identity:      lockIdentity,
   865  			EventRecorder: c.EventRecorder,
   866  		},
   867  		c.Kubeconfig,
   868  		c.ComponentConfig.Generic.LeaderElection.RenewDeadline.Duration)
   869  	if err != nil {
   870  		logger.Error(err, "Error creating lock")
   871  		klog.FlushAndExit(klog.ExitFlushTimeout, 1)
   872  	}
   873  
   874  	leaderelection.RunOrDie(ctx, leaderelection.LeaderElectionConfig{
   875  		Lock:          rl,
   876  		LeaseDuration: c.ComponentConfig.Generic.LeaderElection.LeaseDuration.Duration,
   877  		RenewDeadline: c.ComponentConfig.Generic.LeaderElection.RenewDeadline.Duration,
   878  		RetryPeriod:   c.ComponentConfig.Generic.LeaderElection.RetryPeriod.Duration,
   879  		Callbacks:     callbacks,
   880  		WatchDog:      electionChecker,
   881  		Name:          leaseName,
   882  	})
   883  
   884  	panic("unreachable")
   885  }
   886  
   887  // filteredControllerDescriptors returns all controllerDescriptors after filtering through filterFunc.
   888  func filteredControllerDescriptors(controllerDescriptors map[string]*ControllerDescriptor, filterFunc leadermigration.FilterFunc, expected leadermigration.FilterResult) map[string]*ControllerDescriptor {
   889  	resultControllers := make(map[string]*ControllerDescriptor)
   890  	for name, controllerDesc := range controllerDescriptors {
   891  		if filterFunc(name) == expected {
   892  			resultControllers[name] = controllerDesc
   893  		}
   894  	}
   895  	return resultControllers
   896  }