-
Notifications
You must be signed in to change notification settings - Fork 589
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Limit ingested Secrets to those actually used #2868
Comments
Tentatively sticking this in 2.7: this is large enough that it may slip, but as a known performance limitation and general annoyance (we don't want to scan and generate logs for a bunch of irrelevant Secrets) I'd like to try and get it fixed sooner if possible. |
Do we allow referencing a secret that does not exist when we create the referencing object(ingress/kongplugin/...)? I think we should allow it. |
I think it has to be determined on a per-reference basis. There are some cases where you can potentially create partial configuration and some where you cannot. In the proposed solution, for example, the reconciler for an Ingress is now responsible for adding both the Ingress and Secret to the store. If it processes an Ingress successfully, it won't process it again until the Ingress is modified. If the Secret isn't available at the time that it processes that reconcile event, it will not add the Secret to the store. You need to requeue the reconcile in order to eventually add the Secret if it becomes available. While we do need to requeue the reconcile events if we can't fetch a referent, nothing stops us from adding the referrer to the store if some referent is unavailable. This may or may not be desirable or consistent with current behavior. Following the examples below, maintaining status quo would mean that Ingresses with missing cert Secrets are added to the store and do result in routes, whereas plugins with Secret configuration are not. At present: kinda? It depends on where you're looking and the specific reference. Following are some examples for the two main areas that handle this. Some checks in the admission webhook require referenced Secrets:
This is a general problem with cross-resource validation, and doesn't play nice with eventual consistency. However, absent a feedback mechanism by which we can indicate these resources are invalid after admission (the issues linked to FTI-4350), we can reasonably consider the consequences of allowing these through (no updates at all until they're fixed) worse than the annoyance of needing to create the Secrets first. Elsewhere, in the parser, we may allow these or not depending on the specifics:
The simplest way to implement this is to allow upserts without valid references in the modified controllers. AFAIK, none of the current controllers perform these checks because we've historically placed this responsibility primarily in the parser and have not had the controllers handle any checks outside their main resource (with the exception of some IngressClass-related checks). So long as you do requeue to ensure those resources do end up in the store, you can ignore broken references. This will preserve the status quo: the existing parser-level checks will continue functioning, and they are generally written with the expectation that references won't always work. Whether this responsibility should live in the parser or whether we should allow partial configuration is something of an open question. My overall impression of controller-runtime is that it does expect you to place more validation in the controllers than we currently do, but that's subjective. Discussions with the Gateway API working group have generally leaned against allowing partial/best effort configuration and toward instead invalidating the top-level resource altogether until issues are fixed. The latter approach is usually less complicated to implement and avoids inferring a potentially incorrect interpretation of user intent, but is risky insofar as it can make typos catastrophic. |
I may not be able to fully comment on this issue but one note I'd like to make is that
I'd say having an outright failure and returning a meaningful error to the user makes sense to me. It's better to have a consistent, expected failed state rather than a quasi-OK state where some settings/objects are applied and some are not. Having said that, ingesting the referrer (e.g. Ingress) without having the Secret ready in the store sounds OK to me as long as we do not apply whatever the Ingress and its config entail (a route? only?) until the secret that's necessary to fulfil the "Ingress contract" (of applying a working route) is ingested by the store as well. I imaging that whatever is handling the secret (in secrets controller?) would be able to figure out somehow that there is an Ingress (in that particular scenario) waiting for it so the its config can be applied. |
https://danielmangum.com/posts/controller-runtime-client-go-rate-limiting/ covers the "are requeues a problem if they never encounter an acceptable resource?" question quite extensively. controller-runtime does throttle requeues using exponential backoff. We can even tune the throttling behavior if that's not working well. If we're in the expected race condition, where someone creates an Ingress and Secret in short succession, and the first reconcile runs before the Secret is visible, controller-runtime will requeue quickly and eventually successfully process the resource. If someone instead forgets to create the referent Secret entirely, the requeues will never succeed and never end, but will eventually become very infrequent. |
Is there an existing issue for this?
Problem Statement
Currently, KIC ingests all Secrets, places them in the store, and filters which make it into Kong configuration in the parser based on the presence of a
konghq.com/ca-cert: true
label or references from Ingresses, Gateways, KongConsumers, or Kong(Cluster)Plugins. Because Secrets are a generic resource, many Secrets in a cluster are not relevant to KIC (e.g. we do not need to ingest service account tokens, they will never be used in Kong configuration)Although these Secrets are unused, we still ingest them, they consume (potentially a sizeable amount of) memory. Users cannot reduce the amount of memory used by any means other than simply using fewer Secrets, which isn't a viable option if you're actually using them.
Aside from CA certificate Secrets, we cannot determine if a Secret will be needed later based on the Secret alone. We need to know if there is a reference to the Secret from some other object, our standard generated controller cannot find those references.
Proposed Solution
controller-runtime provides a standard example pattern for tracking resources referenced by another. My initial read is that this should let us avoid reading Secrets we will not need.
(*whateverReconciler) findObjectForSecret()
map function handlers and the resource version changed predicate.findObjectForSecret()
handler lists and queues requests for any resource handled by that reconciler that includes a reference to that Secret. FWIW It doesn't look like this uses the new index directly; I'm guessing controller-runtime uses it as an under the hood optimization.Additional information
Acceptance Criteria
The text was updated successfully, but these errors were encountered: