1
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 svmv1alpha1 "k8s.io/api/storagemigration/v1alpha1"
57 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
58 "k8s.io/apimachinery/pkg/runtime/schema"
59 utilnet "k8s.io/apimachinery/pkg/util/net"
60 "k8s.io/apimachinery/pkg/util/runtime"
61 "k8s.io/apimachinery/pkg/util/uuid"
62 "k8s.io/apimachinery/pkg/util/wait"
63 "k8s.io/apiserver/pkg/endpoints/discovery"
64 apiserverfeatures "k8s.io/apiserver/pkg/features"
65 peerreconcilers "k8s.io/apiserver/pkg/reconcilers"
66 "k8s.io/apiserver/pkg/registry/generic"
67 genericapiserver "k8s.io/apiserver/pkg/server"
68 "k8s.io/apiserver/pkg/server/dynamiccertificates"
69 serverstorage "k8s.io/apiserver/pkg/server/storage"
70 utilfeature "k8s.io/apiserver/pkg/util/feature"
71 utilpeerproxy "k8s.io/apiserver/pkg/util/peerproxy"
72 "k8s.io/client-go/informers"
73 "k8s.io/client-go/kubernetes"
74 corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
75 discoveryclient "k8s.io/client-go/kubernetes/typed/discovery/v1"
76 "k8s.io/component-helpers/apimachinery/lease"
77 "k8s.io/klog/v2"
78 api "k8s.io/kubernetes/pkg/apis/core"
79 flowcontrolv1 "k8s.io/kubernetes/pkg/apis/flowcontrol/v1"
80 flowcontrolv1beta1 "k8s.io/kubernetes/pkg/apis/flowcontrol/v1beta1"
81 flowcontrolv1beta2 "k8s.io/kubernetes/pkg/apis/flowcontrol/v1beta2"
82 flowcontrolv1beta3 "k8s.io/kubernetes/pkg/apis/flowcontrol/v1beta3"
83 "k8s.io/kubernetes/pkg/controlplane/apiserver/options"
84 "k8s.io/kubernetes/pkg/controlplane/controller/apiserverleasegc"
85 "k8s.io/kubernetes/pkg/controlplane/controller/clusterauthenticationtrust"
86 "k8s.io/kubernetes/pkg/controlplane/controller/defaultservicecidr"
87 "k8s.io/kubernetes/pkg/controlplane/controller/kubernetesservice"
88 "k8s.io/kubernetes/pkg/controlplane/controller/legacytokentracking"
89 "k8s.io/kubernetes/pkg/controlplane/controller/systemnamespaces"
90 "k8s.io/kubernetes/pkg/controlplane/reconcilers"
91 "k8s.io/kubernetes/pkg/features"
92 kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
93 kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
94 "k8s.io/kubernetes/pkg/routes"
95 "k8s.io/kubernetes/pkg/serviceaccount"
96 "k8s.io/utils/clock"
97
98
99 admissionregistrationrest "k8s.io/kubernetes/pkg/registry/admissionregistration/rest"
100 apiserverinternalrest "k8s.io/kubernetes/pkg/registry/apiserverinternal/rest"
101 appsrest "k8s.io/kubernetes/pkg/registry/apps/rest"
102 authenticationrest "k8s.io/kubernetes/pkg/registry/authentication/rest"
103 authorizationrest "k8s.io/kubernetes/pkg/registry/authorization/rest"
104 autoscalingrest "k8s.io/kubernetes/pkg/registry/autoscaling/rest"
105 batchrest "k8s.io/kubernetes/pkg/registry/batch/rest"
106 certificatesrest "k8s.io/kubernetes/pkg/registry/certificates/rest"
107 coordinationrest "k8s.io/kubernetes/pkg/registry/coordination/rest"
108 corerest "k8s.io/kubernetes/pkg/registry/core/rest"
109 discoveryrest "k8s.io/kubernetes/pkg/registry/discovery/rest"
110 eventsrest "k8s.io/kubernetes/pkg/registry/events/rest"
111 flowcontrolrest "k8s.io/kubernetes/pkg/registry/flowcontrol/rest"
112 networkingrest "k8s.io/kubernetes/pkg/registry/networking/rest"
113 noderest "k8s.io/kubernetes/pkg/registry/node/rest"
114 policyrest "k8s.io/kubernetes/pkg/registry/policy/rest"
115 rbacrest "k8s.io/kubernetes/pkg/registry/rbac/rest"
116 resourcerest "k8s.io/kubernetes/pkg/registry/resource/rest"
117 schedulingrest "k8s.io/kubernetes/pkg/registry/scheduling/rest"
118 storagerest "k8s.io/kubernetes/pkg/registry/storage/rest"
119 svmrest "k8s.io/kubernetes/pkg/registry/storagemigration/rest"
120 )
121
122 const (
123
124
125 DefaultEndpointReconcilerInterval = 10 * time.Second
126
127 DefaultEndpointReconcilerTTL = 15 * time.Second
128
129
130
131 IdentityLeaseComponentLabelKey = "apiserver.kubernetes.io/identity"
132
133 KubeAPIServer = "kube-apiserver"
134
135 KubeAPIServerIdentityLeaseLabelSelector = IdentityLeaseComponentLabelKey + "=" + KubeAPIServer
136
137 repairLoopInterval = 3 * time.Minute
138 )
139
140 var (
141
142
143 IdentityLeaseGCPeriod = 3600 * time.Second
144
145
146 IdentityLeaseDurationSeconds = 3600
147
148
149 IdentityLeaseRenewIntervalPeriod = 10 * time.Second
150 )
151
152
153 type ExtraConfig struct {
154 ClusterAuthenticationInfo clusterauthenticationtrust.ClusterAuthenticationInfo
155
156 APIResourceConfigSource serverstorage.APIResourceConfigSource
157 StorageFactory serverstorage.StorageFactory
158 EndpointReconcilerConfig EndpointReconcilerConfig
159 EventTTL time.Duration
160 KubeletClientConfig kubeletclient.KubeletClientConfig
161
162 EnableLogsSupport bool
163 ProxyTransport *http.Transport
164
165
166
167 PeerProxy utilpeerproxy.Interface
168
169
170 PeerEndpointLeaseReconciler peerreconcilers.PeerEndpointLeaseReconciler
171
172
173
174
175 PeerCAFile string
176
177
178
179
180 PeerAdvertiseAddress peerreconcilers.PeerAdvertiseAddress
181
182
183
184 ServiceIPRange net.IPNet
185
186 APIServerServiceIP net.IP
187
188
189
190 SecondaryServiceIPRange net.IPNet
191
192 SecondaryAPIServerServiceIP net.IP
193
194
195 APIServerServicePort int
196
197
198
199
200
201 ServiceNodePortRange utilnet.PortRange
202
203 KubernetesServiceNodePort int
204
205
206
207 MasterCount int
208
209
210
211
212
213
214
215
216
217 MasterEndpointReconcileTTL time.Duration
218
219
220 EndpointReconcilerType reconcilers.Type
221
222 ServiceAccountIssuer serviceaccount.TokenGenerator
223 ServiceAccountMaxExpiration time.Duration
224 ExtendExpiration bool
225
226
227 ServiceAccountIssuerURL string
228 ServiceAccountJWKSURI string
229 ServiceAccountPublicKeys []interface{}
230
231 VersionedInformers informers.SharedInformerFactory
232
233
234
235 RepairServicesInterval time.Duration
236 }
237
238
239 type Config struct {
240 GenericConfig *genericapiserver.Config
241 ExtraConfig ExtraConfig
242 }
243
244 type completedConfig struct {
245 GenericConfig genericapiserver.CompletedConfig
246 ExtraConfig *ExtraConfig
247 }
248
249
250 type CompletedConfig struct {
251 *completedConfig
252 }
253
254
255
256 type EndpointReconcilerConfig struct {
257 Reconciler reconcilers.EndpointReconciler
258 Interval time.Duration
259 }
260
261
262 type Instance struct {
263 GenericAPIServer *genericapiserver.GenericAPIServer
264
265 ClusterAuthenticationInfo clusterauthenticationtrust.ClusterAuthenticationInfo
266 }
267
268 func (c *Config) createMasterCountReconciler() reconcilers.EndpointReconciler {
269 endpointClient := corev1client.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig)
270 endpointSliceClient := discoveryclient.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig)
271 endpointsAdapter := reconcilers.NewEndpointsAdapter(endpointClient, endpointSliceClient)
272
273 return reconcilers.NewMasterCountEndpointReconciler(c.ExtraConfig.MasterCount, endpointsAdapter)
274 }
275
276 func (c *Config) createNoneReconciler() reconcilers.EndpointReconciler {
277 return reconcilers.NewNoneEndpointReconciler()
278 }
279
280 func (c *Config) createLeaseReconciler() reconcilers.EndpointReconciler {
281 endpointClient := corev1client.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig)
282 endpointSliceClient := discoveryclient.NewForConfigOrDie(c.GenericConfig.LoopbackClientConfig)
283 endpointsAdapter := reconcilers.NewEndpointsAdapter(endpointClient, endpointSliceClient)
284
285 ttl := c.ExtraConfig.MasterEndpointReconcileTTL
286 config, err := c.ExtraConfig.StorageFactory.NewConfig(api.Resource("apiServerIPInfo"))
287 if err != nil {
288 klog.Fatalf("Error creating storage factory config: %v", err)
289 }
290 masterLeases, err := reconcilers.NewLeases(config, "/masterleases/", ttl)
291 if err != nil {
292 klog.Fatalf("Error creating leases: %v", err)
293 }
294
295 return reconcilers.NewLeaseEndpointReconciler(endpointsAdapter, masterLeases)
296 }
297
298 func (c *Config) createEndpointReconciler() reconcilers.EndpointReconciler {
299 klog.Infof("Using reconciler: %v", c.ExtraConfig.EndpointReconcilerType)
300 switch c.ExtraConfig.EndpointReconcilerType {
301
302 case reconcilers.MasterCountReconcilerType:
303 return c.createMasterCountReconciler()
304 case "", reconcilers.LeaseEndpointReconcilerType:
305 return c.createLeaseReconciler()
306 case reconcilers.NoneEndpointReconcilerType:
307 return c.createNoneReconciler()
308 default:
309 klog.Fatalf("Reconciler not implemented: %v", c.ExtraConfig.EndpointReconcilerType)
310 }
311 return nil
312 }
313
314
315 func (c *Config) Complete() CompletedConfig {
316 cfg := completedConfig{
317 c.GenericConfig.Complete(c.ExtraConfig.VersionedInformers),
318 &c.ExtraConfig,
319 }
320
321 serviceIPRange, apiServerServiceIP, err := options.ServiceIPRange(cfg.ExtraConfig.ServiceIPRange)
322 if err != nil {
323 klog.Fatalf("Error determining service IP ranges: %v", err)
324 }
325 if cfg.ExtraConfig.ServiceIPRange.IP == nil {
326 cfg.ExtraConfig.ServiceIPRange = serviceIPRange
327 }
328 if cfg.ExtraConfig.APIServerServiceIP == nil {
329 cfg.ExtraConfig.APIServerServiceIP = apiServerServiceIP
330 }
331
332 discoveryAddresses := discovery.DefaultAddresses{DefaultAddress: cfg.GenericConfig.ExternalAddress}
333 discoveryAddresses.CIDRRules = append(discoveryAddresses.CIDRRules,
334 discovery.CIDRRule{IPRange: cfg.ExtraConfig.ServiceIPRange, Address: net.JoinHostPort(cfg.ExtraConfig.APIServerServiceIP.String(), strconv.Itoa(cfg.ExtraConfig.APIServerServicePort))})
335 cfg.GenericConfig.DiscoveryAddresses = discoveryAddresses
336
337 if cfg.ExtraConfig.ServiceNodePortRange.Size == 0 {
338
339
340
341
342 cfg.ExtraConfig.ServiceNodePortRange = kubeoptions.DefaultServiceNodePortRange
343 klog.Infof("Node port range unspecified. Defaulting to %v.", cfg.ExtraConfig.ServiceNodePortRange)
344 }
345
346 if cfg.ExtraConfig.EndpointReconcilerConfig.Interval == 0 {
347 cfg.ExtraConfig.EndpointReconcilerConfig.Interval = DefaultEndpointReconcilerInterval
348 }
349
350 if cfg.ExtraConfig.MasterEndpointReconcileTTL == 0 {
351 cfg.ExtraConfig.MasterEndpointReconcileTTL = DefaultEndpointReconcilerTTL
352 }
353
354 if cfg.ExtraConfig.EndpointReconcilerConfig.Reconciler == nil {
355 cfg.ExtraConfig.EndpointReconcilerConfig.Reconciler = c.createEndpointReconciler()
356 }
357
358 if cfg.ExtraConfig.RepairServicesInterval == 0 {
359 cfg.ExtraConfig.RepairServicesInterval = repairLoopInterval
360 }
361
362 return CompletedConfig{&cfg}
363 }
364
365
366
367
368
369 func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget) (*Instance, error) {
370 if reflect.DeepEqual(c.ExtraConfig.KubeletClientConfig, kubeletclient.KubeletClientConfig{}) {
371 return nil, fmt.Errorf("Master.New() called with empty config.KubeletClientConfig")
372 }
373
374 s, err := c.GenericConfig.New("kube-apiserver", delegationTarget)
375 if err != nil {
376 return nil, err
377 }
378
379 if c.ExtraConfig.EnableLogsSupport {
380 routes.Logs{}.Install(s.Handler.GoRestfulContainer)
381 }
382
383
384
385 md, err := serviceaccount.NewOpenIDMetadata(
386 c.ExtraConfig.ServiceAccountIssuerURL,
387 c.ExtraConfig.ServiceAccountJWKSURI,
388 c.GenericConfig.ExternalAddress,
389 c.ExtraConfig.ServiceAccountPublicKeys,
390 )
391 if err != nil {
392
393
394
395
396 msg := fmt.Sprintf("Could not construct pre-rendered responses for"+
397 " ServiceAccountIssuerDiscovery endpoints. Endpoints will not be"+
398 " enabled. Error: %v", err)
399 if c.ExtraConfig.ServiceAccountIssuerURL != "" {
400
401
402
403
404
405 klog.Error(msg)
406 } else {
407 klog.Info(msg)
408 }
409 } else {
410 routes.NewOpenIDMetadataServer(md.ConfigJSON, md.PublicKeysetJSON).
411 Install(s.Handler.GoRestfulContainer)
412 }
413
414 m := &Instance{
415 GenericAPIServer: s,
416 ClusterAuthenticationInfo: c.ExtraConfig.ClusterAuthenticationInfo,
417 }
418
419 clientset, err := kubernetes.NewForConfig(c.GenericConfig.LoopbackClientConfig)
420 if err != nil {
421 return nil, err
422 }
423
424
425 discoveryClientForAdmissionRegistration := clientset.Discovery()
426
427 legacyRESTStorageProvider, err := corerest.New(corerest.Config{
428 GenericConfig: corerest.GenericConfig{
429 StorageFactory: c.ExtraConfig.StorageFactory,
430 EventTTL: c.ExtraConfig.EventTTL,
431 LoopbackClientConfig: c.GenericConfig.LoopbackClientConfig,
432 ServiceAccountIssuer: c.ExtraConfig.ServiceAccountIssuer,
433 ExtendExpiration: c.ExtraConfig.ExtendExpiration,
434 ServiceAccountMaxExpiration: c.ExtraConfig.ServiceAccountMaxExpiration,
435 APIAudiences: c.GenericConfig.Authentication.APIAudiences,
436 Informers: c.ExtraConfig.VersionedInformers,
437 },
438 Proxy: corerest.ProxyConfig{
439 Transport: c.ExtraConfig.ProxyTransport,
440 KubeletClientConfig: c.ExtraConfig.KubeletClientConfig,
441 },
442 Services: corerest.ServicesConfig{
443 ClusterIPRange: c.ExtraConfig.ServiceIPRange,
444 SecondaryClusterIPRange: c.ExtraConfig.SecondaryServiceIPRange,
445 NodePortRange: c.ExtraConfig.ServiceNodePortRange,
446 IPRepairInterval: c.ExtraConfig.RepairServicesInterval,
447 },
448 })
449 if err != nil {
450 return nil, err
451 }
452
453
454
455
456
457
458
459
460 restStorageProviders := []RESTStorageProvider{
461 legacyRESTStorageProvider,
462 apiserverinternalrest.StorageProvider{},
463 authenticationrest.RESTStorageProvider{Authenticator: c.GenericConfig.Authentication.Authenticator, APIAudiences: c.GenericConfig.Authentication.APIAudiences},
464 authorizationrest.RESTStorageProvider{Authorizer: c.GenericConfig.Authorization.Authorizer, RuleResolver: c.GenericConfig.RuleResolver},
465 autoscalingrest.RESTStorageProvider{},
466 batchrest.RESTStorageProvider{},
467 certificatesrest.RESTStorageProvider{},
468 coordinationrest.RESTStorageProvider{},
469 discoveryrest.StorageProvider{},
470 networkingrest.RESTStorageProvider{},
471 noderest.RESTStorageProvider{},
472 policyrest.RESTStorageProvider{},
473 rbacrest.RESTStorageProvider{Authorizer: c.GenericConfig.Authorization.Authorizer},
474 schedulingrest.RESTStorageProvider{},
475 storagerest.RESTStorageProvider{},
476 svmrest.RESTStorageProvider{},
477 flowcontrolrest.RESTStorageProvider{InformerFactory: c.GenericConfig.SharedInformerFactory},
478
479
480 appsrest.StorageProvider{},
481 admissionregistrationrest.RESTStorageProvider{Authorizer: c.GenericConfig.Authorization.Authorizer, DiscoveryClient: discoveryClientForAdmissionRegistration},
482 eventsrest.RESTStorageProvider{TTL: c.ExtraConfig.EventTTL},
483 resourcerest.RESTStorageProvider{},
484 }
485 if err := m.InstallAPIs(c.ExtraConfig.APIResourceConfigSource, c.GenericConfig.RESTOptionsGetter, restStorageProviders...); err != nil {
486 return nil, err
487 }
488
489 m.GenericAPIServer.AddPostStartHookOrDie("start-system-namespaces-controller", func(hookContext genericapiserver.PostStartHookContext) error {
490 go systemnamespaces.NewController(clientset, c.ExtraConfig.VersionedInformers.Core().V1().Namespaces()).Run(hookContext.StopCh)
491 return nil
492 })
493
494 _, publicServicePort, err := c.GenericConfig.SecureServing.HostPort()
495 if err != nil {
496 return nil, fmt.Errorf("failed to get listener address: %w", err)
497 }
498 kubernetesServiceCtrl := kubernetesservice.New(kubernetesservice.Config{
499 PublicIP: c.GenericConfig.PublicAddress,
500
501 EndpointReconciler: c.ExtraConfig.EndpointReconcilerConfig.Reconciler,
502 EndpointInterval: c.ExtraConfig.EndpointReconcilerConfig.Interval,
503
504 ServiceIP: c.ExtraConfig.APIServerServiceIP,
505 ServicePort: c.ExtraConfig.APIServerServicePort,
506 PublicServicePort: publicServicePort,
507 KubernetesServiceNodePort: c.ExtraConfig.KubernetesServiceNodePort,
508 }, clientset, c.ExtraConfig.VersionedInformers.Core().V1().Services())
509 m.GenericAPIServer.AddPostStartHookOrDie("bootstrap-controller", func(hookContext genericapiserver.PostStartHookContext) error {
510 kubernetesServiceCtrl.Start(hookContext.StopCh)
511 return nil
512 })
513 m.GenericAPIServer.AddPreShutdownHookOrDie("stop-kubernetes-service-controller", func() error {
514 kubernetesServiceCtrl.Stop()
515 return nil
516 })
517
518 if utilfeature.DefaultFeatureGate.Enabled(features.MultiCIDRServiceAllocator) {
519 m.GenericAPIServer.AddPostStartHookOrDie("start-kubernetes-service-cidr-controller", func(hookContext genericapiserver.PostStartHookContext) error {
520 controller := defaultservicecidr.NewController(
521 c.ExtraConfig.ServiceIPRange,
522 c.ExtraConfig.SecondaryServiceIPRange,
523 clientset,
524 )
525
526
527 controller.Start(hookContext.StopCh)
528 return nil
529 })
530 }
531
532 if utilfeature.DefaultFeatureGate.Enabled(features.UnknownVersionInteroperabilityProxy) {
533 peeraddress := getPeerAddress(c.ExtraConfig.PeerAdvertiseAddress, c.GenericConfig.PublicAddress, publicServicePort)
534 peerEndpointCtrl := peerreconcilers.New(
535 c.GenericConfig.APIServerID,
536 peeraddress,
537 c.ExtraConfig.PeerEndpointLeaseReconciler,
538 c.ExtraConfig.EndpointReconcilerConfig.Interval,
539 clientset)
540 if err != nil {
541 return nil, fmt.Errorf("failed to create peer endpoint lease controller: %w", err)
542 }
543 m.GenericAPIServer.AddPostStartHookOrDie("peer-endpoint-reconciler-controller",
544 func(hookContext genericapiserver.PostStartHookContext) error {
545 peerEndpointCtrl.Start(hookContext.StopCh)
546 return nil
547 })
548 m.GenericAPIServer.AddPreShutdownHookOrDie("peer-endpoint-reconciler-controller",
549 func() error {
550 peerEndpointCtrl.Stop()
551 return nil
552 })
553
554 if c.ExtraConfig.PeerProxy != nil {
555 m.GenericAPIServer.AddPostStartHookOrDie("unknown-version-proxy-filter", func(context genericapiserver.PostStartHookContext) error {
556 err := c.ExtraConfig.PeerProxy.WaitForCacheSync(context.StopCh)
557 return err
558 })
559 }
560 }
561
562 m.GenericAPIServer.AddPostStartHookOrDie("start-cluster-authentication-info-controller", func(hookContext genericapiserver.PostStartHookContext) error {
563 controller := clusterauthenticationtrust.NewClusterAuthenticationTrustController(m.ClusterAuthenticationInfo, clientset)
564
565
566
567 ctx := wait.ContextForChannel(hookContext.StopCh)
568
569
570 if m.ClusterAuthenticationInfo.ClientCA != nil {
571 m.ClusterAuthenticationInfo.ClientCA.AddListener(controller)
572 if controller, ok := m.ClusterAuthenticationInfo.ClientCA.(dynamiccertificates.ControllerRunner); ok {
573
574 if err := controller.RunOnce(ctx); err != nil {
575 runtime.HandleError(err)
576 }
577 go controller.Run(ctx, 1)
578 }
579 }
580 if m.ClusterAuthenticationInfo.RequestHeaderCA != nil {
581 m.ClusterAuthenticationInfo.RequestHeaderCA.AddListener(controller)
582 if controller, ok := m.ClusterAuthenticationInfo.RequestHeaderCA.(dynamiccertificates.ControllerRunner); ok {
583
584 if err := controller.RunOnce(ctx); err != nil {
585 runtime.HandleError(err)
586 }
587 go controller.Run(ctx, 1)
588 }
589 }
590
591 go controller.Run(ctx, 1)
592 return nil
593 })
594
595 if utilfeature.DefaultFeatureGate.Enabled(apiserverfeatures.APIServerIdentity) {
596 m.GenericAPIServer.AddPostStartHookOrDie("start-kube-apiserver-identity-lease-controller", func(hookContext genericapiserver.PostStartHookContext) error {
597
598
599 ctx := wait.ContextForChannel(hookContext.StopCh)
600
601 leaseName := m.GenericAPIServer.APIServerID
602 holderIdentity := m.GenericAPIServer.APIServerID + "_" + string(uuid.NewUUID())
603
604 peeraddress := getPeerAddress(c.ExtraConfig.PeerAdvertiseAddress, c.GenericConfig.PublicAddress, publicServicePort)
605
606 controller := lease.NewController(
607 clock.RealClock{},
608 clientset,
609 holderIdentity,
610 int32(IdentityLeaseDurationSeconds),
611 nil,
612 IdentityLeaseRenewIntervalPeriod,
613 leaseName,
614 metav1.NamespaceSystem,
615
616 labelAPIServerHeartbeatFunc(KubeAPIServer, peeraddress))
617 go controller.Run(ctx)
618 return nil
619 })
620
621 m.GenericAPIServer.AddPostStartHookOrDie("start-kube-apiserver-identity-lease-garbage-collector", func(hookContext genericapiserver.PostStartHookContext) error {
622 go apiserverleasegc.NewAPIServerLeaseGC(
623 clientset,
624 IdentityLeaseGCPeriod,
625 metav1.NamespaceSystem,
626 KubeAPIServerIdentityLeaseLabelSelector,
627 ).Run(hookContext.StopCh)
628 return nil
629 })
630 }
631
632 m.GenericAPIServer.AddPostStartHookOrDie("start-legacy-token-tracking-controller", func(hookContext genericapiserver.PostStartHookContext) error {
633 go legacytokentracking.NewController(clientset).Run(hookContext.StopCh)
634 return nil
635 })
636
637 return m, nil
638 }
639
640 func labelAPIServerHeartbeatFunc(identity string, peeraddress string) lease.ProcessLeaseFunc {
641 return func(lease *coordinationapiv1.Lease) error {
642 if lease.Labels == nil {
643 lease.Labels = map[string]string{}
644 }
645
646 if lease.Annotations == nil {
647 lease.Annotations = map[string]string{}
648 }
649
650
651 lease.Labels[IdentityLeaseComponentLabelKey] = identity
652
653 hostname, err := os.Hostname()
654 if err != nil {
655 return err
656 }
657
658
659 lease.Labels[apiv1.LabelHostname] = hostname
660
661
662 if utilfeature.DefaultFeatureGate.Enabled(features.UnknownVersionInteroperabilityProxy) {
663 if peeraddress != "" {
664 lease.Annotations[apiv1.AnnotationPeerAdvertiseAddress] = peeraddress
665 }
666 }
667 return nil
668 }
669 }
670
671
672 type RESTStorageProvider interface {
673 GroupName() string
674 NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error)
675 }
676
677
678 func (m *Instance) InstallAPIs(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter, restStorageProviders ...RESTStorageProvider) error {
679 nonLegacy := []*genericapiserver.APIGroupInfo{}
680
681
682 resourceExpirationEvaluator, err := genericapiserver.NewResourceExpirationEvaluator(*m.GenericAPIServer.Version)
683 if err != nil {
684 return err
685 }
686
687 for _, restStorageBuilder := range restStorageProviders {
688 groupName := restStorageBuilder.GroupName()
689 apiGroupInfo, err := restStorageBuilder.NewRESTStorage(apiResourceConfigSource, restOptionsGetter)
690 if err != nil {
691 return fmt.Errorf("problem initializing API group %q : %v", groupName, err)
692 }
693 if len(apiGroupInfo.VersionedResourcesStorageMap) == 0 {
694
695
696 klog.Infof("API group %q is not enabled, skipping.", groupName)
697 continue
698 }
699
700
701
702
703 resourceExpirationEvaluator.RemoveDeletedKinds(groupName, apiGroupInfo.Scheme, apiGroupInfo.VersionedResourcesStorageMap)
704 if len(apiGroupInfo.VersionedResourcesStorageMap) == 0 {
705 klog.V(1).Infof("Removing API group %v because it is time to stop serving it because it has no versions per APILifecycle.", groupName)
706 continue
707 }
708
709 klog.V(1).Infof("Enabling API group %q.", groupName)
710
711 if postHookProvider, ok := restStorageBuilder.(genericapiserver.PostStartHookProvider); ok {
712 name, hook, err := postHookProvider.PostStartHook()
713 if err != nil {
714 klog.Fatalf("Error building PostStartHook: %v", err)
715 }
716 m.GenericAPIServer.AddPostStartHookOrDie(name, hook)
717 }
718
719 if len(groupName) == 0 {
720
721 if err := m.GenericAPIServer.InstallLegacyAPIGroup(genericapiserver.DefaultLegacyAPIPrefix, &apiGroupInfo); err != nil {
722 return fmt.Errorf("error in registering legacy API: %w", err)
723 }
724 } else {
725
726 nonLegacy = append(nonLegacy, &apiGroupInfo)
727 }
728 }
729
730 if err := m.GenericAPIServer.InstallAPIGroups(nonLegacy...); err != nil {
731 return fmt.Errorf("error in registering group versions: %v", err)
732 }
733 return nil
734 }
735
736 var (
737
738 stableAPIGroupVersionsEnabledByDefault = []schema.GroupVersion{
739 admissionregistrationv1.SchemeGroupVersion,
740 apiv1.SchemeGroupVersion,
741 appsv1.SchemeGroupVersion,
742 authenticationv1.SchemeGroupVersion,
743 authorizationapiv1.SchemeGroupVersion,
744 autoscalingapiv1.SchemeGroupVersion,
745 autoscalingapiv2.SchemeGroupVersion,
746 batchapiv1.SchemeGroupVersion,
747 certificatesapiv1.SchemeGroupVersion,
748 coordinationapiv1.SchemeGroupVersion,
749 discoveryv1.SchemeGroupVersion,
750 eventsv1.SchemeGroupVersion,
751 networkingapiv1.SchemeGroupVersion,
752 nodev1.SchemeGroupVersion,
753 policyapiv1.SchemeGroupVersion,
754 rbacv1.SchemeGroupVersion,
755 storageapiv1.SchemeGroupVersion,
756 schedulingapiv1.SchemeGroupVersion,
757 flowcontrolv1.SchemeGroupVersion,
758 }
759
760
761
762
763
764 legacyBetaEnabledByDefaultResources = []schema.GroupVersionResource{
765 flowcontrolv1beta3.SchemeGroupVersion.WithResource("flowschemas"),
766 flowcontrolv1beta3.SchemeGroupVersion.WithResource("prioritylevelconfigurations"),
767 }
768
769 betaAPIGroupVersionsDisabledByDefault = []schema.GroupVersion{
770 admissionregistrationv1beta1.SchemeGroupVersion,
771 authenticationv1beta1.SchemeGroupVersion,
772 storageapiv1beta1.SchemeGroupVersion,
773 flowcontrolv1beta1.SchemeGroupVersion,
774 flowcontrolv1beta2.SchemeGroupVersion,
775 flowcontrolv1beta3.SchemeGroupVersion,
776 }
777
778
779 alphaAPIGroupVersionsDisabledByDefault = []schema.GroupVersion{
780 admissionregistrationv1alpha1.SchemeGroupVersion,
781 apiserverinternalv1alpha1.SchemeGroupVersion,
782 authenticationv1alpha1.SchemeGroupVersion,
783 resourcev1alpha2.SchemeGroupVersion,
784 certificatesv1alpha1.SchemeGroupVersion,
785 networkingapiv1alpha1.SchemeGroupVersion,
786 storageapiv1alpha1.SchemeGroupVersion,
787 svmv1alpha1.SchemeGroupVersion,
788 }
789 )
790
791
792 func DefaultAPIResourceConfigSource() *serverstorage.ResourceConfig {
793 ret := serverstorage.NewResourceConfig()
794
795 ret.EnableVersions(stableAPIGroupVersionsEnabledByDefault...)
796
797
798 ret.DisableVersions(betaAPIGroupVersionsDisabledByDefault...)
799 ret.DisableVersions(alphaAPIGroupVersionsDisabledByDefault...)
800
801
802 ret.EnableResources(legacyBetaEnabledByDefaultResources...)
803
804 return ret
805 }
806
807
808
809 func getPeerAddress(peerAdvertiseAddress peerreconcilers.PeerAdvertiseAddress, publicAddress net.IP, publicServicePort int) string {
810 if peerAdvertiseAddress.PeerAdvertiseIP != "" && peerAdvertiseAddress.PeerAdvertisePort != "" {
811 return net.JoinHostPort(peerAdvertiseAddress.PeerAdvertiseIP, peerAdvertiseAddress.PeerAdvertisePort)
812 } else {
813 return net.JoinHostPort(publicAddress.String(), strconv.Itoa(publicServicePort))
814 }
815 }
816
View as plain text