From 8b55bdc405caccbedb5d653ba41cff333b0b3e5c Mon Sep 17 00:00:00 2001 From: David Eads Date: Tue, 2 Mar 2021 16:38:22 -0500 Subject: [PATCH] increase discovery burst for kube-controller-manager --- .../app/controllermanager.go | 4 +-- cmd/kube-controller-manager/app/core.go | 6 ++-- cmd/kube-controller-manager/app/core_test.go | 11 ++++++++ .../pkg/clientbuilder/client_builder.go | 28 +++++++++++++++++++ .../clientbuilder/client_builder_dynamic.go | 21 ++++++++++++++ 5 files changed, 66 insertions(+), 4 deletions(-) diff --git a/cmd/kube-controller-manager/app/controllermanager.go b/cmd/kube-controller-manager/app/controllermanager.go index 74713640102..e1455969de0 100644 --- a/cmd/kube-controller-manager/app/controllermanager.go +++ b/cmd/kube-controller-manager/app/controllermanager.go @@ -466,8 +466,8 @@ func CreateControllerContext(s *config.CompletedConfig, rootClientBuilder, clien } // Use a discovery client capable of being refreshed. - discoveryClient := rootClientBuilder.ClientOrDie("controller-discovery") - cachedClient := cacheddiscovery.NewMemCacheClient(discoveryClient.Discovery()) + discoveryClient := rootClientBuilder.DiscoveryClientOrDie("controller-discovery") + cachedClient := cacheddiscovery.NewMemCacheClient(discoveryClient) restMapper := restmapper.NewDeferredDiscoveryRESTMapper(cachedClient) go wait.Until(func() { restMapper.Reset() diff --git a/cmd/kube-controller-manager/app/core.go b/cmd/kube-controller-manager/app/core.go index a7775cdf7c3..9391cb6ed6b 100644 --- a/cmd/kube-controller-manager/app/core.go +++ b/cmd/kube-controller-manager/app/core.go @@ -441,7 +441,8 @@ func startPodGCController(ctx ControllerContext) (http.Handler, bool, error) { func startResourceQuotaController(ctx ControllerContext) (http.Handler, bool, error) { resourceQuotaControllerClient := ctx.ClientBuilder.ClientOrDie("resourcequota-controller") - discoveryFunc := resourceQuotaControllerClient.Discovery().ServerPreferredNamespacedResources + resourceQuotaControllerDiscoveryClient := ctx.ClientBuilder.DiscoveryClientOrDie("resourcequota-controller") + discoveryFunc := resourceQuotaControllerDiscoveryClient.ServerPreferredNamespacedResources listerFuncForResource := generic.ListerFuncForResourceFunc(ctx.InformerFactory.ForResource) quotaConfiguration := quotainstall.NewQuotaConfigurationForControllers(listerFuncForResource) @@ -535,6 +536,7 @@ func startGarbageCollectorController(ctx ControllerContext) (http.Handler, bool, } gcClientset := ctx.ClientBuilder.ClientOrDie("generic-garbage-collector") + discoveryClient := ctx.ClientBuilder.DiscoveryClientOrDie("generic-garbage-collector") config := ctx.ClientBuilder.ConfigOrDie("generic-garbage-collector") metadataClient, err := metadata.NewForConfig(config) @@ -564,7 +566,7 @@ func startGarbageCollectorController(ctx ControllerContext) (http.Handler, bool, // Periodically refresh the RESTMapper with new discovery information and sync // the garbage collector. - go garbageCollector.Sync(gcClientset.Discovery(), 30*time.Second, ctx.Stop) + go garbageCollector.Sync(discoveryClient, 30*time.Second, ctx.Stop) return garbagecollector.NewDebugHandler(garbageCollector), true, nil } diff --git a/cmd/kube-controller-manager/app/core_test.go b/cmd/kube-controller-manager/app/core_test.go index 88bd8614d20..3645edc8211 100644 --- a/cmd/kube-controller-manager/app/core_test.go +++ b/cmd/kube-controller-manager/app/core_test.go @@ -45,6 +45,17 @@ func (m TestClientBuilder) ClientOrDie(name string) clientset.Interface { return m.clientset } +func (m TestClientBuilder) DiscoveryClient(name string) (discovery.DiscoveryInterface, error) { + return m.clientset.Discovery(), nil +} +func (m TestClientBuilder) DiscoveryClientOrDie(name string) discovery.DiscoveryInterface { + ret, err := m.DiscoveryClient(name) + if err != nil { + panic(err) + } + return ret +} + // FakeDiscoveryWithError inherits DiscoveryInterface(via FakeDiscovery) with some methods accepting testing data. type FakeDiscoveryWithError struct { fakediscovery.FakeDiscovery diff --git a/staging/src/k8s.io/controller-manager/pkg/clientbuilder/client_builder.go b/staging/src/k8s.io/controller-manager/pkg/clientbuilder/client_builder.go index 437e0f9ffa2..3f2282c2144 100644 --- a/staging/src/k8s.io/controller-manager/pkg/clientbuilder/client_builder.go +++ b/staging/src/k8s.io/controller-manager/pkg/clientbuilder/client_builder.go @@ -17,6 +17,7 @@ limitations under the License. package clientbuilder import ( + "k8s.io/client-go/discovery" clientset "k8s.io/client-go/kubernetes" restclient "k8s.io/client-go/rest" "k8s.io/klog/v2" @@ -30,6 +31,8 @@ type ControllerClientBuilder interface { ConfigOrDie(name string) *restclient.Config Client(name string) (clientset.Interface, error) ClientOrDie(name string) clientset.Interface + DiscoveryClient(name string) (discovery.DiscoveryInterface, error) + DiscoveryClientOrDie(name string) discovery.DiscoveryInterface } // SimpleControllerClientBuilder returns a fixed client with different user agents @@ -72,3 +75,28 @@ func (b SimpleControllerClientBuilder) ClientOrDie(name string) clientset.Interf } return client } + +// DiscoveryClientOrDie returns a discovery.DiscoveryInterface built from the ClientBuilder +// Discovery is special because it will artificially pump the burst quite high to handle the many discovery requests. +func (b SimpleControllerClientBuilder) DiscoveryClient(name string) (discovery.DiscoveryInterface, error) { + clientConfig, err := b.Config(name) + if err != nil { + return nil, err + } + // Discovery makes a lot of requests infrequently. This allows the burst to succeed and refill to happen + // in just a few seconds. + clientConfig.Burst = 200 + clientConfig.QPS = 20 + return clientset.NewForConfig(clientConfig) +} + +// DiscoveryClientOrDie returns a discovery.DiscoveryInterface built from the ClientBuilder with no error. +// Discovery is special because it will artificially pump the burst quite high to handle the many discovery requests. +// If it gets an error getting the client, it will log the error and kill the process it's running in. +func (b SimpleControllerClientBuilder) DiscoveryClientOrDie(name string) discovery.DiscoveryInterface { + client, err := b.DiscoveryClient(name) + if err != nil { + klog.Fatal(err) + } + return client +} diff --git a/staging/src/k8s.io/controller-manager/pkg/clientbuilder/client_builder_dynamic.go b/staging/src/k8s.io/controller-manager/pkg/clientbuilder/client_builder_dynamic.go index 7c03ebef9b0..00f925cc7b8 100644 --- a/staging/src/k8s.io/controller-manager/pkg/clientbuilder/client_builder_dynamic.go +++ b/staging/src/k8s.io/controller-manager/pkg/clientbuilder/client_builder_dynamic.go @@ -31,6 +31,7 @@ import ( "k8s.io/apimachinery/pkg/util/clock" "k8s.io/apimachinery/pkg/util/wait" apiserverserviceaccount "k8s.io/apiserver/pkg/authentication/serviceaccount" + "k8s.io/client-go/discovery" clientset "k8s.io/client-go/kubernetes" v1core "k8s.io/client-go/kubernetes/typed/core/v1" restclient "k8s.io/client-go/rest" @@ -155,6 +156,26 @@ func (t *DynamicControllerClientBuilder) ClientOrDie(name string) clientset.Inte return client } +func (t *DynamicControllerClientBuilder) DiscoveryClient(name string) (discovery.DiscoveryInterface, error) { + clientConfig, err := t.Config(name) + if err != nil { + return nil, err + } + // Discovery makes a lot of requests infrequently. This allows the burst to succeed and refill to happen + // in just a few seconds. + clientConfig.Burst = 200 + clientConfig.QPS = 20 + return clientset.NewForConfig(clientConfig) +} + +func (t *DynamicControllerClientBuilder) DiscoveryClientOrDie(name string) discovery.DiscoveryInterface { + client, err := t.DiscoveryClient(name) + if err != nil { + klog.Fatal(err) + } + return client +} + type tokenSourceImpl struct { namespace string serviceAccountName string