Skip to content
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 controller-runtime integration for pprof #16594

Open
JorTurFer opened this issue Dec 12, 2023 · 10 comments · May be fixed by #17068
Open

Support controller-runtime integration for pprof #16594

JorTurFer opened this issue Dec 12, 2023 · 10 comments · May be fixed by #17068

Comments

@JorTurFer
Copy link
Contributor

JorTurFer commented Dec 12, 2023

Summary

We are facing with some performance issues that we want to troubleshoot. For going deeper, we want to profile the app for detecting the bottlenecks, but I've noticed that controller-runtime built-in integration isn't configured.

Controller-runtime can enable (or not) the profiling just configuring the address (or not). This is really easy to integrate/configure and allows profiling ArgoCD components just changing a value on cm and restarting a pod, which is so much better than adding the profiling code in the old (and hard) way.

Motivation

I have to profile applicationset-controller and it requires changes in code for enabling the profiler. It also means that I have to checkout the exact version I've deployed to base my changes on it, which is more effort. Integrating this built-in feature I'd not need to change a line of code and I can profile the components easily when I need it

Proposal

I'd just configure PprofBindAddress on controllers. IDK if reading the value from cm or maybe from args

@JorTurFer JorTurFer added the enhancement New feature or request label Dec 12, 2023
@JorTurFer
Copy link
Contributor Author

Tomorrow I'll try to draft a PR with this feature, you can assign the issue to me if you want :)

@JorTurFer
Copy link
Contributor Author

This will be more complicated than I expected:
image

The built-in feature was added in [email protected] but there are too much replaces to k8s 0.26 and there are several incompatibilities.

Apart from that, only applicationset-controller uses controller-runtime to generate the managers, other components use listers/informers generated using raw kube-client (for instance):

config, err := clientConfig.ClientConfig()
....

kubeClient := kubernetes.NewForConfigOrDie(config)
appClient := appclientset.NewForConfigOrDie(config)

I need to think about how to solve it in a single way for all the
components. Maybe writing a helper like controller-runtime does but not directly using it... 🤔
WDYT @blakepettersson @crenshaw-dev ?

@blakepettersson
Copy link
Member

@JorTurFer I think those replaces are caused by having k8s.io/kubernetes as a dependency and ideally would be solved with argoproj/gitops-engine#535, or with someone else continuing the work on that.

@JorTurFer
Copy link
Contributor Author

The problem is that the replaces aren't the only problem I faced with. As only the applicationset-controller is directly build on top of controller-runtime, only it can enable this feature. Other components use kubernetes client, but don't looks as built on top of controller-runtime because they don't have any point where that dep is used.

Based on that, my proposal is to create a helper shared for all ArgoCD components that starts up a server with the same endpoints as controller-runtime's server, adding the same features. Basically my idea is to port that feature from controller-runtime to ArgoCD instead of integrate it (due to the replaces and also the controller-runtime usage stuff)

WDYT?

@blakepettersson
Copy link
Member

@JorTurFer it makes sense to me, especially given that something like this would be useful for argocd-server and the repo server. Perhaps if for now this feature is limited to the applicationset-controller (since that's where your original pain point was) and we thereafter can port this to the other Argo components? WDYT @crenshaw-dev?

@JorTurFer
Copy link
Contributor Author

I think that we can include something like controller-runtime did: https://github.com/kubernetes-sigs/controller-runtime/pull/1943/files

Basically with a few lines we could create an optional server that we enable based on a given config. I think that it's something easy and "clean"

@blakepettersson
Copy link
Member

@JorTurFer makes sense to me 👍

@JorTurFer
Copy link
Contributor Author

nice! I'll draft a PR when I have some time :)

@JorTurFer
Copy link
Contributor Author

JorTurFer commented Feb 1, 2024

Late is always better than never, so I've just drafted the PR: #17068 🤣

Let's move the discussion there :)

@agilgur5
Copy link
Member

agilgur5 commented Feb 9, 2024

Noting here that per #17068 (comment), pprof was already supported after #7533, but it was running unconditionally (which is a security and perf issue) as well as always on the metrics port.

EDIT: well, it was only enabled for the Application Controller and the Server (not all the current components may have existed at the time, the Repo Server may have been the only one missing then).
#17068 adds pprof support for the rest of the current components as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment