k8s.io/kubernetes@v1.29.3/pkg/controlplane/instance.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 controlplane
    18  
    19  import (
    20  	"fmt"
    21  	"net"
    22  	"net/http"
    23  	"os"
    24  	"reflect"
    25  	"strconv"
    26  	"time"
    27  
    28  	admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
    29  	admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1"
    30  	admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
    31  	apiserverinternalv1alpha1 "k8s.io/api/apiserverinternal/v1alpha1"
    32  	appsv1 "k8s.io/api/apps/v1"
    33  	authenticationv1 "k8s.io/api/authentication/v1"
    34  	authenticationv1alpha1 "k8s.io/api/authentication/v1alpha1"
    35  	authenticationv1beta1 "k8s.io/api/authentication/v1beta1"
    36  	authorizationapiv1 "k8s.io/api/authorization/v1"
    37  	autoscalingapiv1 "k8s.io/api/autoscaling/v1"
    38  	autoscalingapiv2 "k8s.io/api/autoscaling/v2"
    39  	batchapiv1 "k8s.io/api/batch/v1"
    40  	certificatesapiv1 "k8s.io/api/certificates/v1"
    41  	certificatesv1alpha1 "k8s.io/api/certificates/v1alpha1"
    42  	coordinationapiv1 "k8s.io/api/coordination/v1"
    43  	apiv1 "k8s.io/api/core/v1"
    44  	discoveryv1 "k8s.io/api/discovery/v1"
    45  	eventsv1 "k8s.io/api/events/v1"
    46  	networkingapiv1 "k8s.io/api/networking/v1"
    47  	networkingapiv1alpha1 "k8s.io/api/networking/v1alpha1"
    48  	nodev1 "k8s.io/api/node/v1"
    49  	policyapiv1 "k8s.io/api/policy/v1"
    50  	rbacv1 "k8s.io/api/rbac/v1"
    51  	resourcev1alpha2 "k8s.io/api/resource/v1alpha2"
    52  	schedulingapiv1 "k8s.io/api/scheduling/v1"
    53  	storageapiv1 "k8s.io/api/storage/v1"
    54  	storageapiv1alpha1 "k8s.io/api/storage/v1alpha1"
    55  	storageapiv1beta1 "k8s.io/api/storage/v1beta1"
    56  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    57  	"k8s.io/apimachinery/pkg/runtime/schema"
    58  	utilnet "k8s.io/apimachinery/pkg/util/net"
    59  	"k8s.io/apimachinery/pkg/util/runtime"
    60  	"k8s.io/apimachinery/pkg/util/uuid"
    61  	"k8s.io/apimachinery/pkg/util/wait"
    62  	"k8s.io/apiserver/pkg/endpoints/discovery"
    63  	apiserverfeatures "k8s.io/apiserver/pkg/features"
    64  	peerreconcilers "k8s.io/apiserver/pkg/reconcilers"
    65  	"k8s.io/apiserver/pkg/registry/generic"
    66  	genericapiserver "k8s.io/apiserver/pkg/server"
    67  	"k8s.io/apiserver/pkg/server/dynamiccertificates"
    68  	serverstorage "k8s.io/apiserver/pkg/server/storage"
    69  	utilfeature "k8s.io/apiserver/pkg/util/feature"
    70  	utilpeerproxy "k8s.io/apiserver/pkg/util/peerproxy"
    71  	"k8s.io/client-go/informers"
    72  	"k8s.io/client-go/kubernetes"
    73  	corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
    74  	discoveryclient "k8s.io/client-go/kubernetes/typed/discovery/v1"
    75  	"k8s.io/component-helpers/apimachinery/lease"
    76  	"k8s.io/klog/v2"
    77  	api "k8s.io/kubernetes/pkg/apis/core"
    78  	flowcontrolv1 "k8s.io/kubernetes/pkg/apis/flowcontrol/v1"
    79  	flowcontrolv1beta1 "k8s.io/kubernetes/pkg/apis/flowcontrol/v1beta1"
    80  	flowcontrolv1beta2 "k8s.io/kubernetes/pkg/apis/flowcontrol/v1beta2"
    81  	flowcontrolv1beta3 "k8s.io/kubernetes/pkg/apis/flowcontrol/v1beta3"
    82  	"k8s.io/kubernetes/pkg/controlplane/apiserver/options"
    83  	"k8s.io/kubernetes/pkg/controlplane/controller/apiserverleasegc"
    84  	"k8s.io/kubernetes/pkg/controlplane/controller/clusterauthenticationtrust"
    85  	"k8s.io/kubernetes/pkg/controlplane/controller/defaultservicecidr"
    86  	"k8s.io/kubernetes/pkg/controlplane/controller/kubernetesservice"
    87  	"k8s.io/kubernetes/pkg/controlplane/controller/legacytokentracking"
    88  	"k8s.io/kubernetes/pkg/controlplane/controller/systemnamespaces"
    89  	"k8s.io/kubernetes/pkg/controlplane/reconcilers"
    90  	"k8s.io/kubernetes/pkg/features"
    91  	kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
    92  	kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
    93  	"k8s.io/kubernetes/pkg/routes"
    94  	"k8s.io/kubernetes/pkg/serviceaccount"
    95  	"k8s.io/utils/clock"
    96  
    97  	// RESTStorage installers
    98  	admissionregistrationrest "k8s.io/kubernetes/pkg/registry/admissionregistration/rest"
    99  	apiserverinternalrest "k8s.io/kubernetes/pkg/registry/apiserverinternal/rest"
   100  	appsrest "k8s.io/kubernetes/pkg/registry/apps/rest"
   101  	authenticationrest "k8s.io/kubernetes/pkg/registry/authentication/rest"
   102  	authorizationrest "k8s.io/kubernetes/pkg/registry/authorization/rest"
   103  	autoscalingrest "k8s.io/kubernetes/pkg/registry/autoscaling/rest"
   104  	batchrest "k8s.io/kubernetes/pkg/registry/batch/rest"
   105  	certificatesrest "k8s.io/kubernetes/pkg/registry/certificates/rest"
   106  	coordinationrest "k8s.io/kubernetes/pkg/registry/coordination/rest"
   107  	corerest "k8s.io/kubernetes/pkg/registry/core/rest"
   108  	discoveryrest "k8s.io/kubernetes/pkg/registry/discovery/rest"
   109  	eventsrest "k8s.io/kubernetes/pkg/registry/events/rest"
   110  	flowcontrolrest "k8s.io/kubernetes/pkg/registry/flowcontrol/rest"
   111  	networkingrest "k8s.io/kubernetes/pkg/registry/networking/rest"
   112  	noderest "k8s.io/kubernetes/pkg/registry/node/rest"
   113  	policyrest "k8s.io/kubernetes/pkg/registry/policy/rest"
   114  	rbacrest "k8s.io/kubernetes/pkg/registry/rbac/rest"
   115  	resourcerest "k8s.io/kubernetes/pkg/registry/resource/rest"
   116  	schedulingrest "k8s.io/kubernetes/pkg/registry/scheduling/rest"
   117  	storagerest "k8s.io/kubernetes/pkg/registry/storage/rest"
   118  )
   119  
   120  const (
   121  	// DefaultEndpointReconcilerInterval is the default amount of time for how often the endpoints for
   122  	// the kubernetes Service are reconciled.
   123  	DefaultEndpointReconcilerInterval = 10 * time.Second
   124  	// DefaultEndpointReconcilerTTL is the default TTL timeout for the storage layer
   125  	DefaultEndpointReconcilerTTL = 15 * time.Second
   126  	// IdentityLeaseComponentLabelKey is used to apply a component label to identity lease objects, indicating:
   127  	//   1. the lease is an identity lease (different from leader election leases)
   128  	//   2. which component owns this lease
   129  	IdentityLeaseComponentLabelKey = "apiserver.kubernetes.io/identity"
   130  	// KubeAPIServer defines variable used internally when referring to kube-apiserver component
   131  	KubeAPIServer = "kube-apiserver"
   132  	// KubeAPIServerIdentityLeaseLabelSelector selects kube-apiserver identity leases
   133  	KubeAPIServerIdentityLeaseLabelSelector = IdentityLeaseComponentLabelKey + "=" + KubeAPIServer
   134  	// repairLoopInterval defines the interval used to run the Services ClusterIP and NodePort repair loops
   135  	repairLoopInterval = 3 * time.Minute
   136  )
   137  
   138  var (
   139  	// IdentityLeaseGCPeriod is the interval which the lease GC controller checks for expired leases
   140  	// IdentityLeaseGCPeriod is exposed so integration tests can tune this value.
   141  	IdentityLeaseGCPeriod = 3600 * time.Second
   142  	// IdentityLeaseDurationSeconds is the duration of kube-apiserver lease in seconds
   143  	// IdentityLeaseDurationSeconds is exposed so integration tests can tune this value.
   144  	IdentityLeaseDurationSeconds = 3600
   145  	// IdentityLeaseRenewIntervalSeconds is the interval of kube-apiserver renewing its lease in seconds
   146  	// IdentityLeaseRenewIntervalSeconds is exposed so integration tests can tune this value.
   147  	IdentityLeaseRenewIntervalPeriod = 10 * time.Second
   148  )
   149  
   150  // ExtraConfig defines extra configuration for the master
   151  type ExtraConfig struct {
   152  	ClusterAuthenticationInfo clusterauthenticationtrust.ClusterAuthenticationInfo
   153  
   154  	APIResourceConfigSource  serverstorage.APIResourceConfigSource
   155  	StorageFactory           serverstorage.StorageFactory
   156  	EndpointReconcilerConfig EndpointReconcilerConfig
   157  	EventTTL                 time.Duration
   158  	KubeletClientConfig      kubeletclient.KubeletClientConfig
   159  
   160  	EnableLogsSupport bool
   161  	ProxyTransport    *http.Transport
   162  
   163  	// PeerProxy, if not nil, sets proxy transport between kube-apiserver peers for requests
   164  	// that can not be served locally
   165  	PeerProxy utilpeerproxy.Interface
   166  
   167  	// PeerEndpointLeaseReconciler updates the peer endpoint leases
   168  	PeerEndpointLeaseReconciler peerreconcilers.PeerEndpointLeaseReconciler
   169  
   170  	// PeerCAFile is the ca bundle used by this kube-apiserver to verify peer apiservers'
   171  	// serving certs when routing a request to the peer in the case the request can not be served
   172  	// locally due to version skew.
   173  	PeerCAFile string
   174  
   175  	// PeerAdvertiseAddress is the IP for this kube-apiserver which is used by peer apiservers to route a request
   176  	// to this apiserver. This happens in cases where the peer is not able to serve the request due to
   177  	// version skew. If unset, AdvertiseAddress/BindAddress will be used.
   178  	PeerAdvertiseAddress peerreconcilers.PeerAdvertiseAddress
   179  
   180  	// Values to build the IP addresses used by discovery
   181  	// The range of IPs to be assigned to services with type=ClusterIP or greater
   182  	ServiceIPRange net.IPNet
   183  	// The IP address for the GenericAPIServer service (must be inside ServiceIPRange)
   184  	APIServerServiceIP net.IP
   185  
   186  	// dual stack services, the range represents an alternative IP range for service IP
   187  	// must be of different family than primary (ServiceIPRange)
   188  	SecondaryServiceIPRange net.IPNet
   189  	// the secondary IP address the GenericAPIServer service (must be inside SecondaryServiceIPRange)
   190  	SecondaryAPIServerServiceIP net.IP
   191  
   192  	// Port for the apiserver service.
   193  	APIServerServicePort int
   194  
   195  	// TODO, we can probably group service related items into a substruct to make it easier to configure
   196  	// the API server items and `Extra*` fields likely fit nicely together.
   197  
   198  	// The range of ports to be assigned to services with type=NodePort or greater
   199  	ServiceNodePortRange utilnet.PortRange
   200  	// If non-zero, the "kubernetes" services uses this port as NodePort.
   201  	KubernetesServiceNodePort int
   202  
   203  	// Number of masters running; all masters must be started with the
   204  	// same value for this field. (Numbers > 1 currently untested.)
   205  	MasterCount int
   206  
   207  	// MasterEndpointReconcileTTL sets the time to live in seconds of an
   208  	// endpoint record recorded by each master. The endpoints are checked at an
   209  	// interval that is 2/3 of this value and this value defaults to 15s if
   210  	// unset. In very large clusters, this value may be increased to reduce the
   211  	// possibility that the master endpoint record expires (due to other load
   212  	// on the etcd server) and causes masters to drop in and out of the
   213  	// kubernetes service record. It is not recommended to set this value below
   214  	// 15s.
   215  	MasterEndpointReconcileTTL time.Duration
   216  
   217  	// Selects which reconciler to use
   218  	EndpointReconcilerType reconcilers.Type
   219  
   220  	ServiceAccountIssuer        serviceaccount.TokenGenerator
   221  	ServiceAccountMaxExpiration time.Duration
   222  	ExtendExpiration            bool
   223  
   224  	// ServiceAccountIssuerDiscovery
   225  	ServiceAccountIssuerURL  string
   226  	ServiceAccountJWKSURI    string
   227  	ServiceAccountPublicKeys []interface{}
   228  
   229  	VersionedInformers informers.SharedInformerFactory
   230  
   231  	// RepairServicesInterval interval used by the repair loops for
   232  	// the Services NodePort and ClusterIP resources
   233  	RepairServicesInterval time.Duration
   234  }
   235  
   236  // Config defines configuration for the master
   237  type Config struct {
   238  	GenericConfig *genericapiserver.Config
   239  	ExtraConfig   ExtraConfig
   240  }
   241  
   242  type completedConfig struct {
   243  	GenericConfig genericapiserver.CompletedConfig
   244  	ExtraConfig   *ExtraConfig
   245  }
   246  
   247  // CompletedConfig embeds a private pointer that cannot be instantiated outside of this package
   248  type CompletedConfig struct {
   249  	*completedConfig
   250  }
   251  
   252  // EndpointReconcilerConfig holds the endpoint reconciler and endpoint reconciliation interval to be
   253  // used by the master.
   254  type EndpointReconcilerConfig struct {
   255  	Reconciler reconcilers.EndpointReconciler
   256  	Interval   time.Duration
   257  }
   258  
   259  // Instance contains state for a Kubernetes cluster api server instance.
   260  type Instance struct {
   261  	GenericAPIServer *genericapiserver.GenericAPIServer
   262  
   263  	ClusterAuthenticationInfo clusterauthenticationtrust.ClusterAuthenticationInfo
   264  }
   265  
   266  func (c *Config) createMasterCountReconciler() reconcilers.EndpointReconciler {
   267  	endpointClient := corev1client.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig)
   268  	endpointSliceClient := discoveryclient.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig)
   269  	endpointsAdapter := reconcilers.NewEndpointsAdapter(endpointClient, endpointSliceClient)
   270  
   271  	return reconcilers.NewMasterCountEndpointReconciler(c.ExtraConfig.MasterCount, endpointsAdapter)
   272  }
   273  
   274  func (c *Config) createNoneReconciler() reconcilers.EndpointReconciler {
   275  	return reconcilers.NewNoneEndpointReconciler()
   276  }
   277  
   278  func (c *Config) createLeaseReconciler() reconcilers.EndpointReconciler {
   279  	endpointClient := corev1client.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig)
   280  	endpointSliceClient := discoveryclient.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig)
   281  	endpointsAdapter := reconcilers.NewEndpointsAdapter(endpointClient, endpointSliceClient)
   282  
   283  	ttl := c.ExtraConfig.MasterEndpointReconcileTTL
   284  	config, err := c.ExtraConfig.StorageFactory.NewConfig(api.Resource("apiServerIPInfo"))
   285  	if err != nil {
   286  		klog.Fatalf("Error creating storage factory config: %v", err)
   287  	}
   288  	masterLeases, err := reconcilers.NewLeases(config, "/masterleases/", ttl)
   289  	if err != nil {
   290  		klog.Fatalf("Error creating leases: %v", err)
   291  	}
   292  
   293  	return reconcilers.NewLeaseEndpointReconciler(endpointsAdapter, masterLeases)
   294  }
   295  
   296  func (c *Config) createEndpointReconciler() reconcilers.EndpointReconciler {
   297  	klog.Infof("Using reconciler: %v", c.ExtraConfig.EndpointReconcilerType)
   298  	switch c.ExtraConfig.EndpointReconcilerType {
   299  	// there are numerous test dependencies that depend on a default controller
   300  	case reconcilers.MasterCountReconcilerType:
   301  		return c.createMasterCountReconciler()
   302  	case "", reconcilers.LeaseEndpointReconcilerType:
   303  		return c.createLeaseReconciler()
   304  	case reconcilers.NoneEndpointReconcilerType:
   305  		return c.createNoneReconciler()
   306  	default:
   307  		klog.Fatalf("Reconciler not implemented: %v", c.ExtraConfig.EndpointReconcilerType)
   308  	}
   309  	return nil
   310  }
   311  
   312  // Complete fills in any fields not set that are required to have valid data. It's mutating the receiver.
   313  func (c *Config) Complete() CompletedConfig {
   314  	cfg := completedConfig{
   315  		c.GenericConfig.Complete(c.ExtraConfig.VersionedInformers),
   316  		&c.ExtraConfig,
   317  	}
   318  
   319  	serviceIPRange, apiServerServiceIP, err := options.ServiceIPRange(cfg.ExtraConfig.ServiceIPRange)
   320  	if err != nil {
   321  		klog.Fatalf("Error determining service IP ranges: %v", err)
   322  	}
   323  	if cfg.ExtraConfig.ServiceIPRange.IP == nil {
   324  		cfg.ExtraConfig.ServiceIPRange = serviceIPRange
   325  	}
   326  	if cfg.ExtraConfig.APIServerServiceIP == nil {
   327  		cfg.ExtraConfig.APIServerServiceIP = apiServerServiceIP
   328  	}
   329  
   330  	discoveryAddresses := discovery.DefaultAddresses{DefaultAddress: cfg.GenericConfig.ExternalAddress}
   331  	discoveryAddresses.CIDRRules = append(discoveryAddresses.CIDRRules,
   332  		discovery.CIDRRule{IPRange: cfg.ExtraConfig.ServiceIPRange, Address: net.JoinHostPort(cfg.ExtraConfig.APIServerServiceIP.String(), strconv.Itoa(cfg.ExtraConfig.APIServerServicePort))})
   333  	cfg.GenericConfig.DiscoveryAddresses = discoveryAddresses
   334  
   335  	if cfg.ExtraConfig.ServiceNodePortRange.Size == 0 {
   336  		// TODO: Currently no way to specify an empty range (do we need to allow this?)
   337  		// We should probably allow this for clouds that don't require NodePort to do load-balancing (GCE)
   338  		// but then that breaks the strict nestedness of ServiceType.
   339  		// Review post-v1
   340  		cfg.ExtraConfig.ServiceNodePortRange = kubeoptions.DefaultServiceNodePortRange
   341  		klog.Infof("Node port range unspecified. Defaulting to %v.", cfg.ExtraConfig.ServiceNodePortRange)
   342  	}
   343  
   344  	if cfg.ExtraConfig.EndpointReconcilerConfig.Interval == 0 {
   345  		cfg.ExtraConfig.EndpointReconcilerConfig.Interval = DefaultEndpointReconcilerInterval
   346  	}
   347  
   348  	if cfg.ExtraConfig.MasterEndpointReconcileTTL == 0 {
   349  		cfg.ExtraConfig.MasterEndpointReconcileTTL = DefaultEndpointReconcilerTTL
   350  	}
   351  
   352  	if cfg.ExtraConfig.EndpointReconcilerConfig.Reconciler == nil {
   353  		cfg.ExtraConfig.EndpointReconcilerConfig.Reconciler = c.createEndpointReconciler()
   354  	}
   355  
   356  	if cfg.ExtraConfig.RepairServicesInterval == 0 {
   357  		cfg.ExtraConfig.RepairServicesInterval = repairLoopInterval
   358  	}
   359  
   360  	return CompletedConfig{&cfg}
   361  }
   362  
   363  // New returns a new instance of Master from the given config.
   364  // Certain config fields will be set to a default value if unset.
   365  // Certain config fields must be specified, including:
   366  // KubeletClientConfig
   367  func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget) (*Instance, error) {
   368  	if reflect.DeepEqual(c.ExtraConfig.KubeletClientConfig, kubeletclient.KubeletClientConfig{}) {
   369  		return nil, fmt.Errorf("Master.New() called with empty config.KubeletClientConfig")
   370  	}
   371  
   372  	s, err := c.GenericConfig.New("kube-apiserver", delegationTarget)
   373  	if err != nil {
   374  		return nil, err
   375  	}
   376  
   377  	if c.ExtraConfig.EnableLogsSupport {
   378  		routes.Logs{}.Install(s.Handler.GoRestfulContainer)
   379  	}
   380  
   381  	// Metadata and keys are expected to only change across restarts at present,
   382  	// so we just marshal immediately and serve the cached JSON bytes.
   383  	md, err := serviceaccount.NewOpenIDMetadata(
   384  		c.ExtraConfig.ServiceAccountIssuerURL,
   385  		c.ExtraConfig.ServiceAccountJWKSURI,
   386  		c.GenericConfig.ExternalAddress,
   387  		c.ExtraConfig.ServiceAccountPublicKeys,
   388  	)
   389  	if err != nil {
   390  		// If there was an error, skip installing the endpoints and log the
   391  		// error, but continue on. We don't return the error because the
   392  		// metadata responses require additional, backwards incompatible
   393  		// validation of command-line options.
   394  		msg := fmt.Sprintf("Could not construct pre-rendered responses for"+
   395  			" ServiceAccountIssuerDiscovery endpoints. Endpoints will not be"+
   396  			" enabled. Error: %v", err)
   397  		if c.ExtraConfig.ServiceAccountIssuerURL != "" {
   398  			// The user likely expects this feature to be enabled if issuer URL is
   399  			// set and the feature gate is enabled. In the future, if there is no
   400  			// longer a feature gate and issuer URL is not set, the user may not
   401  			// expect this feature to be enabled. We log the former case as an Error
   402  			// and the latter case as an Info.
   403  			klog.Error(msg)
   404  		} else {
   405  			klog.Info(msg)
   406  		}
   407  	} else {
   408  		routes.NewOpenIDMetadataServer(md.ConfigJSON, md.PublicKeysetJSON).
   409  			Install(s.Handler.GoRestfulContainer)
   410  	}
   411  
   412  	m := &Instance{
   413  		GenericAPIServer:          s,
   414  		ClusterAuthenticationInfo: c.ExtraConfig.ClusterAuthenticationInfo,
   415  	}
   416  
   417  	clientset, err := kubernetes.NewForConfig(c.GenericConfig.LoopbackClientConfig)
   418  	if err != nil {
   419  		return nil, err
   420  	}
   421  
   422  	// TODO: update to a version that caches success but will recheck on failure, unlike memcache discovery
   423  	discoveryClientForAdmissionRegistration := clientset.Discovery()
   424  
   425  	legacyRESTStorageProvider, err := corerest.New(corerest.Config{
   426  		GenericConfig: corerest.GenericConfig{
   427  			StorageFactory:              c.ExtraConfig.StorageFactory,
   428  			EventTTL:                    c.ExtraConfig.EventTTL,
   429  			LoopbackClientConfig:        c.GenericConfig.LoopbackClientConfig,
   430  			ServiceAccountIssuer:        c.ExtraConfig.ServiceAccountIssuer,
   431  			ExtendExpiration:            c.ExtraConfig.ExtendExpiration,
   432  			ServiceAccountMaxExpiration: c.ExtraConfig.ServiceAccountMaxExpiration,
   433  			APIAudiences:                c.GenericConfig.Authentication.APIAudiences,
   434  			Informers:                   c.ExtraConfig.VersionedInformers,
   435  		},
   436  		Proxy: corerest.ProxyConfig{
   437  			Transport:           c.ExtraConfig.ProxyTransport,
   438  			KubeletClientConfig: c.ExtraConfig.KubeletClientConfig,
   439  		},
   440  		Services: corerest.ServicesConfig{
   441  			ClusterIPRange:          c.ExtraConfig.ServiceIPRange,
   442  			SecondaryClusterIPRange: c.ExtraConfig.SecondaryServiceIPRange,
   443  			NodePortRange:           c.ExtraConfig.ServiceNodePortRange,
   444  			IPRepairInterval:        c.ExtraConfig.RepairServicesInterval,
   445  		},
   446  	})
   447  	if err != nil {
   448  		return nil, err
   449  	}
   450  
   451  	// The order here is preserved in discovery.
   452  	// If resources with identical names exist in more than one of these groups (e.g. "deployments.apps"" and "deployments.extensions"),
   453  	// the order of this list determines which group an unqualified resource name (e.g. "deployments") should prefer.
   454  	// This priority order is used for local discovery, but it ends up aggregated in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go
   455  	// with specific priorities.
   456  	// TODO: describe the priority all the way down in the RESTStorageProviders and plumb it back through the various discovery
   457  	// handlers that we have.
   458  	restStorageProviders := []RESTStorageProvider{
   459  		legacyRESTStorageProvider,
   460  		apiserverinternalrest.StorageProvider{},
   461  		authenticationrest.RESTStorageProvider{Authenticator: c.GenericConfig.Authentication.Authenticator, APIAudiences: c.GenericConfig.Authentication.APIAudiences},
   462  		authorizationrest.RESTStorageProvider{Authorizer: c.GenericConfig.Authorization.Authorizer, RuleResolver: c.GenericConfig.RuleResolver},
   463  		autoscalingrest.RESTStorageProvider{},
   464  		batchrest.RESTStorageProvider{},
   465  		certificatesrest.RESTStorageProvider{},
   466  		coordinationrest.RESTStorageProvider{},
   467  		discoveryrest.StorageProvider{},
   468  		networkingrest.RESTStorageProvider{},
   469  		noderest.RESTStorageProvider{},
   470  		policyrest.RESTStorageProvider{},
   471  		rbacrest.RESTStorageProvider{Authorizer: c.GenericConfig.Authorization.Authorizer},
   472  		schedulingrest.RESTStorageProvider{},
   473  		storagerest.RESTStorageProvider{},
   474  		flowcontrolrest.RESTStorageProvider{InformerFactory: c.GenericConfig.SharedInformerFactory},
   475  		// keep apps after extensions so legacy clients resolve the extensions versions of shared resource names.
   476  		// See https://github.com/kubernetes/kubernetes/issues/42392
   477  		appsrest.StorageProvider{},
   478  		admissionregistrationrest.RESTStorageProvider{Authorizer: c.GenericConfig.Authorization.Authorizer, DiscoveryClient: discoveryClientForAdmissionRegistration},
   479  		eventsrest.RESTStorageProvider{TTL: c.ExtraConfig.EventTTL},
   480  		resourcerest.RESTStorageProvider{},
   481  	}
   482  	if err := m.InstallAPIs(c.ExtraConfig.APIResourceConfigSource, c.GenericConfig.RESTOptionsGetter, restStorageProviders...); err != nil {
   483  		return nil, err
   484  	}
   485  
   486  	m.GenericAPIServer.AddPostStartHookOrDie("start-system-namespaces-controller", func(hookContext genericapiserver.PostStartHookContext) error {
   487  		go systemnamespaces.NewController(clientset, c.ExtraConfig.VersionedInformers.Core().V1().Namespaces()).Run(hookContext.StopCh)
   488  		return nil
   489  	})
   490  
   491  	_, publicServicePort, err := c.GenericConfig.SecureServing.HostPort()
   492  	if err != nil {
   493  		return nil, fmt.Errorf("failed to get listener address: %w", err)
   494  	}
   495  	kubernetesServiceCtrl := kubernetesservice.New(kubernetesservice.Config{
   496  		PublicIP: c.GenericConfig.PublicAddress,
   497  
   498  		EndpointReconciler: c.ExtraConfig.EndpointReconcilerConfig.Reconciler,
   499  		EndpointInterval:   c.ExtraConfig.EndpointReconcilerConfig.Interval,
   500  
   501  		ServiceIP:                 c.ExtraConfig.APIServerServiceIP,
   502  		ServicePort:               c.ExtraConfig.APIServerServicePort,
   503  		PublicServicePort:         publicServicePort,
   504  		KubernetesServiceNodePort: c.ExtraConfig.KubernetesServiceNodePort,
   505  	}, clientset, c.ExtraConfig.VersionedInformers.Core().V1().Services())
   506  	m.GenericAPIServer.AddPostStartHookOrDie("bootstrap-controller", func(hookContext genericapiserver.PostStartHookContext) error {
   507  		kubernetesServiceCtrl.Start(hookContext.StopCh)
   508  		return nil
   509  	})
   510  	m.GenericAPIServer.AddPreShutdownHookOrDie("stop-kubernetes-service-controller", func() error {
   511  		kubernetesServiceCtrl.Stop()
   512  		return nil
   513  	})
   514  
   515  	if utilfeature.DefaultFeatureGate.Enabled(features.MultiCIDRServiceAllocator) {
   516  		m.GenericAPIServer.AddPostStartHookOrDie("start-kubernetes-service-cidr-controller", func(hookContext genericapiserver.PostStartHookContext) error {
   517  			controller := defaultservicecidr.NewController(
   518  				c.ExtraConfig.ServiceIPRange,
   519  				c.ExtraConfig.SecondaryServiceIPRange,
   520  				clientset,
   521  			)
   522  			// The default serviceCIDR must exist before the apiserver is healthy
   523  			// otherwise the allocators for Services will not work.
   524  			controller.Start(hookContext.StopCh)
   525  			return nil
   526  		})
   527  	}
   528  
   529  	if utilfeature.DefaultFeatureGate.Enabled(features.UnknownVersionInteroperabilityProxy) {
   530  		peeraddress := getPeerAddress(c.ExtraConfig.PeerAdvertiseAddress, c.GenericConfig.PublicAddress, publicServicePort)
   531  		peerEndpointCtrl := peerreconcilers.New(
   532  			c.GenericConfig.APIServerID,
   533  			peeraddress,
   534  			c.ExtraConfig.PeerEndpointLeaseReconciler,
   535  			c.ExtraConfig.EndpointReconcilerConfig.Interval,
   536  			clientset)
   537  		if err != nil {
   538  			return nil, fmt.Errorf("failed to create peer endpoint lease controller: %w", err)
   539  		}
   540  		m.GenericAPIServer.AddPostStartHookOrDie("peer-endpoint-reconciler-controller",
   541  			func(hookContext genericapiserver.PostStartHookContext) error {
   542  				peerEndpointCtrl.Start(hookContext.StopCh)
   543  				return nil
   544  			})
   545  		m.GenericAPIServer.AddPreShutdownHookOrDie("peer-endpoint-reconciler-controller",
   546  			func() error {
   547  				peerEndpointCtrl.Stop()
   548  				return nil
   549  			})
   550  		// Add PostStartHooks for Unknown Version Proxy filter.
   551  		if c.ExtraConfig.PeerProxy != nil {
   552  			m.GenericAPIServer.AddPostStartHookOrDie("unknown-version-proxy-filter", func(context genericapiserver.PostStartHookContext) error {
   553  				err := c.ExtraConfig.PeerProxy.WaitForCacheSync(context.StopCh)
   554  				return err
   555  			})
   556  		}
   557  	}
   558  
   559  	m.GenericAPIServer.AddPostStartHookOrDie("start-cluster-authentication-info-controller", func(hookContext genericapiserver.PostStartHookContext) error {
   560  		controller := clusterauthenticationtrust.NewClusterAuthenticationTrustController(m.ClusterAuthenticationInfo, clientset)
   561  
   562  		// generate a context  from stopCh. This is to avoid modifying files which are relying on apiserver
   563  		// TODO: See if we can pass ctx to the current method
   564  		ctx := wait.ContextForChannel(hookContext.StopCh)
   565  
   566  		// prime values and start listeners
   567  		if m.ClusterAuthenticationInfo.ClientCA != nil {
   568  			m.ClusterAuthenticationInfo.ClientCA.AddListener(controller)
   569  			if controller, ok := m.ClusterAuthenticationInfo.ClientCA.(dynamiccertificates.ControllerRunner); ok {
   570  				// runonce to be sure that we have a value.
   571  				if err := controller.RunOnce(ctx); err != nil {
   572  					runtime.HandleError(err)
   573  				}
   574  				go controller.Run(ctx, 1)
   575  			}
   576  		}
   577  		if m.ClusterAuthenticationInfo.RequestHeaderCA != nil {
   578  			m.ClusterAuthenticationInfo.RequestHeaderCA.AddListener(controller)
   579  			if controller, ok := m.ClusterAuthenticationInfo.RequestHeaderCA.(dynamiccertificates.ControllerRunner); ok {
   580  				// runonce to be sure that we have a value.
   581  				if err := controller.RunOnce(ctx); err != nil {
   582  					runtime.HandleError(err)
   583  				}
   584  				go controller.Run(ctx, 1)
   585  			}
   586  		}
   587  
   588  		go controller.Run(ctx, 1)
   589  		return nil
   590  	})
   591  
   592  	if utilfeature.DefaultFeatureGate.Enabled(apiserverfeatures.APIServerIdentity) {
   593  		m.GenericAPIServer.AddPostStartHookOrDie("start-kube-apiserver-identity-lease-controller", func(hookContext genericapiserver.PostStartHookContext) error {
   594  			// generate a context  from stopCh. This is to avoid modifying files which are relying on apiserver
   595  			// TODO: See if we can pass ctx to the current method
   596  			ctx := wait.ContextForChannel(hookContext.StopCh)
   597  
   598  			leaseName := m.GenericAPIServer.APIServerID
   599  			holderIdentity := m.GenericAPIServer.APIServerID + "_" + string(uuid.NewUUID())
   600  
   601  			peeraddress := getPeerAddress(c.ExtraConfig.PeerAdvertiseAddress, c.GenericConfig.PublicAddress, publicServicePort)
   602  			// must replace ':,[]' in [ip:port] to be able to store this as a valid label value
   603  			controller := lease.NewController(
   604  				clock.RealClock{},
   605  				clientset,
   606  				holderIdentity,
   607  				int32(IdentityLeaseDurationSeconds),
   608  				nil,
   609  				IdentityLeaseRenewIntervalPeriod,
   610  				leaseName,
   611  				metav1.NamespaceSystem,
   612  				// TODO: receive identity label value as a parameter when post start hook is moved to generic apiserver.
   613  				labelAPIServerHeartbeatFunc(KubeAPIServer, peeraddress))
   614  			go controller.Run(ctx)
   615  			return nil
   616  		})
   617  		// TODO: move this into generic apiserver and make the lease identity value configurable
   618  		m.GenericAPIServer.AddPostStartHookOrDie("start-kube-apiserver-identity-lease-garbage-collector", func(hookContext genericapiserver.PostStartHookContext) error {
   619  			go apiserverleasegc.NewAPIServerLeaseGC(
   620  				clientset,
   621  				IdentityLeaseGCPeriod,
   622  				metav1.NamespaceSystem,
   623  				KubeAPIServerIdentityLeaseLabelSelector,
   624  			).Run(hookContext.StopCh)
   625  			return nil
   626  		})
   627  	}
   628  
   629  	m.GenericAPIServer.AddPostStartHookOrDie("start-legacy-token-tracking-controller", func(hookContext genericapiserver.PostStartHookContext) error {
   630  		go legacytokentracking.NewController(clientset).Run(hookContext.StopCh)
   631  		return nil
   632  	})
   633  
   634  	return m, nil
   635  }
   636  
   637  func labelAPIServerHeartbeatFunc(identity string, peeraddress string) lease.ProcessLeaseFunc {
   638  	return func(lease *coordinationapiv1.Lease) error {
   639  		if lease.Labels == nil {
   640  			lease.Labels = map[string]string{}
   641  		}
   642  
   643  		if lease.Annotations == nil {
   644  			lease.Annotations = map[string]string{}
   645  		}
   646  
   647  		// This label indiciates the identity of the lease object.
   648  		lease.Labels[IdentityLeaseComponentLabelKey] = identity
   649  
   650  		hostname, err := os.Hostname()
   651  		if err != nil {
   652  			return err
   653  		}
   654  
   655  		// convenience label to easily map a lease object to a specific apiserver
   656  		lease.Labels[apiv1.LabelHostname] = hostname
   657  
   658  		// Include apiserver network location <ip_port> used by peers to proxy requests between kube-apiservers
   659  		if utilfeature.DefaultFeatureGate.Enabled(features.UnknownVersionInteroperabilityProxy) {
   660  			if peeraddress != "" {
   661  				lease.Annotations[apiv1.AnnotationPeerAdvertiseAddress] = peeraddress
   662  			}
   663  		}
   664  		return nil
   665  	}
   666  }
   667  
   668  // RESTStorageProvider is a factory type for REST storage.
   669  type RESTStorageProvider interface {
   670  	GroupName() string
   671  	NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error)
   672  }
   673  
   674  // InstallAPIs will install the APIs for the restStorageProviders if they are enabled.
   675  func (m *Instance) InstallAPIs(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter, restStorageProviders ...RESTStorageProvider) error {
   676  	nonLegacy := []*genericapiserver.APIGroupInfo{}
   677  
   678  	// used later in the loop to filter the served resource by those that have expired.
   679  	resourceExpirationEvaluator, err := genericapiserver.NewResourceExpirationEvaluator(*m.GenericAPIServer.Version)
   680  	if err != nil {
   681  		return err
   682  	}
   683  
   684  	for _, restStorageBuilder := range restStorageProviders {
   685  		groupName := restStorageBuilder.GroupName()
   686  		apiGroupInfo, err := restStorageBuilder.NewRESTStorage(apiResourceConfigSource, restOptionsGetter)
   687  		if err != nil {
   688  			return fmt.Errorf("problem initializing API group %q : %v", groupName, err)
   689  		}
   690  		if len(apiGroupInfo.VersionedResourcesStorageMap) == 0 {
   691  			// If we have no storage for any resource configured, this API group is effectively disabled.
   692  			// This can happen when an entire API group, version, or development-stage (alpha, beta, GA) is disabled.
   693  			klog.Infof("API group %q is not enabled, skipping.", groupName)
   694  			continue
   695  		}
   696  
   697  		// Remove resources that serving kinds that are removed.
   698  		// We do this here so that we don't accidentally serve versions without resources or openapi information that for kinds we don't serve.
   699  		// This is a spot above the construction of individual storage handlers so that no sig accidentally forgets to check.
   700  		resourceExpirationEvaluator.RemoveDeletedKinds(groupName, apiGroupInfo.Scheme, apiGroupInfo.VersionedResourcesStorageMap)
   701  		if len(apiGroupInfo.VersionedResourcesStorageMap) == 0 {
   702  			klog.V(1).Infof("Removing API group %v because it is time to stop serving it because it has no versions per APILifecycle.", groupName)
   703  			continue
   704  		}
   705  
   706  		klog.V(1).Infof("Enabling API group %q.", groupName)
   707  
   708  		if postHookProvider, ok := restStorageBuilder.(genericapiserver.PostStartHookProvider); ok {
   709  			name, hook, err := postHookProvider.PostStartHook()
   710  			if err != nil {
   711  				klog.Fatalf("Error building PostStartHook: %v", err)
   712  			}
   713  			m.GenericAPIServer.AddPostStartHookOrDie(name, hook)
   714  		}
   715  
   716  		if len(groupName) == 0 {
   717  			// the legacy group for core APIs is special that it is installed into /api via this special install method.
   718  			if err := m.GenericAPIServer.InstallLegacyAPIGroup(genericapiserver.DefaultLegacyAPIPrefix, &apiGroupInfo); err != nil {
   719  				return fmt.Errorf("error in registering legacy API: %w", err)
   720  			}
   721  		} else {
   722  			// everything else goes to /apis
   723  			nonLegacy = append(nonLegacy, &apiGroupInfo)
   724  		}
   725  	}
   726  
   727  	if err := m.GenericAPIServer.InstallAPIGroups(nonLegacy...); err != nil {
   728  		return fmt.Errorf("error in registering group versions: %v", err)
   729  	}
   730  	return nil
   731  }
   732  
   733  var (
   734  	// stableAPIGroupVersionsEnabledByDefault is a list of our stable versions.
   735  	stableAPIGroupVersionsEnabledByDefault = []schema.GroupVersion{
   736  		admissionregistrationv1.SchemeGroupVersion,
   737  		apiv1.SchemeGroupVersion,
   738  		appsv1.SchemeGroupVersion,
   739  		authenticationv1.SchemeGroupVersion,
   740  		authorizationapiv1.SchemeGroupVersion,
   741  		autoscalingapiv1.SchemeGroupVersion,
   742  		autoscalingapiv2.SchemeGroupVersion,
   743  		batchapiv1.SchemeGroupVersion,
   744  		certificatesapiv1.SchemeGroupVersion,
   745  		coordinationapiv1.SchemeGroupVersion,
   746  		discoveryv1.SchemeGroupVersion,
   747  		eventsv1.SchemeGroupVersion,
   748  		networkingapiv1.SchemeGroupVersion,
   749  		nodev1.SchemeGroupVersion,
   750  		policyapiv1.SchemeGroupVersion,
   751  		rbacv1.SchemeGroupVersion,
   752  		storageapiv1.SchemeGroupVersion,
   753  		schedulingapiv1.SchemeGroupVersion,
   754  		flowcontrolv1.SchemeGroupVersion,
   755  	}
   756  
   757  	// legacyBetaEnabledByDefaultResources is the list of beta resources we enable.  You may only add to this list
   758  	// if your resource is already enabled by default in a beta level we still serve AND there is no stable API for it.
   759  	// see https://github.com/kubernetes/enhancements/tree/master/keps/sig-architecture/3136-beta-apis-off-by-default
   760  	// for more details.
   761  	legacyBetaEnabledByDefaultResources = []schema.GroupVersionResource{
   762  		flowcontrolv1beta3.SchemeGroupVersion.WithResource("flowschemas"),                 // deprecate in 1.29, remove in 1.32
   763  		flowcontrolv1beta3.SchemeGroupVersion.WithResource("prioritylevelconfigurations"), // deprecate in 1.29, remove in 1.32
   764  	}
   765  	// betaAPIGroupVersionsDisabledByDefault is for all future beta groupVersions.
   766  	betaAPIGroupVersionsDisabledByDefault = []schema.GroupVersion{
   767  		admissionregistrationv1beta1.SchemeGroupVersion,
   768  		authenticationv1beta1.SchemeGroupVersion,
   769  		storageapiv1beta1.SchemeGroupVersion,
   770  		flowcontrolv1beta1.SchemeGroupVersion,
   771  		flowcontrolv1beta2.SchemeGroupVersion,
   772  		flowcontrolv1beta3.SchemeGroupVersion,
   773  	}
   774  
   775  	// alphaAPIGroupVersionsDisabledByDefault holds the alpha APIs we have.  They are always disabled by default.
   776  	alphaAPIGroupVersionsDisabledByDefault = []schema.GroupVersion{
   777  		admissionregistrationv1alpha1.SchemeGroupVersion,
   778  		apiserverinternalv1alpha1.SchemeGroupVersion,
   779  		authenticationv1alpha1.SchemeGroupVersion,
   780  		resourcev1alpha2.SchemeGroupVersion,
   781  		certificatesv1alpha1.SchemeGroupVersion,
   782  		networkingapiv1alpha1.SchemeGroupVersion,
   783  		storageapiv1alpha1.SchemeGroupVersion,
   784  	}
   785  )
   786  
   787  // DefaultAPIResourceConfigSource returns default configuration for an APIResource.
   788  func DefaultAPIResourceConfigSource() *serverstorage.ResourceConfig {
   789  	ret := serverstorage.NewResourceConfig()
   790  	// NOTE: GroupVersions listed here will be enabled by default. Don't put alpha or beta versions in the list.
   791  	ret.EnableVersions(stableAPIGroupVersionsEnabledByDefault...)
   792  
   793  	// disable alpha and beta versions explicitly so we have a full list of what's possible to serve
   794  	ret.DisableVersions(betaAPIGroupVersionsDisabledByDefault...)
   795  	ret.DisableVersions(alphaAPIGroupVersionsDisabledByDefault...)
   796  
   797  	// enable the legacy beta resources that were present before stopped serving new beta APIs by default.
   798  	ret.EnableResources(legacyBetaEnabledByDefaultResources...)
   799  
   800  	return ret
   801  }
   802  
   803  // utility function to get the apiserver address that is used by peer apiservers to proxy
   804  // requests to this apiserver in case the peer is incapable of serving the request
   805  func getPeerAddress(peerAdvertiseAddress peerreconcilers.PeerAdvertiseAddress, publicAddress net.IP, publicServicePort int) string {
   806  	if peerAdvertiseAddress.PeerAdvertiseIP != "" && peerAdvertiseAddress.PeerAdvertisePort != "" {
   807  		return net.JoinHostPort(peerAdvertiseAddress.PeerAdvertiseIP, peerAdvertiseAddress.PeerAdvertisePort)
   808  	} else {
   809  		return net.JoinHostPort(publicAddress.String(), strconv.Itoa(publicServicePort))
   810  	}
   811  }