Skip to content

Commit f741716

Browse files
committed
Use lazy restmapper
The feature was introduced in controller-runtime 0.14.4+ allows to use lazy restmapper. The main advantage of this restmapper is that it fetches only required api resources in runtime, which highly reduces the number of http calls to the api server.
1 parent d249ac4 commit f741716

File tree

13 files changed

+76
-14
lines changed

13 files changed

+76
-14
lines changed

bootstrap/kubeadm/config/manager/manager.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ spec:
2121
args:
2222
- "--leader-elect"
2323
- "--metrics-bind-addr=localhost:8080"
24-
- "--feature-gates=MachinePool=${EXP_MACHINE_POOL:=false},KubeadmBootstrapFormatIgnition=${EXP_KUBEADM_BOOTSTRAP_FORMAT_IGNITION:=false}"
24+
- "--feature-gates=MachinePool=${EXP_MACHINE_POOL:=false},KubeadmBootstrapFormatIgnition=${EXP_KUBEADM_BOOTSTRAP_FORMAT_IGNITION:=false},LazyRestmapper=${EXP_LAZY_RESTMAPPER:=false}"
2525
- "--bootstrap-token-ttl=${KUBEADM_BOOTSTRAP_TOKEN_TTL:=15m}"
2626
image: controller:latest
2727
name: manager

bootstrap/kubeadm/main.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ import (
3030
// +kubebuilder:scaffold:imports
3131
"github.com/spf13/pflag"
3232
corev1 "k8s.io/api/core/v1"
33+
"k8s.io/apimachinery/pkg/api/meta"
3334
"k8s.io/apimachinery/pkg/runtime"
3435
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
36+
"k8s.io/client-go/rest"
3537
"k8s.io/client-go/tools/leaderelection/resourcelock"
3638
cliflag "k8s.io/component-base/cli/flag"
3739
"k8s.io/component-base/logs"
@@ -40,6 +42,7 @@ import (
4042
"k8s.io/klog/v2"
4143
ctrl "sigs.k8s.io/controller-runtime"
4244
"sigs.k8s.io/controller-runtime/pkg/client"
45+
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
4346
"sigs.k8s.io/controller-runtime/pkg/controller"
4447

4548
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
@@ -175,7 +178,7 @@ func main() {
175178
os.Exit(1)
176179
}
177180

178-
mgr, err := ctrl.NewManager(restConfig, ctrl.Options{
181+
ctrlOptions := ctrl.Options{
179182
Scheme: scheme,
180183
MetricsBindAddress: metricsBindAddr,
181184
LeaderElection: enableLeaderElection,
@@ -194,7 +197,15 @@ func main() {
194197
HealthProbeBindAddress: healthAddr,
195198
CertDir: webhookCertDir,
196199
TLSOpts: tlsOptionOverrides,
197-
})
200+
}
201+
202+
if feature.Gates.Enabled(feature.LazyRestmapper) {
203+
ctrlOptions.MapperProvider = func(c *rest.Config) (meta.RESTMapper, error) {
204+
return apiutil.NewDynamicRESTMapper(c, apiutil.WithExperimentalLazyMapper)
205+
}
206+
}
207+
208+
mgr, err := ctrl.NewManager(restConfig, ctrlOptions)
198209
if err != nil {
199210
setupLog.Error(err, "unable to start manager")
200211
os.Exit(1)

config/manager/manager.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ spec:
2222
args:
2323
- "--leader-elect"
2424
- "--metrics-bind-addr=localhost:8080"
25-
- "--feature-gates=MachinePool=${EXP_MACHINE_POOL:=false},ClusterResourceSet=${EXP_CLUSTER_RESOURCE_SET:=false},ClusterTopology=${CLUSTER_TOPOLOGY:=false},RuntimeSDK=${EXP_RUNTIME_SDK:=false}"
25+
- "--feature-gates=MachinePool=${EXP_MACHINE_POOL:=false},ClusterResourceSet=${EXP_CLUSTER_RESOURCE_SET:=false},ClusterTopology=${CLUSTER_TOPOLOGY:=false},RuntimeSDK=${EXP_RUNTIME_SDK:=false},LazyRestmapper=${EXP_LAZY_RESTMAPPER:=false}"
2626
image: controller:latest
2727
name: manager
2828
env:

controllers/remote/cluster_cache_tracker.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import (
4747
"sigs.k8s.io/controller-runtime/pkg/source"
4848

4949
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
50+
"sigs.k8s.io/cluster-api/feature"
5051
"sigs.k8s.io/cluster-api/util/conditions"
5152
)
5253

@@ -370,8 +371,15 @@ func (t *ClusterCacheTracker) runningOnWorkloadCluster(ctx context.Context, c cl
370371

371372
// createClient creates a client and a mapper based on a rest.Config.
372373
func (t *ClusterCacheTracker) createClient(config *rest.Config, cluster client.ObjectKey) (client.Client, meta.RESTMapper, error) {
374+
var mapper meta.RESTMapper
375+
var err error
376+
373377
// Create a mapper for it
374-
mapper, err := apiutil.NewDynamicRESTMapper(config)
378+
if !feature.Gates.Enabled(feature.LazyRestmapper) {
379+
mapper, err = apiutil.NewDynamicRESTMapper(config)
380+
} else {
381+
mapper, err = apiutil.NewDynamicRESTMapper(config, apiutil.WithExperimentalLazyMapper)
382+
}
375383
if err != nil {
376384
return nil, nil, errors.Wrapf(err, "error creating dynamic rest mapper for remote cluster %q", cluster.String())
377385
}

controlplane/kubeadm/config/manager/manager.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ spec:
2121
args:
2222
- "--leader-elect"
2323
- "--metrics-bind-addr=localhost:8080"
24-
- "--feature-gates=ClusterTopology=${CLUSTER_TOPOLOGY:=false},KubeadmBootstrapFormatIgnition=${EXP_KUBEADM_BOOTSTRAP_FORMAT_IGNITION:=false}"
24+
- "--feature-gates=ClusterTopology=${CLUSTER_TOPOLOGY:=false},KubeadmBootstrapFormatIgnition=${EXP_KUBEADM_BOOTSTRAP_FORMAT_IGNITION:=false},LazyRestmapper=${EXP_LAZY_RESTMAPPER:=false}"
2525
image: controller:latest
2626
name: manager
2727
env:

controlplane/kubeadm/main.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@ import (
3232
appsv1 "k8s.io/api/apps/v1"
3333
corev1 "k8s.io/api/core/v1"
3434
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
35+
"k8s.io/apimachinery/pkg/api/meta"
3536
"k8s.io/apimachinery/pkg/runtime"
3637
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
38+
"k8s.io/client-go/rest"
3739
"k8s.io/client-go/tools/leaderelection/resourcelock"
3840
cliflag "k8s.io/component-base/cli/flag"
3941
"k8s.io/component-base/logs"
@@ -42,6 +44,7 @@ import (
4244
"k8s.io/klog/v2"
4345
ctrl "sigs.k8s.io/controller-runtime"
4446
"sigs.k8s.io/controller-runtime/pkg/client"
47+
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
4548
"sigs.k8s.io/controller-runtime/pkg/controller"
4649

4750
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
@@ -184,7 +187,7 @@ func main() {
184187
os.Exit(1)
185188
}
186189

187-
mgr, err := ctrl.NewManager(restConfig, ctrl.Options{
190+
ctrlOptions := ctrl.Options{
188191
Scheme: scheme,
189192
MetricsBindAddress: metricsBindAddr,
190193
LeaderElection: enableLeaderElection,
@@ -203,7 +206,15 @@ func main() {
203206
HealthProbeBindAddress: healthAddr,
204207
CertDir: webhookCertDir,
205208
TLSOpts: tlsOptionOverrides,
206-
})
209+
}
210+
211+
if feature.Gates.Enabled(feature.LazyRestmapper) {
212+
ctrlOptions.MapperProvider = func(c *rest.Config) (meta.RESTMapper, error) {
213+
return apiutil.NewDynamicRESTMapper(c, apiutil.WithExperimentalLazyMapper)
214+
}
215+
}
216+
217+
mgr, err := ctrl.NewManager(restConfig, ctrlOptions)
207218
if err != nil {
208219
setupLog.Error(err, "unable to start manager")
209220
os.Exit(1)

docs/book/src/developer/testing.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ kustomize_substitutions:
267267
EXP_CLUSTER_RESOURCE_SET: "true"
268268
EXP_KUBEADM_BOOTSTRAP_FORMAT_IGNITION: "true"
269269
EXP_RUNTIME_SDK: "true"
270+
EXP_LAZY_RESTMAPPER: "true"
270271
```
271272
272273
</aside>

docs/book/src/developer/tilt.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ kustomize_substitutions:
110110
EXP_CLUSTER_RESOURCE_SET: "true"
111111
EXP_KUBEADM_BOOTSTRAP_FORMAT_IGNITION: "true"
112112
EXP_RUNTIME_SDK: "true"
113+
EXP_LAZY_RESTMAPPER: "true"
113114
```
114115

115116
{{#tabs name:"tab-tilt-kustomize-substitution" tabs:"AWS,Azure,DigitalOcean,GCP,vSphere"}}

docs/book/src/tasks/experimental-features/experimental-features.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ variables:
3434
EXP_MACHINE_POOL: "true"
3535
CLUSTER_TOPOLOGY: "true"
3636
EXP_RUNTIME_SDK: "true"
37+
EXP_LAZY_RESTMAPPER: "true"
3738
```
3839

3940
Another way is to set them as environmental variables before running e2e tests.
@@ -48,6 +49,7 @@ kustomize_substitutions:
4849
EXP_MACHINE_POOL: 'true'
4950
CLUSTER_TOPOLOGY: 'true'
5051
EXP_RUNTIME_SDK: 'true'
52+
EXP_LAZY_RESTMAPPER: 'true'
5153
```
5254

5355
For more details on setting up a development environment with `tilt`, see [Developing Cluster API with Tilt](../../developer/tilt.md)
@@ -60,10 +62,10 @@ To enable/disable features on existing management clusters, users can modify CAP
6062
kubectl edit -n capi-system deployment.apps/capi-controller-manager
6163
```
6264
```
63-
// Enable/disable available feautures by modifying Args below.
65+
// Enable/disable available features by modifying Args below.
6466
Args:
6567
--leader-elect
66-
--feature-gates=MachinePool=true,ClusterResourceSet=true
68+
--feature-gates=MachinePool=true,ClusterResourceSet=true,LazyRestmapper=true
6769
```
6870
6971
Similarly, to **validate** if a particular feature is enabled, see cluster-api-provider deployment arguments by:

internal/test/envtest/environment.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
corev1 "k8s.io/api/core/v1"
3636
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
3737
apierrors "k8s.io/apimachinery/pkg/api/errors"
38+
"k8s.io/apimachinery/pkg/api/meta"
3839
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3940
kerrors "k8s.io/apimachinery/pkg/util/errors"
4041
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
@@ -45,6 +46,7 @@ import (
4546
"k8s.io/klog/v2/klogr"
4647
ctrl "sigs.k8s.io/controller-runtime"
4748
"sigs.k8s.io/controller-runtime/pkg/client"
49+
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
4850
"sigs.k8s.io/controller-runtime/pkg/envtest"
4951
"sigs.k8s.io/controller-runtime/pkg/manager"
5052

@@ -255,6 +257,9 @@ func newEnvironment(uncachedObjs ...client.Object) *Environment {
255257
Port: env.WebhookInstallOptions.LocalServingPort,
256258
ClientDisableCacheFor: objs,
257259
Host: host,
260+
MapperProvider: func(c *rest.Config) (meta.RESTMapper, error) {
261+
return apiutil.NewDynamicRESTMapper(c, apiutil.WithExperimentalLazyMapper)
262+
},
258263
}
259264

260265
mgr, err := ctrl.NewManager(env.Config, options)

0 commit comments

Comments
 (0)