Skip to content
This repository was archived by the owner on Apr 25, 2023. It is now read-only.

Commit 0541f43

Browse files
authored
Merge pull request #1400 from zqzten/feat/concurrent_reconciles
feat: make concurrency of the worker configurable
2 parents ad65b8c + 661df5d commit 0541f43

File tree

23 files changed

+207
-33
lines changed

23 files changed

+207
-33
lines changed

.gitignore

+7
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,10 @@
66
# Ignore binaries built by the makefile to avoid accidentally committing them
77
/images/kubefed/hyperfed
88
/images/kubefed/controller-manager
9+
10+
# editor and IDE paraphernalia
11+
.idea
12+
.vscode
13+
14+
# macOS paraphernalia
15+
.DS_Store

charts/kubefed/README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ chart and their default values.
123123
| controllermanager.clusterHealthCheckFailureThreshold | Minimum consecutive failures for the cluster health to be considered failed after having succeeded. | 3 |
124124
| controllermanager.clusterHealthCheckSuccessThreshold | Minimum consecutive successes for the cluster health to be considered successful after having failed. | 1 |
125125
| controllermanager.clusterHealthCheckTimeout | Duration after which the cluster health check times out. | 3s |
126-
| controllermanager.syncController.adoptResources | Whether to adopt pre-existing resource in member clusters. | Enabled |
126+
| controllermanager.syncController.maxConcurrentReconciles | The maximum number of concurrent Reconciles of sync controller which can be run. | 1 |
127+
| controllermanager.syncController.adoptResources | Whether to adopt pre-existing resource in member clusters. | Enabled |
128+
| controllermanager.statusController.maxConcurrentReconciles | The maximum number of concurrent Reconciles of status controller which can be run. | 1 |
127129
| controllermanager.service.labels | Kubernetes labels attached to the controller manager's services | {} |
128130
| controllermanager.certManager.enabled | Specifies whether to enable the usage of the cert-manager for the certificates generation. | false |
129131
| controllermanager.certManager.rootCertificate.organizations | Specifies the list of organizations to include in the cert-manager generated root certificate. | [] |

charts/kubefed/charts/controllermanager/crds/crds.yaml

+13
Original file line numberDiff line numberDiff line change
@@ -692,12 +692,25 @@ spec:
692692
`Namespaced` or `Cluster`. `Namespaced` indicates that the KubeFed
693693
namespace will be the only target of the control plane.
694694
type: string
695+
statusController:
696+
properties:
697+
maxConcurrentReconciles:
698+
description: The maximum number of concurrent Reconciles of status
699+
controller which can be run. Defaults to 1.
700+
format: int64
701+
type: integer
702+
type: object
695703
syncController:
696704
properties:
697705
adoptResources:
698706
description: Whether to adopt pre-existing resources in member
699707
clusters. Defaults to "Enabled".
700708
type: string
709+
maxConcurrentReconciles:
710+
description: The maximum number of concurrent Reconciles of sync
711+
controller which can be run. Defaults to 1.
712+
format: int64
713+
type: integer
701714
type: object
702715
required:
703716
- scope

charts/kubefed/charts/controllermanager/templates/kubefedconfig.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ spec:
1919
successThreshold: {{ .Values.clusterHealthCheckSuccessThreshold | default 1 }}
2020
timeout: {{ .Values.clusterHealthCheckTimeout | default "3s" | quote }}
2121
syncController:
22+
maxConcurrentReconciles: {{ .Values.syncController.maxConcurrentReconciles | default 1 }}
2223
adoptResources: {{ .Values.syncController.adoptResources | default "Enabled" | quote }}
24+
statusController:
25+
maxConcurrentReconciles: {{ .Values.statusController.maxConcurrentReconciles | default 1 }}
2326
featureGates:
2427
{{- if .Values.featureGates }}
2528
- name: PushReconciler

charts/kubefed/values.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ controllermanager:
1818
## Supported options are `configmaps` and `endpoints`
1919
leaderElectResourceLock:
2020
syncController:
21+
maxConcurrentReconciles:
2122
adoptResources:
23+
statusController:
24+
maxConcurrentReconciles:
2225
## Value of feature gates item should be either `Enabled` or `Disabled`
2326
featureGates:
2427
PushReconciler:

cmd/controller-manager/app/controller-manager.go

+3
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,9 @@ func setOptionsByKubeFedConfig(opts *options.Options) {
365365
opts.ClusterHealthCheckConfig.FailureThreshold = *spec.ClusterHealthCheck.FailureThreshold
366366
opts.ClusterHealthCheckConfig.SuccessThreshold = *spec.ClusterHealthCheck.SuccessThreshold
367367

368+
opts.Config.MaxConcurrentSyncReconciles = *spec.SyncController.MaxConcurrentReconciles
369+
opts.Config.MaxConcurrentStatusReconciles = *spec.StatusController.MaxConcurrentReconciles
370+
368371
opts.Config.SkipAdoptingResources = *spec.SyncController.AdoptResources == corev1b1.AdoptResourcesDisabled
369372

370373
var featureGates = make(map[string]bool)

config/kubefedconfig.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,7 @@ spec:
2626
successThreshold: 1
2727
timeout: 3s
2828
syncController:
29+
maxConcurrentReconciles: 1
2930
adoptResources: Enabled
31+
statusController:
32+
maxConcurrentReconciles: 1

pkg/apis/core/v1beta1/defaults/defaults.go

+11
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ const (
3939
DefaultClusterHealthCheckFailureThreshold = 3
4040
DefaultClusterHealthCheckSuccessThreshold = 1
4141
DefaultClusterHealthCheckTimeout = 3 * time.Second
42+
43+
DefaultSyncControllerMaxConcurrentReconciles = 1
44+
DefaultStatusControllerMaxConcurrentReconciles = 1
4245
)
4346

4447
func SetDefaultKubeFedConfig(fedConfig *v1beta1.KubeFedConfig) {
@@ -87,10 +90,18 @@ func SetDefaultKubeFedConfig(fedConfig *v1beta1.KubeFedConfig) {
8790
spec.SyncController = &v1beta1.SyncControllerConfig{}
8891
}
8992

93+
setInt64(&spec.SyncController.MaxConcurrentReconciles, DefaultSyncControllerMaxConcurrentReconciles)
94+
9095
if spec.SyncController.AdoptResources == nil {
9196
spec.SyncController.AdoptResources = new(v1beta1.ResourceAdoption)
9297
*spec.SyncController.AdoptResources = v1beta1.AdoptResourcesEnabled
9398
}
99+
100+
if spec.StatusController == nil {
101+
spec.StatusController = &v1beta1.StatusControllerConfig{}
102+
}
103+
104+
setInt64(&spec.StatusController.MaxConcurrentReconciles, DefaultStatusControllerMaxConcurrentReconciles)
94105
}
95106

96107
func setDefaultKubeFedFeatureGates(fgc []v1beta1.FeatureGatesConfig) []v1beta1.FeatureGatesConfig {

pkg/apis/core/v1beta1/defaults/defaults_test.go

+16-1
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,26 @@ func TestSetDefaultKubeFedConfig(t *testing.T) {
120120
successCases["spec.clusterHealthCheck.timeout is preserved"] = KubeFedConfigComparison{timeoutKFC, modifiedTimeoutKFC}
121121

122122
// SyncController
123+
syncControllerMaxConcurrentReconcilesKFC := defaultKubeFedConfig()
124+
syncControllerMaxConcurrentReconciles := int64(DefaultSyncControllerMaxConcurrentReconciles + 3)
125+
syncControllerMaxConcurrentReconcilesKFC.Spec.SyncController.MaxConcurrentReconciles = &syncControllerMaxConcurrentReconciles
126+
modifiedSyncControllerMaxConcurrentReconcilesKFC := syncControllerMaxConcurrentReconcilesKFC.DeepCopyObject().(*v1beta1.KubeFedConfig)
127+
SetDefaultKubeFedConfig(modifiedSyncControllerMaxConcurrentReconcilesKFC)
128+
successCases["spec.syncController.maxConcurrentReconciles is preserved"] = KubeFedConfigComparison{syncControllerMaxConcurrentReconcilesKFC, modifiedSyncControllerMaxConcurrentReconcilesKFC}
129+
123130
adoptResourcesKFC := defaultKubeFedConfig()
124131
*adoptResourcesKFC.Spec.SyncController.AdoptResources = v1beta1.AdoptResourcesDisabled
125132
modifiedAdoptResourcesKFC := adoptResourcesKFC.DeepCopyObject().(*v1beta1.KubeFedConfig)
126133
SetDefaultKubeFedConfig(modifiedAdoptResourcesKFC)
127-
successCases["spec.leaderElect.adoptResources is preserved"] = KubeFedConfigComparison{adoptResourcesKFC, modifiedAdoptResourcesKFC}
134+
successCases["spec.syncController.adoptResources is preserved"] = KubeFedConfigComparison{adoptResourcesKFC, modifiedAdoptResourcesKFC}
135+
136+
// StatusController
137+
statusControllerMaxConcurrentReconcilesKFC := defaultKubeFedConfig()
138+
statusControllerMaxConcurrentReconciles := int64(DefaultStatusControllerMaxConcurrentReconciles + 3)
139+
statusControllerMaxConcurrentReconcilesKFC.Spec.StatusController.MaxConcurrentReconciles = &statusControllerMaxConcurrentReconciles
140+
modifiedStatusControllerMaxConcurrentReconcilesKFC := statusControllerMaxConcurrentReconcilesKFC.DeepCopyObject().(*v1beta1.KubeFedConfig)
141+
SetDefaultKubeFedConfig(modifiedStatusControllerMaxConcurrentReconcilesKFC)
142+
successCases["spec.statusController.maxConcurrentReconciles is preserved"] = KubeFedConfigComparison{statusControllerMaxConcurrentReconcilesKFC, modifiedStatusControllerMaxConcurrentReconcilesKFC}
128143

129144
for k, v := range successCases {
130145
if !reflect.DeepEqual(v.original, v.modified) {

pkg/apis/core/v1beta1/kubefedconfig_types.go

+13
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ type KubeFedConfigSpec struct {
3737
ClusterHealthCheck *ClusterHealthCheckConfig `json:"clusterHealthCheck,omitempty"`
3838
// +optional
3939
SyncController *SyncControllerConfig `json:"syncController,omitempty"`
40+
// +optional
41+
StatusController *StatusControllerConfig `json:"statusController,omitempty"`
4042
}
4143

4244
type DurationConfig struct {
@@ -105,6 +107,10 @@ type ClusterHealthCheckConfig struct {
105107
}
106108

107109
type SyncControllerConfig struct {
110+
// The maximum number of concurrent Reconciles of sync controller which can be run.
111+
// Defaults to 1.
112+
// +optional
113+
MaxConcurrentReconciles *int64 `json:"maxConcurrentReconciles,omitempty"`
108114
// Whether to adopt pre-existing resources in member clusters. Defaults to
109115
// "Enabled".
110116
// +optional
@@ -118,6 +124,13 @@ const (
118124
AdoptResourcesDisabled ResourceAdoption = "Disabled"
119125
)
120126

127+
type StatusControllerConfig struct {
128+
// The maximum number of concurrent Reconciles of status controller which can be run.
129+
// Defaults to 1.
130+
// +optional
131+
MaxConcurrentReconciles *int64 `json:"maxConcurrentReconciles,omitempty"`
132+
}
133+
121134
// +kubebuilder:object:root=true
122135
// +kubebuilder:resource:path=kubefedconfigs
123136

pkg/apis/core/v1beta1/validation/validation.go

+9
Original file line numberDiff line numberDiff line change
@@ -356,10 +356,19 @@ func ValidateKubeFedConfig(kubeFedConfig, oldKubeFedConfig *v1beta1.KubeFedConfi
356356
case sync.AdoptResources == nil:
357357
allErrs = append(allErrs, field.Required(adoptPath, ""))
358358
default:
359+
allErrs = append(allErrs, validateIntPtrGreaterThan0(syncPath.Child("maxConcurrentReconciles"), sync.MaxConcurrentReconciles)...)
359360
allErrs = append(allErrs, validateEnumStrings(adoptPath, string(*sync.AdoptResources),
360361
[]string{string(v1beta1.AdoptResourcesEnabled), string(v1beta1.AdoptResourcesDisabled)})...)
361362
}
362363

364+
statusController := spec.StatusController
365+
statusControllerPath := specPath.Child("statusController")
366+
if statusController == nil {
367+
allErrs = append(allErrs, field.Required(statusControllerPath, ""))
368+
} else {
369+
allErrs = append(allErrs, validateIntPtrGreaterThan0(statusControllerPath.Child("maxConcurrentReconciles"), statusController.MaxConcurrentReconciles)...)
370+
}
371+
363372
return allErrs
364373
}
365374

pkg/apis/core/v1beta1/validation/validation_test.go

+20
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,14 @@ func TestValidateKubeFedConfig(t *testing.T) {
844844
invalidSyncControllerNil.Spec.SyncController = nil
845845
errorCases["spec.syncController: Required value"] = invalidSyncControllerNil
846846

847+
invalidSyncControllerMaxConcurrentReconcilesNil := testcommon.ValidKubeFedConfig()
848+
invalidSyncControllerMaxConcurrentReconcilesNil.Spec.SyncController.MaxConcurrentReconciles = nil
849+
errorCases["spec.syncController.maxConcurrentReconciles: Required value"] = invalidSyncControllerMaxConcurrentReconcilesNil
850+
851+
invalidSyncControllerMaxConcurrentReconcilesGreaterThan0 := testcommon.ValidKubeFedConfig()
852+
invalidSyncControllerMaxConcurrentReconcilesGreaterThan0.Spec.SyncController.MaxConcurrentReconciles = zeroIntPtr
853+
errorCases["spec.syncController.maxConcurrentReconciles: Invalid value"] = invalidSyncControllerMaxConcurrentReconcilesGreaterThan0
854+
847855
invalidAdoptResourcesNil := testcommon.ValidKubeFedConfig()
848856
invalidAdoptResourcesNil.Spec.SyncController.AdoptResources = nil
849857
errorCases["spec.syncController.adoptResources: Required value"] = invalidAdoptResourcesNil
@@ -853,6 +861,18 @@ func TestValidateKubeFedConfig(t *testing.T) {
853861
invalidAdoptResources.Spec.SyncController.AdoptResources = &invalidAdoptResourcesValue
854862
errorCases["spec.syncController.adoptResources: Unsupported value"] = invalidAdoptResources
855863

864+
invalidStatusControllerNil := testcommon.ValidKubeFedConfig()
865+
invalidStatusControllerNil.Spec.StatusController = nil
866+
errorCases["spec.statusController: Required value"] = invalidStatusControllerNil
867+
868+
invalidStatusControllerMaxConcurrentReconcilesNil := testcommon.ValidKubeFedConfig()
869+
invalidStatusControllerMaxConcurrentReconcilesNil.Spec.StatusController.MaxConcurrentReconciles = nil
870+
errorCases["spec.statusController.maxConcurrentReconciles: Required value"] = invalidStatusControllerMaxConcurrentReconcilesNil
871+
872+
invalidStatusControllerMaxConcurrentReconcilesGreaterThan0 := testcommon.ValidKubeFedConfig()
873+
invalidStatusControllerMaxConcurrentReconcilesGreaterThan0.Spec.StatusController.MaxConcurrentReconciles = zeroIntPtr
874+
errorCases["spec.statusController.maxConcurrentReconciles: Invalid value"] = invalidStatusControllerMaxConcurrentReconcilesGreaterThan0
875+
856876
for k, v := range errorCases {
857877
errs := ValidateKubeFedConfig(v, testcommon.ValidKubeFedConfig())
858878
if len(errs) == 0 {

pkg/apis/core/v1beta1/zz_generated.deepcopy.go

+30
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/controller/federatedtypeconfig/controller.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func newController(config *util.ControllerConfig) (*Controller, error) {
9090
stopChannels: make(map[string]chan struct{}),
9191
}
9292

93-
c.worker = util.NewReconcileWorker("federatedtypeconfig", c.reconcile, util.WorkerTiming{})
93+
c.worker = util.NewReconcileWorker("federatedtypeconfig", c.reconcile, util.WorkerOptions{})
9494

9595
// Only watch the KubeFed namespace to ensure
9696
// restrictive authz can be applied to a namespaced

pkg/controller/schedulingmanager/controller.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func newSchedulingManager(config *util.ControllerConfig) (*SchedulingManager, er
9292
schedulers: util.NewSafeMap(),
9393
}
9494

95-
c.worker = util.NewReconcileWorker("schedulingmanager", c.reconcile, util.WorkerTiming{})
95+
c.worker = util.NewReconcileWorker("schedulingmanager", c.reconcile, util.WorkerOptions{})
9696

9797
var err error
9898
c.store, c.controller, err = util.NewGenericInformer(

pkg/controller/schedulingpreference/controller.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,10 @@ func newSchedulingPreferenceController(config *util.ControllerConfig, scheduling
105105
eventRecorder: recorder,
106106
}
107107

108-
s.worker = util.NewReconcileWorker(strings.ToLower(schedulingType.Kind), s.reconcile, util.WorkerTiming{
109-
ClusterSyncDelay: s.clusterAvailableDelay,
108+
s.worker = util.NewReconcileWorker(strings.ToLower(schedulingType.Kind), s.reconcile, util.WorkerOptions{
109+
WorkerTiming: util.WorkerTiming{
110+
ClusterSyncDelay: s.clusterAvailableDelay,
111+
},
110112
})
111113

112114
eventHandlers := schedulingtypes.SchedulerEventHandlers{

pkg/controller/status/controller.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,11 @@ func newKubeFedStatusController(controllerConfig *util.ControllerConfig, typeCon
123123
fedNamespace: controllerConfig.KubeFedNamespace,
124124
}
125125

126-
s.worker = util.NewReconcileWorker(strings.ToLower(statusAPIResource.Kind), s.reconcile, util.WorkerTiming{
127-
ClusterSyncDelay: s.clusterAvailableDelay,
126+
s.worker = util.NewReconcileWorker(strings.ToLower(statusAPIResource.Kind), s.reconcile, util.WorkerOptions{
127+
WorkerTiming: util.WorkerTiming{
128+
ClusterSyncDelay: s.clusterAvailableDelay,
129+
},
130+
MaxConcurrentReconciles: int(controllerConfig.MaxConcurrentStatusReconciles),
128131
})
129132

130133
// Build deliverer for triggering cluster reconciliations.

pkg/controller/sync/controller.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,11 @@ func newKubeFedSyncController(controllerConfig *util.ControllerConfig, typeConfi
132132
rawResourceStatusCollection: controllerConfig.RawResourceStatusCollection,
133133
}
134134

135-
s.worker = util.NewReconcileWorker(strings.ToLower(federatedTypeAPIResource.Kind), s.reconcile, util.WorkerTiming{
136-
ClusterSyncDelay: s.clusterAvailableDelay,
135+
s.worker = util.NewReconcileWorker(strings.ToLower(federatedTypeAPIResource.Kind), s.reconcile, util.WorkerOptions{
136+
WorkerTiming: util.WorkerTiming{
137+
ClusterSyncDelay: s.clusterAvailableDelay,
138+
},
139+
MaxConcurrentReconciles: int(controllerConfig.MaxConcurrentSyncReconciles),
137140
})
138141

139142
// Build deliverer for triggering cluster reconciliations.

pkg/controller/testdata/fixtures/crds.yaml

+13
Original file line numberDiff line numberDiff line change
@@ -774,12 +774,25 @@ spec:
774774
`Namespaced` or `Cluster`. `Namespaced` indicates that the KubeFed
775775
namespace will be the only target of the control plane.
776776
type: string
777+
statusController:
778+
properties:
779+
maxConcurrentReconciles:
780+
description: The maximum number of concurrent Reconciles of status
781+
controller which can be run. Defaults to 1.
782+
format: int64
783+
type: integer
784+
type: object
777785
syncController:
778786
properties:
779787
adoptResources:
780788
description: Whether to adopt pre-existing resources in member
781789
clusters. Defaults to "Enabled".
782790
type: string
791+
maxConcurrentReconciles:
792+
description: The maximum number of concurrent Reconciles of sync
793+
controller which can be run. Defaults to 1.
794+
format: int64
795+
type: integer
783796
type: object
784797
required:
785798
- scope

pkg/controller/util/controllerconfig.go

+8-6
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,14 @@ type ClusterHealthCheckConfig struct {
6868
// controllers.
6969
type ControllerConfig struct {
7070
KubeFedNamespaces
71-
KubeConfig *restclient.Config
72-
ClusterAvailableDelay time.Duration
73-
ClusterUnavailableDelay time.Duration
74-
MinimizeLatency bool
75-
SkipAdoptingResources bool
76-
RawResourceStatusCollection bool
71+
KubeConfig *restclient.Config
72+
ClusterAvailableDelay time.Duration
73+
ClusterUnavailableDelay time.Duration
74+
MinimizeLatency bool
75+
MaxConcurrentSyncReconciles int64
76+
MaxConcurrentStatusReconciles int64
77+
SkipAdoptingResources bool
78+
RawResourceStatusCollection bool
7779
}
7880

7981
func (c *ControllerConfig) LimitedScope() bool {

0 commit comments

Comments
 (0)