diff --git a/api/api-rules/violation_exceptions.list b/api/api-rules/violation_exceptions.list index aa239a93d92..cefe8376d1e 100644 --- a/api/api-rules/violation_exceptions.list +++ b/api/api-rules/violation_exceptions.list @@ -208,6 +208,7 @@ API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,H API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,HPAControllerConfiguration,HorizontalPodAutoscalerInitialReadinessDelay API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,HPAControllerConfiguration,HorizontalPodAutoscalerSyncPeriod API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,HPAControllerConfiguration,HorizontalPodAutoscalerTolerance +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,ImperativeEvictionResponderControllerConfiguration,ConcurrentImperativeEvictionResponderSyncs API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,JobControllerConfiguration,ConcurrentJobSyncs API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,AttachDetachController API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,CSRSigningController @@ -225,6 +226,7 @@ API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,K API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,GarbageCollectorController API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,Generic API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,HPAController +API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,ImperativeEvictionResponderController API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,JobController API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,KubeCloudShared API rule violation: names_match,k8s.io/kube-controller-manager/config/v1alpha1,KubeControllerManagerConfiguration,LegacySATokenCleaner diff --git a/cmd/kube-controller-manager/app/controller_descriptor.go b/cmd/kube-controller-manager/app/controller_descriptor.go index a094958ec72..59e2f602302 100644 --- a/cmd/kube-controller-manager/app/controller_descriptor.go +++ b/cmd/kube-controller-manager/app/controller_descriptor.go @@ -219,6 +219,7 @@ func NewControllerDescriptors() map[string]*ControllerDescriptor { register(newDeviceTaintEvictionControllerDescriptor()) register(newLegacyServiceAccountTokenCleanerControllerDescriptor()) register(newValidatingAdmissionPolicyStatusControllerDescriptor()) + register(newImperativeEvictionResponderControllerDescriptor()) register(newTaintEvictionControllerDescriptor()) register(newServiceCIDRsControllerDescriptor()) register(newStorageVersionMigratorControllerDescriptor()) diff --git a/cmd/kube-controller-manager/app/controllermanager_test.go b/cmd/kube-controller-manager/app/controllermanager_test.go index 4bd3d97c3f9..3fb58cd4da2 100644 --- a/cmd/kube-controller-manager/app/controllermanager_test.go +++ b/cmd/kube-controller-manager/app/controllermanager_test.go @@ -99,6 +99,7 @@ func TestControllerNamesDeclaration(t *testing.T) { names.StorageVersionMigratorController, names.SELinuxWarningController, names.EvictionRequestController, + names.ImperativeEvictionResponderController, ) for _, name := range KnownControllers() { diff --git a/cmd/kube-controller-manager/app/lifecycle.go b/cmd/kube-controller-manager/app/lifecycle.go index 02ba917ddac..f69151822cd 100644 --- a/cmd/kube-controller-manager/app/lifecycle.go +++ b/cmd/kube-controller-manager/app/lifecycle.go @@ -22,6 +22,7 @@ import ( "k8s.io/component-base/featuregate" "k8s.io/kubernetes/cmd/kube-controller-manager/names" "k8s.io/kubernetes/pkg/controller/evictionrequest" + "k8s.io/kubernetes/pkg/controller/imperativeevictionresponder" "k8s.io/kubernetes/pkg/features" ) @@ -57,3 +58,35 @@ func newEvictionRequestController(ctx context.Context, controllerContext Control evictionRequestController.Run(ctx, int(controllerContext.ComponentConfig.EvictionRequestController.ConcurrentEvictionRequestSyncs)) }, controllerName), nil } + +func newImperativeEvictionResponderControllerDescriptor() *ControllerDescriptor { + return &ControllerDescriptor{ + name: names.ImperativeEvictionResponderController, + constructor: newImperativeEvictionResponderController, + requiredFeatureGates: []featuregate.Feature{ + features.EvictionRequestAPI, + }, + } +} + +func newImperativeEvictionResponderController(ctx context.Context, controllerContext ControllerContext, controllerName string) (Controller, error) { + client, err := controllerContext.NewClient(controllerName) + if err != nil { + return nil, err + } + + imperativeEvictionResponderController, err := imperativeevictionresponder.NewController( + ctx, + controllerName, + controllerContext.InformerFactory.Lifecycle().V1alpha1().Evictions(), + controllerContext.InformerFactory.Core().V1().Pods(), + client, + ) + if err != nil { + return nil, err + } + + return newControllerLoop(func(ctx context.Context) { + imperativeEvictionResponderController.Run(ctx, int(controllerContext.ComponentConfig.ImperativeEvictionResponderController.ConcurrentImperativeEvictionResponderSyncs)) + }, controllerName), nil +} diff --git a/cmd/kube-controller-manager/app/options/imperativeevictionrespondercontroller.go b/cmd/kube-controller-manager/app/options/imperativeevictionrespondercontroller.go new file mode 100644 index 00000000000..cc7cfa51d0d --- /dev/null +++ b/cmd/kube-controller-manager/app/options/imperativeevictionrespondercontroller.go @@ -0,0 +1,72 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package options + +import ( + "fmt" + + "github.com/spf13/pflag" + + imperativeevictionresponderconfig "k8s.io/kubernetes/pkg/controller/imperativeevictionresponder/config" +) + +const ( + minConcurrentImperativeEvictionResponderSyncs = 1 + maxConcurrentImperativeEvictionResponderSyncs = 50 +) + +// ImperativeEvictionResponderControllerOptions holds the ImperativeEvictionResponderController options. +type ImperativeEvictionResponderControllerOptions struct { + *imperativeevictionresponderconfig.ImperativeEvictionResponderControllerConfiguration +} + +// AddFlags adds flags related to ImperativeEvictionResponderController for controller manager to the specified FlagSet. +func (o *ImperativeEvictionResponderControllerOptions) AddFlags(fs *pflag.FlagSet) { + if o == nil { + return + } + + fs.Int32Var(&o.ConcurrentImperativeEvictionResponderSyncs, "concurrent-imperative-eviction-responder-syncs", o.ConcurrentImperativeEvictionResponderSyncs, "The number of eviction object syncing and imperative eviction operations that will be done concurrently. Larger number = bigger throughput of imperative evictions that call the /eviction API and faster Eviction status updating, but more CPU (and network) load. Defaults to 5.") +} + +// ApplyTo fills up ImperativeEvictionResponderController config with options. +func (o *ImperativeEvictionResponderControllerOptions) ApplyTo(cfg *imperativeevictionresponderconfig.ImperativeEvictionResponderControllerConfiguration) error { + if o == nil { + return nil + } + + cfg.ConcurrentImperativeEvictionResponderSyncs = o.ConcurrentImperativeEvictionResponderSyncs + + return nil +} + +// Validate checks validation of ImperativeEvictionResponderControllerOptions. +func (o *ImperativeEvictionResponderControllerOptions) Validate() []error { + if o == nil { + return nil + } + + errs := []error{} + + if o.ConcurrentImperativeEvictionResponderSyncs < minConcurrentImperativeEvictionResponderSyncs { + errs = append(errs, fmt.Errorf("concurrent-imperative-eviction-responder-syncs must not be less than %d, but got %d", minConcurrentImperativeEvictionResponderSyncs, o.ConcurrentImperativeEvictionResponderSyncs)) + } else if o.ConcurrentImperativeEvictionResponderSyncs > maxConcurrentImperativeEvictionResponderSyncs { + errs = append(errs, fmt.Errorf("concurrent-imperative-eviction-responder-syncs must not be more than %d, but got %d", maxConcurrentImperativeEvictionResponderSyncs, o.ConcurrentImperativeEvictionResponderSyncs)) + } + + return errs +} diff --git a/cmd/kube-controller-manager/app/options/options.go b/cmd/kube-controller-manager/app/options/options.go index 95fc0da0c98..e52b84342e6 100644 --- a/cmd/kube-controller-manager/app/options/options.go +++ b/cmd/kube-controller-manager/app/options/options.go @@ -85,6 +85,7 @@ type KubeControllerManagerOptions struct { EvictionRequestController *EvictionRequestControllerOptions GarbageCollectorController *GarbageCollectorControllerOptions HPAController *HPAControllerOptions + ImperativeEvictionResponderController *ImperativeEvictionResponderControllerOptions JobController *JobControllerOptions CronJobController *CronJobControllerOptions LegacySATokenCleaner *LegacySATokenCleanerOptions @@ -184,6 +185,9 @@ func NewKubeControllerManagerOptions() (*KubeControllerManagerOptions, error) { HPAController: &HPAControllerOptions{ &componentConfig.HPAController, }, + ImperativeEvictionResponderController: &ImperativeEvictionResponderControllerOptions{ + &componentConfig.ImperativeEvictionResponderController, + }, JobController: &JobControllerOptions{ &componentConfig.JobController, }, @@ -292,6 +296,7 @@ func (s *KubeControllerManagerOptions) Flags(allControllers []string, disabledBy s.EvictionRequestController.AddFlags(fss.FlagSet(names.EvictionRequestController)) s.GarbageCollectorController.AddFlags(fss.FlagSet(names.GarbageCollectorController)) s.HPAController.AddFlags(fss.FlagSet(names.HorizontalPodAutoscalerController)) + s.ImperativeEvictionResponderController.AddFlags(fss.FlagSet(names.ImperativeEvictionResponderController)) s.JobController.AddFlags(fss.FlagSet(names.JobController)) s.CronJobController.AddFlags(fss.FlagSet(names.CronJobController)) s.LegacySATokenCleaner.AddFlags(fss.FlagSet(names.LegacyServiceAccountTokenCleanerController)) @@ -381,6 +386,9 @@ func (s *KubeControllerManagerOptions) ApplyTo(c *kubecontrollerconfig.Config, a if err := s.HPAController.ApplyTo(&c.ComponentConfig.HPAController); err != nil { return err } + if err := s.ImperativeEvictionResponderController.ApplyTo(&c.ComponentConfig.ImperativeEvictionResponderController); err != nil { + return err + } if err := s.JobController.ApplyTo(&c.ComponentConfig.JobController); err != nil { return err } @@ -465,6 +473,7 @@ func (s *KubeControllerManagerOptions) Validate(allControllers []string, disable errs = append(errs, s.EvictionRequestController.Validate()...) errs = append(errs, s.GarbageCollectorController.Validate()...) errs = append(errs, s.HPAController.Validate()...) + errs = append(errs, s.ImperativeEvictionResponderController.Validate()...) errs = append(errs, s.JobController.Validate()...) errs = append(errs, s.CronJobController.Validate()...) errs = append(errs, s.LegacySATokenCleaner.Validate()...) diff --git a/cmd/kube-controller-manager/app/options/options_test.go b/cmd/kube-controller-manager/app/options/options_test.go index 22a0119982d..c641ce00697 100644 --- a/cmd/kube-controller-manager/app/options/options_test.go +++ b/cmd/kube-controller-manager/app/options/options_test.go @@ -63,6 +63,7 @@ import ( endpointslicemirroringconfig "k8s.io/kubernetes/pkg/controller/endpointslicemirroring/config" evictionrequestconfig "k8s.io/kubernetes/pkg/controller/evictionrequest/config" garbagecollectorconfig "k8s.io/kubernetes/pkg/controller/garbagecollector/config" + imperativeevictionresponderconfig "k8s.io/kubernetes/pkg/controller/imperativeevictionresponder/config" jobconfig "k8s.io/kubernetes/pkg/controller/job/config" namespaceconfig "k8s.io/kubernetes/pkg/controller/namespace/config" nodeipamconfig "k8s.io/kubernetes/pkg/controller/nodeipam/config" @@ -114,6 +115,7 @@ var args = []string{ "--concurrent-service-endpoint-syncs=10", "--concurrent-gc-syncs=30", "--concurrent-namespace-syncs=20", + "--concurrent-imperative-eviction-responder-syncs=17", "--concurrent-job-syncs=10", "--concurrent-cron-job-syncs=10", "--concurrent-replicaset-syncs=10", @@ -344,6 +346,11 @@ func TestAddFlags(t *testing.T) { HorizontalPodAutoscalerTolerance: 0.1, }, }, + ImperativeEvictionResponderController: &ImperativeEvictionResponderControllerOptions{ + &imperativeevictionresponderconfig.ImperativeEvictionResponderControllerConfiguration{ + ConcurrentImperativeEvictionResponderSyncs: 17, + }, + }, JobController: &JobControllerOptions{ &jobconfig.JobControllerConfiguration{ ConcurrentJobSyncs: 10, @@ -696,6 +703,9 @@ func TestApplyTo(t *testing.T) { HorizontalPodAutoscalerInitialReadinessDelay: metav1.Duration{Duration: 50 * time.Second}, HorizontalPodAutoscalerTolerance: 0.1, }, + ImperativeEvictionResponderController: imperativeevictionresponderconfig.ImperativeEvictionResponderControllerConfiguration{ + ConcurrentImperativeEvictionResponderSyncs: 17, + }, JobController: jobconfig.JobControllerConfiguration{ ConcurrentJobSyncs: 10, }, @@ -1387,6 +1397,35 @@ func TestValidateControllersOptions(t *testing.T) { }, }, }, + { + name: "ImperativeEvictionResponderControllerConfiguration", + expectErrors: false, + options: &ImperativeEvictionResponderControllerOptions{ + &imperativeevictionresponderconfig.ImperativeEvictionResponderControllerConfiguration{ + ConcurrentImperativeEvictionResponderSyncs: 17, + }, + }, + }, + { + name: "ImperativeEvictionResponderControllerConfiguration lower than minConcurrentImperativeEvictionResponderSyncs (1)", + expectErrors: true, + expectedErrorSubString: "concurrent-imperative-eviction-responder-syncs must not be less than 1", + options: &ImperativeEvictionResponderControllerOptions{ + &imperativeevictionresponderconfig.ImperativeEvictionResponderControllerConfiguration{ + ConcurrentImperativeEvictionResponderSyncs: 0, + }, + }, + }, + { + name: "ImperativeEvictionResponderControllerConfiguration greater than maxConcurrentImperativeEvictionResponderSyncs (50)", + expectErrors: true, + expectedErrorSubString: "concurrent-imperative-eviction-responder-syncs must not be more than 50", + options: &ImperativeEvictionResponderControllerOptions{ + &imperativeevictionresponderconfig.ImperativeEvictionResponderControllerConfiguration{ + ConcurrentImperativeEvictionResponderSyncs: 51, + }, + }, + }, { name: "JobControllerOptions", expectErrors: false, diff --git a/cmd/kube-controller-manager/names/controller_names.go b/cmd/kube-controller-manager/names/controller_names.go index f4058e34840..aec20d10315 100644 --- a/cmd/kube-controller-manager/names/controller_names.go +++ b/cmd/kube-controller-manager/names/controller_names.go @@ -91,4 +91,5 @@ const ( StorageVersionMigratorController = "storage-version-migrator-controller" SELinuxWarningController = "selinux-warning-controller" EvictionRequestController = "evictionrequest-controller" + ImperativeEvictionResponderController = "imperative-eviction-responder-controller" ) diff --git a/pkg/controller/apis/config/types.go b/pkg/controller/apis/config/types.go index 4dac770c43b..c4b3ba54adc 100644 --- a/pkg/controller/apis/config/types.go +++ b/pkg/controller/apis/config/types.go @@ -32,6 +32,7 @@ import ( endpointslicemirroringconfig "k8s.io/kubernetes/pkg/controller/endpointslicemirroring/config" evictionrequestconfig "k8s.io/kubernetes/pkg/controller/evictionrequest/config" garbagecollectorconfig "k8s.io/kubernetes/pkg/controller/garbagecollector/config" + imperativeevictionresponder "k8s.io/kubernetes/pkg/controller/imperativeevictionresponder/config" jobconfig "k8s.io/kubernetes/pkg/controller/job/config" namespaceconfig "k8s.io/kubernetes/pkg/controller/namespace/config" nodeipamconfig "k8s.io/kubernetes/pkg/controller/nodeipam/config" @@ -106,6 +107,9 @@ type KubeControllerManagerConfiguration struct { GarbageCollectorController garbagecollectorconfig.GarbageCollectorControllerConfiguration // HPAControllerConfiguration holds configuration for HPAController related features. HPAController poautosclerconfig.HPAControllerConfiguration + // ImperativeEvictionResponderControllerConfiguration contains elements configuring + // the imperative eviction responder controller. + ImperativeEvictionResponderController imperativeevictionresponder.ImperativeEvictionResponderControllerConfiguration // JobControllerConfiguration holds configuration for JobController related features. JobController jobconfig.JobControllerConfiguration // LegacySATokenCleanerConfiguration holds configuration for LegacySATokenCleaner related features. diff --git a/pkg/controller/apis/config/v1alpha1/defaults.go b/pkg/controller/apis/config/v1alpha1/defaults.go index f761cfdd9e1..ea7673bb58f 100644 --- a/pkg/controller/apis/config/v1alpha1/defaults.go +++ b/pkg/controller/apis/config/v1alpha1/defaults.go @@ -32,6 +32,7 @@ import ( endpointslicemirroringconfigv1alpha1 "k8s.io/kubernetes/pkg/controller/endpointslicemirroring/config/v1alpha1" evictionrequestconfigv1alpha1 "k8s.io/kubernetes/pkg/controller/evictionrequest/config/v1alpha1" garbagecollectorconfigv1alpha1 "k8s.io/kubernetes/pkg/controller/garbagecollector/config/v1alpha1" + imperativeevictionresponderv1alpha1 "k8s.io/kubernetes/pkg/controller/imperativeevictionresponder/config/v1alpha1" jobconfigv1alpha1 "k8s.io/kubernetes/pkg/controller/job/config/v1alpha1" namespaceconfigv1alpha1 "k8s.io/kubernetes/pkg/controller/namespace/config/v1alpha1" nodeipamconfigv1alpha1 "k8s.io/kubernetes/pkg/controller/nodeipam/config/v1alpha1" @@ -95,6 +96,8 @@ func SetDefaults_KubeControllerManagerConfiguration(obj *kubectrlmgrconfigv1alph evictionrequestconfigv1alpha1.RecommendedDefaultEvictionRequestControllerConfiguration(&obj.EvictionRequestController) // Use the default RecommendedDefaultGarbageCollectorControllerConfiguration options garbagecollectorconfigv1alpha1.RecommendedDefaultGarbageCollectorControllerConfiguration(&obj.GarbageCollectorController) + // Use the default RecommendedDefaultImperativeEvictionResponderControllerConfiguration options + imperativeevictionresponderv1alpha1.RecommendedDefaultImperativeEvictionResponderControllerConfiguration(&obj.ImperativeEvictionResponderController) // Use the default RecommendedDefaultJobControllerConfiguration options jobconfigv1alpha1.RecommendedDefaultJobControllerConfiguration(&obj.JobController) // Use the default RecommendedDefaultCronJobControllerConfiguration options diff --git a/pkg/controller/apis/config/v1alpha1/zz_generated.conversion.go b/pkg/controller/apis/config/v1alpha1/zz_generated.conversion.go index f5b396f5cc5..6bb66ecfd4e 100644 --- a/pkg/controller/apis/config/v1alpha1/zz_generated.conversion.go +++ b/pkg/controller/apis/config/v1alpha1/zz_generated.conversion.go @@ -43,6 +43,7 @@ import ( endpointslicemirroringconfigv1alpha1 "k8s.io/kubernetes/pkg/controller/endpointslicemirroring/config/v1alpha1" evictionrequestconfigv1alpha1 "k8s.io/kubernetes/pkg/controller/evictionrequest/config/v1alpha1" garbagecollectorconfigv1alpha1 "k8s.io/kubernetes/pkg/controller/garbagecollector/config/v1alpha1" + imperativeevictionresponderconfigv1alpha1 "k8s.io/kubernetes/pkg/controller/imperativeevictionresponder/config/v1alpha1" jobconfigv1alpha1 "k8s.io/kubernetes/pkg/controller/job/config/v1alpha1" namespaceconfigv1alpha1 "k8s.io/kubernetes/pkg/controller/namespace/config/v1alpha1" nodeipamconfigv1alpha1 "k8s.io/kubernetes/pkg/controller/nodeipam/config/v1alpha1" @@ -191,6 +192,9 @@ func autoConvert_v1alpha1_KubeControllerManagerConfiguration_To_config_KubeContr if err := podautoscalerconfigv1alpha1.Convert_v1alpha1_HPAControllerConfiguration_To_config_HPAControllerConfiguration(&in.HPAController, &out.HPAController, s); err != nil { return err } + if err := imperativeevictionresponderconfigv1alpha1.Convert_v1alpha1_ImperativeEvictionResponderControllerConfiguration_To_config_ImperativeEvictionResponderControllerConfiguration(&in.ImperativeEvictionResponderController, &out.ImperativeEvictionResponderController, s); err != nil { + return err + } if err := jobconfigv1alpha1.Convert_v1alpha1_JobControllerConfiguration_To_config_JobControllerConfiguration(&in.JobController, &out.JobController, s); err != nil { return err } @@ -302,6 +306,9 @@ func autoConvert_config_KubeControllerManagerConfiguration_To_v1alpha1_KubeContr if err := podautoscalerconfigv1alpha1.Convert_config_HPAControllerConfiguration_To_v1alpha1_HPAControllerConfiguration(&in.HPAController, &out.HPAController, s); err != nil { return err } + if err := imperativeevictionresponderconfigv1alpha1.Convert_config_ImperativeEvictionResponderControllerConfiguration_To_v1alpha1_ImperativeEvictionResponderControllerConfiguration(&in.ImperativeEvictionResponderController, &out.ImperativeEvictionResponderController, s); err != nil { + return err + } if err := jobconfigv1alpha1.Convert_config_JobControllerConfiguration_To_v1alpha1_JobControllerConfiguration(&in.JobController, &out.JobController, s); err != nil { return err } diff --git a/pkg/controller/apis/config/zz_generated.deepcopy.go b/pkg/controller/apis/config/zz_generated.deepcopy.go index 7be5453ad64..66fa6a31fda 100644 --- a/pkg/controller/apis/config/zz_generated.deepcopy.go +++ b/pkg/controller/apis/config/zz_generated.deepcopy.go @@ -62,6 +62,7 @@ func (in *KubeControllerManagerConfiguration) DeepCopyInto(out *KubeControllerMa out.EvictionRequestController = in.EvictionRequestController in.GarbageCollectorController.DeepCopyInto(&out.GarbageCollectorController) out.HPAController = in.HPAController + out.ImperativeEvictionResponderController = in.ImperativeEvictionResponderController out.JobController = in.JobController out.LegacySATokenCleaner = in.LegacySATokenCleaner out.NamespaceController = in.NamespaceController diff --git a/pkg/controller/imperativeevictionresponder/config/doc.go b/pkg/controller/imperativeevictionresponder/config/doc.go new file mode 100644 index 00000000000..e605045a401 --- /dev/null +++ b/pkg/controller/imperativeevictionresponder/config/doc.go @@ -0,0 +1,19 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package + +package config diff --git a/pkg/controller/imperativeevictionresponder/config/types.go b/pkg/controller/imperativeevictionresponder/config/types.go new file mode 100644 index 00000000000..7bb02c34501 --- /dev/null +++ b/pkg/controller/imperativeevictionresponder/config/types.go @@ -0,0 +1,26 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package config + +// ImperativeEvictionResponderControllerConfiguration contains elements configuring +// the imperative eviction responder controller. +type ImperativeEvictionResponderControllerConfiguration struct { + // ConcurrentImperativeEvictionResponderSyncs is the number of eviction object syncing and imperative + // eviction operations that will be done concurrently. Larger number = bigger throughput of imperative eviction + // calls (pods//eviction subresource) and faster Eviction status updating, but more CPU (and network) load. + ConcurrentImperativeEvictionResponderSyncs int32 +} diff --git a/pkg/controller/imperativeevictionresponder/config/v1alpha1/conversion.go b/pkg/controller/imperativeevictionresponder/config/v1alpha1/conversion.go new file mode 100644 index 00000000000..3a3181f0da5 --- /dev/null +++ b/pkg/controller/imperativeevictionresponder/config/v1alpha1/conversion.go @@ -0,0 +1,40 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/conversion" + "k8s.io/kube-controller-manager/config/v1alpha1" + imperativeevictionresponderconfig "k8s.io/kubernetes/pkg/controller/imperativeevictionresponder/config" +) + +// Important! The public back-and-forth conversion functions for the types in this +// package with ImperativeEvictionResponderControllerConfiguration types need to +// be manually exposed like this in order for other packages that reference this +// package to be able to call these conversion functions in an autogenerated manner. +// TODO: Fix the bug in conversion-gen so it automatically discovers these +// Convert_* functions in autogenerated code as well. + +// Convert_v1alpha1_ImperativeEvictionResponderControllerConfiguration_To_config_ImperativeEvictionResponderControllerConfiguration is an autogenerated conversion function. +func Convert_v1alpha1_ImperativeEvictionResponderControllerConfiguration_To_config_ImperativeEvictionResponderControllerConfiguration(in *v1alpha1.ImperativeEvictionResponderControllerConfiguration, out *imperativeevictionresponderconfig.ImperativeEvictionResponderControllerConfiguration, s conversion.Scope) error { + return autoConvert_v1alpha1_ImperativeEvictionResponderControllerConfiguration_To_config_ImperativeEvictionResponderControllerConfiguration(in, out, s) +} + +// Convert_config_ImperativeEvictionResponderControllerConfiguration_To_v1alpha1_ImperativeEvictionResponderControllerConfiguration is an autogenerated conversion function. +func Convert_config_ImperativeEvictionResponderControllerConfiguration_To_v1alpha1_ImperativeEvictionResponderControllerConfiguration(in *imperativeevictionresponderconfig.ImperativeEvictionResponderControllerConfiguration, out *v1alpha1.ImperativeEvictionResponderControllerConfiguration, s conversion.Scope) error { + return autoConvert_config_ImperativeEvictionResponderControllerConfiguration_To_v1alpha1_ImperativeEvictionResponderControllerConfiguration(in, out, s) +} diff --git a/pkg/controller/imperativeevictionresponder/config/v1alpha1/defaults.go b/pkg/controller/imperativeevictionresponder/config/v1alpha1/defaults.go new file mode 100644 index 00000000000..d14b20a2d06 --- /dev/null +++ b/pkg/controller/imperativeevictionresponder/config/v1alpha1/defaults.go @@ -0,0 +1,37 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + kubectrlmgrconfigv1alpha1 "k8s.io/kube-controller-manager/config/v1alpha1" +) + +// RecommendedDefaultImperativeEvictionResponderControllerConfiguration defaults +// a pointer to a ImperativeEvictionResponderControllerConfiguration struct. +// This will set the recommended default values, but they may be subject to change +// between API versions. This function is intentionally not registered in the scheme +// as a "normal" `SetDefaults_Foo` function to allow consumers of this type to set +// whatever defaults for their embedded configs. Forcing consumers to use these +// defaults would be problematic as defaulting in the scheme is done as part of the +// conversion, and there would be no easy way to opt-out. Instead, if you want +// to use this defaulting method run it in your wrapper struct of this type in +// its `SetDefaults_` method. +func RecommendedDefaultImperativeEvictionResponderControllerConfiguration(obj *kubectrlmgrconfigv1alpha1.ImperativeEvictionResponderControllerConfiguration) { + if obj.ConcurrentImperativeEvictionResponderSyncs == 0 { + obj.ConcurrentImperativeEvictionResponderSyncs = 5 + } +} diff --git a/pkg/controller/imperativeevictionresponder/config/v1alpha1/doc.go b/pkg/controller/imperativeevictionresponder/config/v1alpha1/doc.go new file mode 100644 index 00000000000..b536dd4a7bb --- /dev/null +++ b/pkg/controller/imperativeevictionresponder/config/v1alpha1/doc.go @@ -0,0 +1,21 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// +k8s:deepcopy-gen=package +// +k8s:conversion-gen=k8s.io/kubernetes/pkg/controller/imperativeevictionresponder/config +// +k8s:conversion-gen-external-types=k8s.io/kube-controller-manager/config/v1alpha1 + +package v1alpha1 diff --git a/pkg/controller/imperativeevictionresponder/config/v1alpha1/register.go b/pkg/controller/imperativeevictionresponder/config/v1alpha1/register.go new file mode 100644 index 00000000000..13a48098161 --- /dev/null +++ b/pkg/controller/imperativeevictionresponder/config/v1alpha1/register.go @@ -0,0 +1,34 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime" +) + +var ( + // SchemeBuilder is the scheme builder with scheme init functions to run for + // this API package + SchemeBuilder runtime.SchemeBuilder + // localSchemeBuilder extends the SchemeBuilder instance with the external + // types. In this package, defaulting and conversion init funcs are + // registered as well. + localSchemeBuilder = &SchemeBuilder + // AddToScheme is a global function that registers this API group & version + // to a scheme + AddToScheme = localSchemeBuilder.AddToScheme +) diff --git a/pkg/controller/imperativeevictionresponder/config/v1alpha1/zz_generated.conversion.go b/pkg/controller/imperativeevictionresponder/config/v1alpha1/zz_generated.conversion.go new file mode 100644 index 00000000000..9321d703463 --- /dev/null +++ b/pkg/controller/imperativeevictionresponder/config/v1alpha1/zz_generated.conversion.go @@ -0,0 +1,92 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by conversion-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + unsafe "unsafe" + + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + configv1alpha1 "k8s.io/kube-controller-manager/config/v1alpha1" + config "k8s.io/kubernetes/pkg/controller/imperativeevictionresponder/config" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*configv1alpha1.GroupResource)(nil), (*v1.GroupResource)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_GroupResource_To_v1_GroupResource(a.(*configv1alpha1.GroupResource), b.(*v1.GroupResource), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1.GroupResource)(nil), (*configv1alpha1.GroupResource)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1_GroupResource_To_v1alpha1_GroupResource(a.(*v1.GroupResource), b.(*configv1alpha1.GroupResource), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*config.ImperativeEvictionResponderControllerConfiguration)(nil), (*configv1alpha1.ImperativeEvictionResponderControllerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_config_ImperativeEvictionResponderControllerConfiguration_To_v1alpha1_ImperativeEvictionResponderControllerConfiguration(a.(*config.ImperativeEvictionResponderControllerConfiguration), b.(*configv1alpha1.ImperativeEvictionResponderControllerConfiguration), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*configv1alpha1.ImperativeEvictionResponderControllerConfiguration)(nil), (*config.ImperativeEvictionResponderControllerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_ImperativeEvictionResponderControllerConfiguration_To_config_ImperativeEvictionResponderControllerConfiguration(a.(*configv1alpha1.ImperativeEvictionResponderControllerConfiguration), b.(*config.ImperativeEvictionResponderControllerConfiguration), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha1_GroupResource_To_v1_GroupResource(in *configv1alpha1.GroupResource, out *v1.GroupResource, s conversion.Scope) error { + *out = *(*v1.GroupResource)(unsafe.Pointer(in)) + return nil +} + +// Convert_v1alpha1_GroupResource_To_v1_GroupResource is an autogenerated conversion function. +func Convert_v1alpha1_GroupResource_To_v1_GroupResource(in *configv1alpha1.GroupResource, out *v1.GroupResource, s conversion.Scope) error { + return autoConvert_v1alpha1_GroupResource_To_v1_GroupResource(in, out, s) +} + +func autoConvert_v1_GroupResource_To_v1alpha1_GroupResource(in *v1.GroupResource, out *configv1alpha1.GroupResource, s conversion.Scope) error { + *out = *(*configv1alpha1.GroupResource)(unsafe.Pointer(in)) + return nil +} + +// Convert_v1_GroupResource_To_v1alpha1_GroupResource is an autogenerated conversion function. +func Convert_v1_GroupResource_To_v1alpha1_GroupResource(in *v1.GroupResource, out *configv1alpha1.GroupResource, s conversion.Scope) error { + return autoConvert_v1_GroupResource_To_v1alpha1_GroupResource(in, out, s) +} + +func autoConvert_v1alpha1_ImperativeEvictionResponderControllerConfiguration_To_config_ImperativeEvictionResponderControllerConfiguration(in *configv1alpha1.ImperativeEvictionResponderControllerConfiguration, out *config.ImperativeEvictionResponderControllerConfiguration, s conversion.Scope) error { + out.ConcurrentImperativeEvictionResponderSyncs = in.ConcurrentImperativeEvictionResponderSyncs + return nil +} + +func autoConvert_config_ImperativeEvictionResponderControllerConfiguration_To_v1alpha1_ImperativeEvictionResponderControllerConfiguration(in *config.ImperativeEvictionResponderControllerConfiguration, out *configv1alpha1.ImperativeEvictionResponderControllerConfiguration, s conversion.Scope) error { + out.ConcurrentImperativeEvictionResponderSyncs = in.ConcurrentImperativeEvictionResponderSyncs + return nil +} diff --git a/pkg/controller/imperativeevictionresponder/config/zz_generated.deepcopy.go b/pkg/controller/imperativeevictionresponder/config/zz_generated.deepcopy.go new file mode 100644 index 00000000000..c171dd11010 --- /dev/null +++ b/pkg/controller/imperativeevictionresponder/config/zz_generated.deepcopy.go @@ -0,0 +1,38 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package config + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImperativeEvictionResponderControllerConfiguration) DeepCopyInto(out *ImperativeEvictionResponderControllerConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImperativeEvictionResponderControllerConfiguration. +func (in *ImperativeEvictionResponderControllerConfiguration) DeepCopy() *ImperativeEvictionResponderControllerConfiguration { + if in == nil { + return nil + } + out := new(ImperativeEvictionResponderControllerConfiguration) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/controller/imperativeevictionresponder/doc.go b/pkg/controller/imperativeevictionresponder/doc.go new file mode 100644 index 00000000000..92720e03ce3 --- /dev/null +++ b/pkg/controller/imperativeevictionresponder/doc.go @@ -0,0 +1,20 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package imperativeevictionresponder implements the built-in "imperative-eviction.k8s.io/evictor" +// responder for declarative Evictions (lifecycle.k8s.io), evicting target pods via the imperative +// pods/eviction subresource. +package imperativeevictionresponder diff --git a/pkg/controller/imperativeevictionresponder/imperative_eviction_responder_controller.go b/pkg/controller/imperativeevictionresponder/imperative_eviction_responder_controller.go new file mode 100644 index 00000000000..b22b0683fad --- /dev/null +++ b/pkg/controller/imperativeevictionresponder/imperative_eviction_responder_controller.go @@ -0,0 +1,200 @@ +/* +Copyright The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package imperativeevictionresponder + +import ( + "context" + "sync" + "time" + + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/wait" + coreinformers "k8s.io/client-go/informers/core/v1" + lifecycleinformers "k8s.io/client-go/informers/lifecycle/v1alpha1" + clientset "k8s.io/client-go/kubernetes" + corelisters "k8s.io/client-go/listers/core/v1" + lifecyclelisters "k8s.io/client-go/listers/lifecycle/v1alpha1" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/workqueue" + "k8s.io/klog/v2" + "k8s.io/utils/clock" +) + +type ImperativeEvictionResponderController struct { + controllerName string + + kubeClient clientset.Interface + + evictionLister lifecyclelisters.EvictionLister + evictionListerSynced cache.InformerSynced + + podLister corelisters.PodLister + podListerSynced cache.InformerSynced + + queue workqueue.TypedRateLimitingInterface[string] + + // syncHandler is the function called to sync an Eviction. + // It may be replaced during tests. + syncHandler func(ctx context.Context, key string) error + + // clock is used for time-based operations. + // It may be replaced during tests with a fake clock. + clock clock.PassiveClock +} + +// NewController creates a new imperative eviction responder controller. +func NewController( + ctx context.Context, + controllerName string, + evictionInformer lifecycleinformers.EvictionInformer, + podInformer coreinformers.PodInformer, + kubeClient clientset.Interface, +) (*ImperativeEvictionResponderController, error) { + logger := klog.FromContext(ctx) + + c := &ImperativeEvictionResponderController{ + controllerName: controllerName, + kubeClient: kubeClient, + evictionLister: evictionInformer.Lister(), + evictionListerSynced: evictionInformer.Informer().HasSynced, + podLister: podInformer.Lister(), + podListerSynced: podInformer.Informer().HasSynced, + queue: workqueue.NewTypedRateLimitingQueueWithConfig( + workqueue.DefaultTypedControllerRateLimiter[string](), + workqueue.TypedRateLimitingQueueConfig[string]{ + Name: controllerName, + }, + ), + clock: clock.RealClock{}, + } + + c.syncHandler = c.sync + + if _, err := evictionInformer.Informer().AddEventHandlerWithOptions(cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj any) { + c.enqueue(logger, obj) + }, + UpdateFunc: func(old, new any) { c.enqueue(logger, new) }, + DeleteFunc: func(obj any) { c.enqueue(logger, obj) }, + }, cache.HandlerOptions{Logger: &logger}); err != nil { + return nil, err + } + + if _, err := podInformer.Informer().AddEventHandlerWithOptions(cache.ResourceEventHandlerFuncs{ + UpdateFunc: func(old, new any) { + oldPod := old.(*v1.Pod) + newPod := new.(*v1.Pod) + if oldPod.DeletionTimestamp == nil && newPod.DeletionTimestamp != nil { + c.queue.Add(evictionKey(newPod)) + } + }, + DeleteFunc: func(obj any) { + c.deletePod(logger, obj) + }, + }, cache.HandlerOptions{Logger: &logger}); err != nil { + return nil, err + } + + return c, nil +} + +func (c *ImperativeEvictionResponderController) Run(ctx context.Context, workers int) { + defer utilruntime.HandleCrash() + + logger := klog.FromContext(ctx) + logger.Info("Starting", "controller", c.controllerName) + + var wg sync.WaitGroup + defer func() { + logger.Info("Shutting down", "controller", c.controllerName) + c.queue.ShutDown() + wg.Wait() + }() + + if !cache.WaitForNamedCacheSyncWithContext(ctx, c.podListerSynced, c.evictionListerSynced) { + return + } + + for range workers { + wg.Go(func() { + wait.UntilWithContext(ctx, c.runWorker, time.Second) + }) + } + + <-ctx.Done() +} + +// enqueue adds an Eviction to the queue. +func (c *ImperativeEvictionResponderController) enqueue(logger klog.Logger, obj any) { + key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj) + if err != nil { + utilruntime.HandleErrorWithLogger(logger, err, "Failed to get key for object") + return + } + c.queue.Add(key) +} + +// deletePod enqueues the Eviction for a deleted Pod. +func (c *ImperativeEvictionResponderController) deletePod(logger klog.Logger, obj any) { + pod, ok := obj.(*v1.Pod) + if !ok { + tombstone, ok := obj.(cache.DeletedFinalStateUnknown) + if !ok { + utilruntime.HandleErrorWithLogger(logger, nil, "Couldn't get object from tombstone", "object", obj) + return + } + pod, ok = tombstone.Obj.(*v1.Pod) + if !ok { + utilruntime.HandleErrorWithLogger(logger, nil, "Tombstone contained object that is not a Pod", "object", obj) + return + } + } + c.queue.Add(evictionKey(pod)) +} + +func (c *ImperativeEvictionResponderController) runWorker(ctx context.Context) { + for c.processNextWorkItem(ctx) { + } +} + +func (c *ImperativeEvictionResponderController) processNextWorkItem(ctx context.Context) bool { + key, quit := c.queue.Get() + if quit { + return false + } + defer c.queue.Done(key) + + err := c.syncHandler(ctx, key) + if err == nil { + c.queue.Forget(key) + return true + } + + utilruntime.HandleErrorWithContext(ctx, err, "Failed to sync Eviction", "key", key) + c.queue.AddRateLimited(key) + return true +} + +func (c *ImperativeEvictionResponderController) sync(ctx context.Context, key string) error { + return nil +} + +func evictionKey(pod metav1.ObjectMetaAccessor) string { + return pod.GetObjectMeta().GetNamespace() + "/" + string(pod.GetObjectMeta().GetUID()) +} diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index e8714408386..c861f5da95e 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -1520,6 +1520,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA kubecontrollermanagerconfigv1alpha1.GarbageCollectorControllerConfiguration{}.OpenAPIModelName(): schema_k8sio_kube_controller_manager_config_v1alpha1_GarbageCollectorControllerConfiguration(ref), kubecontrollermanagerconfigv1alpha1.GroupResource{}.OpenAPIModelName(): schema_k8sio_kube_controller_manager_config_v1alpha1_GroupResource(ref), kubecontrollermanagerconfigv1alpha1.HPAControllerConfiguration{}.OpenAPIModelName(): schema_k8sio_kube_controller_manager_config_v1alpha1_HPAControllerConfiguration(ref), + kubecontrollermanagerconfigv1alpha1.ImperativeEvictionResponderControllerConfiguration{}.OpenAPIModelName(): schema_k8sio_kube_controller_manager_config_v1alpha1_ImperativeEvictionResponderControllerConfiguration(ref), kubecontrollermanagerconfigv1alpha1.JobControllerConfiguration{}.OpenAPIModelName(): schema_k8sio_kube_controller_manager_config_v1alpha1_JobControllerConfiguration(ref), kubecontrollermanagerconfigv1alpha1.KubeControllerManagerConfiguration{}.OpenAPIModelName(): schema_k8sio_kube_controller_manager_config_v1alpha1_KubeControllerManagerConfiguration(ref), kubecontrollermanagerconfigv1alpha1.LegacySATokenCleanerConfiguration{}.OpenAPIModelName(): schema_k8sio_kube_controller_manager_config_v1alpha1_LegacySATokenCleanerConfiguration(ref), @@ -72214,6 +72215,28 @@ func schema_k8sio_kube_controller_manager_config_v1alpha1_HPAControllerConfigura } } +func schema_k8sio_kube_controller_manager_config_v1alpha1_ImperativeEvictionResponderControllerConfiguration(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ImperativeEvictionResponderControllerConfiguration contains elements configuring the imperative eviction responder controller.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "ConcurrentImperativeEvictionResponderSyncs": { + SchemaProps: spec.SchemaProps{ + Description: "ConcurrentImperativeEvictionResponderSyncs is the number of eviction object syncing and imperative eviction operations that will be done concurrently. Larger number = bigger throughput of imperative eviction calls (pods//eviction subresource) and faster Eviction status updating, but more CPU (and network) load.", + Default: 0, + Type: []string{"integer"}, + Format: "int32", + }, + }, + }, + Required: []string{"ConcurrentImperativeEvictionResponderSyncs"}, + }, + }, + } +} + func schema_k8sio_kube_controller_manager_config_v1alpha1_JobControllerConfiguration(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -72369,6 +72392,13 @@ func schema_k8sio_kube_controller_manager_config_v1alpha1_KubeControllerManagerC Ref: ref(kubecontrollermanagerconfigv1alpha1.HPAControllerConfiguration{}.OpenAPIModelName()), }, }, + "ImperativeEvictionResponderController": { + SchemaProps: spec.SchemaProps{ + Description: "ImperativeEvictionResponderControllerConfiguration holds configuration for ImperativeEvictionResponderController related features.", + Default: map[string]interface{}{}, + Ref: ref(kubecontrollermanagerconfigv1alpha1.ImperativeEvictionResponderControllerConfiguration{}.OpenAPIModelName()), + }, + }, "JobController": { SchemaProps: spec.SchemaProps{ Description: "JobControllerConfiguration holds configuration for JobController related features.", @@ -72489,11 +72519,11 @@ func schema_k8sio_kube_controller_manager_config_v1alpha1_KubeControllerManagerC }, }, }, - Required: []string{"Generic", "KubeCloudShared", "AttachDetachController", "CSRSigningController", "DaemonSetController", "DeploymentController", "DisruptionController", "StatefulSetController", "DeprecatedController", "EndpointController", "EndpointSliceController", "EndpointSliceMirroringController", "EphemeralVolumeController", "EvictionRequestController", "GarbageCollectorController", "HPAController", "JobController", "CronJobController", "LegacySATokenCleaner", "NamespaceController", "NodeIPAMController", "NodeLifecycleController", "PersistentVolumeBinderController", "PodGCController", "ReplicaSetController", "ReplicationController", "ResourceQuotaController", "SAController", "ServiceController", "TTLAfterFinishedController", "ValidatingAdmissionPolicyStatusController", "DeviceTaintEvictionController", "ResourceClaimController"}, + Required: []string{"Generic", "KubeCloudShared", "AttachDetachController", "CSRSigningController", "DaemonSetController", "DeploymentController", "DisruptionController", "StatefulSetController", "DeprecatedController", "EndpointController", "EndpointSliceController", "EndpointSliceMirroringController", "EphemeralVolumeController", "EvictionRequestController", "GarbageCollectorController", "HPAController", "ImperativeEvictionResponderController", "JobController", "CronJobController", "LegacySATokenCleaner", "NamespaceController", "NodeIPAMController", "NodeLifecycleController", "PersistentVolumeBinderController", "PodGCController", "ReplicaSetController", "ReplicationController", "ResourceQuotaController", "SAController", "ServiceController", "TTLAfterFinishedController", "ValidatingAdmissionPolicyStatusController", "DeviceTaintEvictionController", "ResourceClaimController"}, }, }, Dependencies: []string{ - configv1alpha1.KubeCloudSharedConfiguration{}.OpenAPIModelName(), serviceconfigv1alpha1.ServiceControllerConfiguration{}.OpenAPIModelName(), controllermanagerconfigv1alpha1.GenericControllerManagerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.AttachDetachControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.CSRSigningControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.CronJobControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.DaemonSetControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.DeploymentControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.DeprecatedControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.DeviceTaintEvictionControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.DisruptionControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.EndpointControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.EndpointSliceControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.EndpointSliceMirroringControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.EphemeralVolumeControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.EvictionRequestControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.GarbageCollectorControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.HPAControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.JobControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.LegacySATokenCleanerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.NamespaceControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.NodeIPAMControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.NodeLifecycleControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.PersistentVolumeBinderControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.PodGCControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.ReplicaSetControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.ReplicationControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.ResourceClaimControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.ResourceQuotaControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.SAControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.StatefulSetControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.TTLAfterFinishedControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.ValidatingAdmissionPolicyStatusControllerConfiguration{}.OpenAPIModelName()}, + configv1alpha1.KubeCloudSharedConfiguration{}.OpenAPIModelName(), serviceconfigv1alpha1.ServiceControllerConfiguration{}.OpenAPIModelName(), controllermanagerconfigv1alpha1.GenericControllerManagerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.AttachDetachControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.CSRSigningControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.CronJobControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.DaemonSetControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.DeploymentControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.DeprecatedControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.DeviceTaintEvictionControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.DisruptionControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.EndpointControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.EndpointSliceControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.EndpointSliceMirroringControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.EphemeralVolumeControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.EvictionRequestControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.GarbageCollectorControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.HPAControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.ImperativeEvictionResponderControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.JobControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.LegacySATokenCleanerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.NamespaceControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.NodeIPAMControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.NodeLifecycleControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.PersistentVolumeBinderControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.PodGCControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.ReplicaSetControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.ReplicationControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.ResourceClaimControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.ResourceQuotaControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.SAControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.StatefulSetControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.TTLAfterFinishedControllerConfiguration{}.OpenAPIModelName(), kubecontrollermanagerconfigv1alpha1.ValidatingAdmissionPolicyStatusControllerConfiguration{}.OpenAPIModelName()}, } } diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go index 63d6c657bb1..3241f5c5cce 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go @@ -620,6 +620,16 @@ func buildControllerRoles() ([]rbacv1.ClusterRole, []rbacv1.ClusterRoleBinding) eventsRule(), }, }) + addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "imperative-eviction-responder-controller"}, + Rules: []rbacv1.PolicyRule{ + rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("pods").RuleOrDie(), + rbacv1helpers.NewRule("get", "list", "watch").Groups(lifecycleGroup).Resources("evictions").RuleOrDie(), + rbacv1helpers.NewRule("update", "patch").Groups(lifecycleGroup).Resources("evictions/status").RuleOrDie(), + rbacv1helpers.NewRule("create").Groups(legacyGroup).Resources("pods/eviction").RuleOrDie(), + eventsRule(), + }, + }) } return controllerRoles, controllerRoleBindings diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/controller-roles-featuregates.yaml b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/controller-roles-featuregates.yaml index 17ff0e03627..0a23d52fafd 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/controller-roles-featuregates.yaml +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/controller-roles-featuregates.yaml @@ -884,6 +884,53 @@ items: - create - patch - update +- apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + annotations: + rbac.authorization.kubernetes.io/autoupdate: "true" + labels: + kubernetes.io/bootstrapping: rbac-defaults + name: system:controller:imperative-eviction-responder-controller + rules: + - apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch + - apiGroups: + - lifecycle.k8s.io + resources: + - evictions + verbs: + - get + - list + - watch + - apiGroups: + - lifecycle.k8s.io + resources: + - evictions/status + verbs: + - patch + - update + - apiGroups: + - "" + resources: + - pods/eviction + verbs: + - create + - apiGroups: + - "" + - events.k8s.io + resources: + - events + verbs: + - create + - patch + - update - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: diff --git a/staging/src/k8s.io/kube-controller-manager/config/v1alpha1/types.go b/staging/src/k8s.io/kube-controller-manager/config/v1alpha1/types.go index 4ba2dc9addd..4381eec8b09 100644 --- a/staging/src/k8s.io/kube-controller-manager/config/v1alpha1/types.go +++ b/staging/src/k8s.io/kube-controller-manager/config/v1alpha1/types.go @@ -133,6 +133,9 @@ type KubeControllerManagerConfiguration struct { GarbageCollectorController GarbageCollectorControllerConfiguration // HPAControllerConfiguration holds configuration for HPAController related features. HPAController HPAControllerConfiguration + // ImperativeEvictionResponderControllerConfiguration holds configuration for + // ImperativeEvictionResponderController related features. + ImperativeEvictionResponderController ImperativeEvictionResponderControllerConfiguration // JobControllerConfiguration holds configuration for JobController related features. JobController JobControllerConfiguration // CronJobControllerConfiguration holds configuration for CronJobController related features. @@ -369,6 +372,15 @@ type HPAControllerConfiguration struct { HorizontalPodAutoscalerInitialReadinessDelay metav1.Duration } +// ImperativeEvictionResponderControllerConfiguration contains elements configuring +// the imperative eviction responder controller. +type ImperativeEvictionResponderControllerConfiguration struct { + // ConcurrentImperativeEvictionResponderSyncs is the number of eviction object syncing and imperative + // eviction operations that will be done concurrently. Larger number = bigger throughput of imperative eviction + // calls (pods//eviction subresource) and faster Eviction status updating, but more CPU (and network) load. + ConcurrentImperativeEvictionResponderSyncs int32 +} + // JobControllerConfiguration contains elements describing JobController. type JobControllerConfiguration struct { // concurrentJobSyncs is the number of job objects that are diff --git a/staging/src/k8s.io/kube-controller-manager/config/v1alpha1/zz_generated.deepcopy.go b/staging/src/k8s.io/kube-controller-manager/config/v1alpha1/zz_generated.deepcopy.go index 1d241d09573..aa6927b37bf 100644 --- a/staging/src/k8s.io/kube-controller-manager/config/v1alpha1/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/kube-controller-manager/config/v1alpha1/zz_generated.deepcopy.go @@ -320,6 +320,22 @@ func (in *HPAControllerConfiguration) DeepCopy() *HPAControllerConfiguration { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImperativeEvictionResponderControllerConfiguration) DeepCopyInto(out *ImperativeEvictionResponderControllerConfiguration) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImperativeEvictionResponderControllerConfiguration. +func (in *ImperativeEvictionResponderControllerConfiguration) DeepCopy() *ImperativeEvictionResponderControllerConfiguration { + if in == nil { + return nil + } + out := new(ImperativeEvictionResponderControllerConfiguration) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *JobControllerConfiguration) DeepCopyInto(out *JobControllerConfiguration) { *out = *in @@ -356,6 +372,7 @@ func (in *KubeControllerManagerConfiguration) DeepCopyInto(out *KubeControllerMa out.EvictionRequestController = in.EvictionRequestController in.GarbageCollectorController.DeepCopyInto(&out.GarbageCollectorController) out.HPAController = in.HPAController + out.ImperativeEvictionResponderController = in.ImperativeEvictionResponderController out.JobController = in.JobController out.CronJobController = in.CronJobController out.LegacySATokenCleaner = in.LegacySATokenCleaner diff --git a/staging/src/k8s.io/kube-controller-manager/config/v1alpha1/zz_generated.model_name.go b/staging/src/k8s.io/kube-controller-manager/config/v1alpha1/zz_generated.model_name.go index f826c6e421d..f516ffc1582 100644 --- a/staging/src/k8s.io/kube-controller-manager/config/v1alpha1/zz_generated.model_name.go +++ b/staging/src/k8s.io/kube-controller-manager/config/v1alpha1/zz_generated.model_name.go @@ -106,6 +106,11 @@ func (in HPAControllerConfiguration) OpenAPIModelName() string { return "io.k8s.kube-controller-manager.config.v1alpha1.HPAControllerConfiguration" } +// OpenAPIModelName returns the OpenAPI model name for this type. +func (in ImperativeEvictionResponderControllerConfiguration) OpenAPIModelName() string { + return "io.k8s.kube-controller-manager.config.v1alpha1.ImperativeEvictionResponderControllerConfiguration" +} + // OpenAPIModelName returns the OpenAPI model name for this type. func (in JobControllerConfiguration) OpenAPIModelName() string { return "io.k8s.kube-controller-manager.config.v1alpha1.JobControllerConfiguration"