diff --git a/CHANGELOG.md b/CHANGELOG.md index 57da828a3d..3769b745b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -219,6 +219,10 @@ Adding a new version? You'll need three changes: those names will be propagated to one or many instances of aforementioned tag. [#6759](https://github.com/Kong/kubernetes-ingress-controller/pull/6759) [#6780](https://github.com/Kong/kubernetes-ingress-controller/pull/6780) +- Added the flag `--secret-label-selector` to set the label selector for `Secrets` to ingest. + By setting this flag, the secrets that are ingested will be limited to those having this label set to "true". + This can reduce the memory usage in scenarios with a large number of giant secrets. + [#6795](https://github.com/Kong/kubernetes-ingress-controller/pull/6795) ## [3.3.1] diff --git a/docs/cli-arguments.md b/docs/cli-arguments.md index 1139c84465..e7a36b4113 100644 --- a/docs/cli-arguments.md +++ b/docs/cli-arguments.md @@ -92,6 +92,7 @@ | `--publish-service-udp` | `namespaced-name` | Service fronting UDP routing resources in "namespace/name" format. The controller will update UDP route status information with this Service's endpoints. If omitted, the same Service will be used for both TCP and UDP routes. | | | `--publish-status-address` | `strings` | Addresses in comma-separated format (or specify this flag multiple times), for use in lieu of "publish-service" when that Service lacks useful address information (for example, in bare-metal environments). | `[]` | | `--publish-status-address-udp` | `strings` | Addresses in comma-separated format (or specify this flag multiple times), for use in lieu of "publish-service-udp" when that Service lacks useful address information (for example, in bare-metal environments). | `[]` | +| `--secret-label-selector` | `string` | Limits the secrets ingested to those having this label set to "true". If not specified, all secrets are ingested. | | | `--skip-ca-certificates` | `bool` | Disable syncing CA certificate syncing (for use with multi-workspace environments). | `false` | | `--sync-period` | `duration` | Determine the minimum frequency at which watched resources are reconciled. Set to 0 to use default from controller-runtime. | `10h0m0s` | | `--term-delay` | `duration` | The time delay to sleep before SIGTERM or SIGINT will shut down the ingress controller. | `0s` | diff --git a/internal/controllers/configuration/secret_controller.go b/internal/controllers/configuration/secret_controller.go index 628625e0ef..3f57a09c99 100644 --- a/internal/controllers/configuration/secret_controller.go +++ b/internal/controllers/configuration/secret_controller.go @@ -2,18 +2,19 @@ package configuration import ( "context" + "fmt" "time" "github.com/go-logr/logr" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/event" - "sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/predicate" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -41,6 +42,7 @@ type CoreV1SecretReconciler struct { CacheSyncTimeout time.Duration ReferenceIndexers ctrlref.CacheIndexers + LabelSelector string } var _ controllers.Reconciler = &CoreV1SecretReconciler{} @@ -51,6 +53,22 @@ func (r *CoreV1SecretReconciler) SetupWithManager(mgr ctrl.Manager) error { // we should always try to delete secrets in caches when they are deleted in cluster. predicateFuncs.DeleteFunc = func(_ event.DeleteEvent) bool { return true } + var ( + labelPredicate predicate.Predicate + labelSelector metav1.LabelSelector + err error + ) + if r.LabelSelector != "" { + labelSelector = metav1.LabelSelector{ + MatchLabels: map[string]string{r.LabelSelector: "true"}, + } + } + + labelPredicate, err = predicate.LabelSelectorPredicate(labelSelector) + if err != nil { + return fmt.Errorf("failed to create secret label selector predicate: %w", err) + } + return ctrl.NewControllerManagedBy(mgr). Named("CoreV1Secret"). WithOptions(controller.Options{ @@ -59,9 +77,12 @@ func (r *CoreV1SecretReconciler) SetupWithManager(mgr ctrl.Manager) error { }, CacheSyncTimeout: r.CacheSyncTimeout, }). - Watches(&corev1.Secret{}, - &handler.EnqueueRequestForObject{}, - builder.WithPredicates(predicateFuncs), + For(&corev1.Secret{}, + builder.WithPredicates( + predicate.And( + predicateFuncs, + labelPredicate, + )), ). Complete(r) } diff --git a/internal/manager/config.go b/internal/manager/config.go index 55fe045dc3..0ef7556346 100644 --- a/internal/manager/config.go +++ b/internal/manager/config.go @@ -131,9 +131,12 @@ type Config struct { GatewayAPIReferenceGrantController bool GatewayAPIGRPCRouteController bool - // KIC can only reconciling the specified Gateway. + // GatewayToReconcile specifies the Gateway to be reconciled. GatewayToReconcile OptionalNamespacedName + // SecretLabelSelector specifies the label which will be used to limit the ingestion of secrets. Only those that have this label set to "true" will be ingested. + SecretLabelSelector string + // Admission Webhook server config AdmissionServer admission.ServerConfig @@ -280,6 +283,8 @@ func (c *Config) FlagSet() *pflag.FlagSet { flagSet.BoolVar(&c.GatewayAPIGRPCRouteController, "enable-controller-gwapi-grpcroute", true, "Enable the Gateway API GRPCRoute controller.") flagSet.Var(flags.NewValidatedValue(&c.GatewayToReconcile, namespacedNameFromFlagValue, nnTypeNameOverride), "gateway-to-reconcile", `Gateway namespaced name in "namespace/name" format. Makes KIC reconcile only the specified Gateway.`) + flagSet.StringVar(&c.SecretLabelSelector, "secret-label-selector", "", + `Limits the secrets ingested to those having this label set to "true". If not specified, all secrets are ingested.`) flagSet.BoolVar(&c.KongServiceFacadeEnabled, "enable-controller-kong-service-facade", true, "Enable the KongServiceFacade controller.") flagSet.BoolVar(&c.KongVaultEnabled, "enable-controller-kong-vault", true, "Enable the KongVault controller.") flagSet.BoolVar(&c.KongLicenseEnabled, "enable-controller-kong-license", true, "Enable the KongLicense controller.") diff --git a/internal/manager/config_validation_test.go b/internal/manager/config_validation_test.go index 8a851ce2b3..0040db481a 100644 --- a/internal/manager/config_validation_test.go +++ b/internal/manager/config_validation_test.go @@ -114,6 +114,15 @@ func TestConfigValidatedVars(t *testing.T) { ExpectedErrorContains: "namespace cannot be empty", }, }, + "--secret-label-selector": { + { + Input: "konghq.com/label-for-caching", + ExtractValueFn: func(c manager.Config) any { + return c.SecretLabelSelector + }, + ExpectedValue: "konghq.com/label-for-caching", + }, + }, } for flag, flagTestCases := range testCasesGroupedByFlag { diff --git a/internal/manager/controllerdef.go b/internal/manager/controllerdef.go index 5d0e236869..7fc23d80c7 100644 --- a/internal/manager/controllerdef.go +++ b/internal/manager/controllerdef.go @@ -142,6 +142,7 @@ func setupControllers( DataplaneClient: dataplaneClient, CacheSyncTimeout: c.CacheSyncTimeout, ReferenceIndexers: referenceIndexers, + LabelSelector: c.SecretLabelSelector, }, }, // ---------------------------------------------------------------------------