Skip to content

Commit 52d5ec7

Browse files
authored
Merge pull request #1371 from vincepri/expose-controller-componentconfig
⚠️ Support global controller options in component config
2 parents a763c9a + 82fc256 commit 52d5ec7

File tree

6 files changed

+136
-1
lines changed

6 files changed

+136
-1
lines changed

pkg/builder/controller.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,8 @@ func (blder *Builder) getControllerName(gvk schema.GroupVersionKind) string {
287287
}
288288

289289
func (blder *Builder) doController(r reconcile.Reconciler) error {
290+
globalOpts := blder.mgr.GetControllerOptions()
291+
290292
ctrlOptions := blder.ctrlOptions
291293
if ctrlOptions.Reconciler == nil {
292294
ctrlOptions.Reconciler = r
@@ -299,6 +301,20 @@ func (blder *Builder) doController(r reconcile.Reconciler) error {
299301
return err
300302
}
301303

304+
// Setup concurrency.
305+
if ctrlOptions.MaxConcurrentReconciles == 0 {
306+
groupKind := gvk.GroupKind().String()
307+
308+
if concurrency, ok := globalOpts.GroupKindConcurrency[groupKind]; ok && concurrency > 0 {
309+
ctrlOptions.MaxConcurrentReconciles = concurrency
310+
}
311+
}
312+
313+
// Setup cache sync timeout.
314+
if ctrlOptions.CacheSyncTimeout == 0 && globalOpts.CacheSyncTimeout != nil {
315+
ctrlOptions.CacheSyncTimeout = *globalOpts.CacheSyncTimeout
316+
}
317+
302318
// Setup the logger.
303319
if ctrlOptions.Log == nil {
304320
ctrlOptions.Log = blder.mgr.GetLogger()

pkg/builder/controller_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import (
3636

3737
"sigs.k8s.io/controller-runtime/pkg/cache"
3838
"sigs.k8s.io/controller-runtime/pkg/client"
39+
"sigs.k8s.io/controller-runtime/pkg/config/v1alpha1"
3940
"sigs.k8s.io/controller-runtime/pkg/controller"
4041
"sigs.k8s.io/controller-runtime/pkg/event"
4142
"sigs.k8s.io/controller-runtime/pkg/handler"
@@ -172,6 +173,34 @@ var _ = Describe("application", func() {
172173
Expect(instance).NotTo(BeNil())
173174
})
174175

176+
It("should override max concurrent reconcilers during creation of controller, when using", func() {
177+
const maxConcurrentReconciles = 10
178+
newController = func(name string, mgr manager.Manager, options controller.Options) (
179+
controller.Controller, error) {
180+
if options.MaxConcurrentReconciles == maxConcurrentReconciles {
181+
return controller.New(name, mgr, options)
182+
}
183+
return nil, fmt.Errorf("max concurrent reconcilers expected %d but found %d", maxConcurrentReconciles, options.MaxConcurrentReconciles)
184+
}
185+
186+
By("creating a controller manager")
187+
m, err := manager.New(cfg, manager.Options{
188+
Controller: v1alpha1.ControllerConfigurationSpec{
189+
GroupKindConcurrency: map[string]int{
190+
"ReplicaSet.apps": maxConcurrentReconciles,
191+
},
192+
},
193+
})
194+
Expect(err).NotTo(HaveOccurred())
195+
196+
instance, err := ControllerManagedBy(m).
197+
For(&appsv1.ReplicaSet{}).
198+
Owns(&appsv1.ReplicaSet{}).
199+
Build(noop)
200+
Expect(err).NotTo(HaveOccurred())
201+
Expect(instance).NotTo(BeNil())
202+
})
203+
175204
It("should override rate limiter during creation of controller", func() {
176205
rateLimiter := workqueue.DefaultItemBasedRateLimiter()
177206
newController = func(name string, mgr manager.Manager, options controller.Options) (controller.Controller, error) {

pkg/config/v1alpha1/types.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ limitations under the License.
1717
package v1alpha1
1818

1919
import (
20+
"time"
21+
2022
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2123

2224
configv1alpha1 "k8s.io/component-base/config/v1alpha1"
@@ -50,9 +52,14 @@ type ControllerManagerConfigurationSpec struct {
5052
// GracefulShutdownTimeout is the duration given to runnable to stop before the manager actually returns on stop.
5153
// To disable graceful shutdown, set to time.Duration(0)
5254
// To use graceful shutdown without timeout, set to a negative duration, e.G. time.Duration(-1)
53-
// The graceful shutdown is skipped for safety reasons in case the leadere election lease is lost.
55+
// The graceful shutdown is skipped for safety reasons in case the leader election lease is lost.
5456
GracefulShutdownTimeout *metav1.Duration `json:"gracefulShutDown,omitempty"`
5557

58+
// Controller contains global configuration options for controllers
59+
// registered within this manager.
60+
// +optional
61+
Controller *ControllerConfigurationSpec `json:"controller,omitempty"`
62+
5663
// Metrics contains thw controller metrics configuration
5764
// +optional
5865
Metrics ControllerMetrics `json:"metrics,omitempty"`
@@ -66,6 +73,29 @@ type ControllerManagerConfigurationSpec struct {
6673
Webhook ControllerWebhook `json:"webhook,omitempty"`
6774
}
6875

76+
// ControllerConfigurationSpec defines the global configuration for
77+
// controllers registered with the manager.
78+
type ControllerConfigurationSpec struct {
79+
// GroupKindConcurrency is a map from a Kind to the number of concurrent reconciliation
80+
// allowed for that controller.
81+
//
82+
// When a controller is registered within this manager using the builder utilities,
83+
// users have to specify the type the controller reconciles in the For(...) call.
84+
// If the object's kind passed matches one of the keys in this map, the concurrency
85+
// for that controller is set to the number specified.
86+
//
87+
// The key is expected to be consistent in form with GroupKind.String(),
88+
// e.g. ReplicaSet in apps group (regardless of version) would be `ReplicaSet.apps`.
89+
//
90+
// +optional
91+
GroupKindConcurrency map[string]int `json:"groupKindConcurrency,omitempty"`
92+
93+
// CacheSyncTimeout refers to the time limit set to wait for syncing caches.
94+
// Defaults to 2 minutes if not set.
95+
// +optional
96+
CacheSyncTimeout *time.Duration `json:"cacheSyncTimeout,omitempty"`
97+
}
98+
6999
// ControllerMetrics defines the metrics configs
70100
type ControllerMetrics struct {
71101
// BindAddress is the TCP address that the controller should bind to

pkg/config/v1alpha1/zz_generated.deepcopy.go

Lines changed: 33 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/manager/internal.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import (
3838
"sigs.k8s.io/controller-runtime/pkg/cache"
3939
"sigs.k8s.io/controller-runtime/pkg/client"
4040
"sigs.k8s.io/controller-runtime/pkg/cluster"
41+
"sigs.k8s.io/controller-runtime/pkg/config/v1alpha1"
4142
"sigs.k8s.io/controller-runtime/pkg/healthz"
4243
intrec "sigs.k8s.io/controller-runtime/pkg/internal/recorder"
4344
"sigs.k8s.io/controller-runtime/pkg/metrics"
@@ -108,6 +109,9 @@ type controllerManager struct {
108109
healthzStarted bool
109110
errChan chan error
110111

112+
// controllerOptions are the global controller options.
113+
controllerOptions v1alpha1.ControllerConfigurationSpec
114+
111115
// Logger is the logger that should be used by this manager.
112116
// If none is set, it defaults to log.Log global logger.
113117
logger logr.Logger
@@ -355,6 +359,10 @@ func (cm *controllerManager) GetLogger() logr.Logger {
355359
return cm.logger
356360
}
357361

362+
func (cm *controllerManager) GetControllerOptions() v1alpha1.ControllerConfigurationSpec {
363+
return cm.controllerOptions
364+
}
365+
358366
func (cm *controllerManager) serveMetrics() {
359367
handler := promhttp.HandlerFor(metrics.Registry, promhttp.HandlerOpts{
360368
ErrorHandling: promhttp.HTTPErrorOnError,

pkg/manager/manager.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ type Manager interface {
9090

9191
// GetLogger returns this manager's logger.
9292
GetLogger() logr.Logger
93+
94+
// GetControllerOptions returns controller global configuration options.
95+
GetControllerOptions() v1alpha1.ControllerConfigurationSpec
9396
}
9497

9598
// Options are the arguments for creating a new Manager
@@ -230,6 +233,11 @@ type Options struct {
230233
// The graceful shutdown is skipped for safety reasons in case the leader election lease is lost.
231234
GracefulShutdownTimeout *time.Duration
232235

236+
// Controller contains global configuration options for controllers
237+
// registered within this manager.
238+
// +optional
239+
Controller v1alpha1.ControllerConfigurationSpec
240+
233241
// makeBroadcaster allows deferring the creation of the broadcaster to
234242
// avoid leaking goroutines if we never call Start on this manager. It also
235243
// returns whether or not this is a "owned" broadcaster, and as such should be
@@ -337,6 +345,7 @@ func New(config *rest.Config, options Options) (Manager, error) {
337345
resourceLock: resourceLock,
338346
metricsListener: metricsListener,
339347
metricsExtraHandlers: metricsExtraHandlers,
348+
controllerOptions: options.Controller,
340349
logger: options.Logger,
341350
elected: make(chan struct{}),
342351
port: options.Port,
@@ -407,6 +416,16 @@ func (o Options) AndFrom(loader config.ControllerManagerConfiguration) (Options,
407416
o.CertDir = newObj.Webhook.CertDir
408417
}
409418

419+
if newObj.Controller != nil {
420+
if o.Controller.CacheSyncTimeout == nil && newObj.Controller.CacheSyncTimeout != nil {
421+
o.Controller.CacheSyncTimeout = newObj.Controller.CacheSyncTimeout
422+
}
423+
424+
if len(o.Controller.GroupKindConcurrency) == 0 && len(newObj.Controller.GroupKindConcurrency) > 0 {
425+
o.Controller.GroupKindConcurrency = newObj.Controller.GroupKindConcurrency
426+
}
427+
}
428+
410429
return o, nil
411430
}
412431

0 commit comments

Comments
 (0)