-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Support APIReader/NoCache option for ControllerUtil.CreateOr(Update|Patch) functions to avoid OOM errors #1222
Comments
Would it make sense to have an option for the client to ignore cached reads? |
I'm surprised by how the default |
Hi @dsbrng25b ,
I thought the same as well, but then I realized that it doesn't make much sense to have any objects cached for which there aren't informers. Otherwise you may be getting stale data. And if you cache upon a get call, wouldn't a subsequent get just cache it again? Anyway, I get (pun intended) why they added implicit watches, but at the same time, I also agree this type of behavior shouldn't be a side-effect, and even possibly opt-in. |
The behavior of the cache is indeed a debatable thing (in both directions). So far, no one bothered to start that discussion 🙃 As for the problem at hand, I don't think its possible to change any about this is You might be able to solve your problem by overriding the Another approach I've used in the past is to just build a client out of the |
At minimum @alvaroaleman, I think we should do a better job of highlighting this behavior in documentation. It was completely unexpected, and while I understand the reasons, we should make sure others are aware of the design and how to mitigate/work-around concerns/situations similar to what I've outlined in this issue. |
We hit the same issue in our clusters as well.
To eliminate unnecessary network traffic and decrease the memory footprint of our controllers in the short-term, we basically implemented exactly what @alvaroaleman suggested (see gardener/gardener#2940). The usage basically looks something like this: mgr, err := manager.New(restConfig, manager.Options{
NewClient: utils.NewClientFuncWithDisabledCacheFor(
&corev1.Secret{},
&corev1.ConfigMap{},
),
}) (e.g. ref gardener/gardener-extension-networking-calico#55) The client implementation can either only cache objects of the specified GKs or disable the cache for the specified GKs. The naming might be horrible, but I'm definitely open to contribute this back to c-r, if there is interest in it :) |
A proposed solution that uses the delegating client and offers a builder is in #1249, feel free to leave feedback and comments. |
Issues go stale after 90d of inactivity. If this issue is safe to close now please do so with Send feedback to sig-testing, kubernetes/test-infra and/or fejta. |
Fixed in #1249 /close |
@vincepri: Closing this issue. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
Use Case(s)
As a Developer,
I would like to use
controllerutil.CreateOrUpdate
and/orcontrollerutil.CreateOrPatch
without theGet
calls in both functions resulting in the creation of an informer/watch for the specified object,Because the implicit watch behavior creates scaling issues and OOM errors on pods that may not ever explicitly watch a
ConfigMap
, but do create one, on a cluster with thousands ofConfigMap
resources.Details
By default, upon creation, the controller-runtime Manager initializes a
DelegatingClient
, which reads from an internal cache and writes directly to the API server. This client uses a backing cache implementation that automatically sets up informers (aka watches) on resource types duringGet
andList
calls.This is by design, and is normally fine, but contributes to issues at scale. Imagine a controller that creates
ConfigMap
resources, but never explicitly watches them. That controller may be running in a pod with a 30MiB memory limit. The pod will be terminated with an out-of-memory (OOM) error on a cluster with 100-120ConfigMap
resources at ~50 KiB each -- resources that have nothing at all to do with this controller.The
Manager
interface does support aGetAPIReader() client.Reader
function that returns a client that will bypass the informer cache. The problem becomes the functionscontrollerutil.CreateOrUpdate
and/orcontrollerutil.CreateOrPatch
. These functions both share similar signatures and logic:Both functions must first
Get
the object before attempting aCreate
orUpdate
/Patch
call. This means that currently these functions cannot take only anAPIReader
. The argument given to theclient.Client
parameter must be a client that can both read and write.The bottom line is the use of the helper functions that are prevalent throughout much our code, and no doubt many others', contribute to scaling problems because of the by-design side-effect of an implicit watch on objects via
Get
calls.The text was updated successfully, but these errors were encountered: