-
Notifications
You must be signed in to change notification settings - Fork 176
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
Proposal: Support multiple custom/external metrics servers in the cluster #70
Comments
Hey @zroubalik, thank you for coming up with this proposal, I think this would be an amazing addition to this project. I would personally lean towards the CRD approach, as this would not require mutating existing adapters. Moreover, in the long run, this would allow more configuration possibilities than with grpc. If at some point, we need to select metrics from a specific producer, I think, it would be easier to do so with CRDs. Does your definition of a child component require an actual modification of existing adapters? To me, child components are the current adapters, and the aggregator is a whole new component dispatching API call to its children. Out of curiosity, with this approach, is your goal to have one component being both an aggregator and a child or have a standalone aggregator?
I think that it is worth adding a boilerplate to create metrics aggregators to this project as having multiple metric providers falls into the overall experience of custom metrics in Kubernetes. |
This proposal sounds good to me too! 🎉 cc'ing @serathius as I am curious about his thoughts too. Generally, from my side I'd love to see i.e. namespace based support for aggregated APIs in Kubernetes itself, which would solve that problem maybe in another way, but supporting it natively here definitely sounds also like a viable approach. |
@s-urbaniak great, I'll follow with some more details later. wrt the namespace based support in k8s itself, if I understand this correctly, this wouldn't help in this case if user would like to consume metrics from multiple providers from the same namespace, or am I wrong? |
@zroubalik correct and this is actually the edge case that I am actually worried about as there doesn't seem to be a clear boundary of responsibilities which provider is responsible for what namespace. |
We are in need of this exact use case. We need our subscribers to use a Stackdriver metric directly from GCP to scale off of. However, in the same namespace we have flask services that need to use the DD trace metrics to scale off request count. In the interim, we have our subscribers using the GCP metric from Datadog, but this adds an 8-10 minute delay in the external metrics server getting the metric to scale off (that is how much time it takes for DD to get metrics from GCP). Is it possible to get this on the roadmap? Is there any information that I can contribute to help architect how this would be solved? |
@mwerickso sorry for the delay. I am planning to start working on a POC, any help is definitely more than welcome. I will add some details later and will let you know then. |
This proposal is awesome. In Karpenter, we decided against the k8s metrics api due to this exact single-slot problem: https://github.com/awslabs/karpenter/blob/main/docs/DESIGN.md#prometheus-vs-kubernetes-metrics-api. I'm a little nervous about the idea of separating by namespace. Namespace is increasingly seen as a security boundary. Similarly, prometheus has moved towards multiple prometheuses deployed into different namespaces. By dividing metrics providers along namespaces, we lose the security properties of namespaces (i.e. metric RBAC) as well as enforce a cluster global semantic for that metrics provider. Instead, I was thinking about a model where a metrics provider could advertise the metrics paths it supports, and effectively have a universal metrics api router that detects these paths and routes to the right metrics provider. This could be modeled with CRDs, as you're suggesting. Strawman workflow:
|
Having ran into the same issue, I'm looking forward to this proposal gaining traction! 🙌 In the meantime, one way of getting around this issue is to reverse-proxy to several metrics provider; I've written a PoC/example at: https://github.com/Pluies/external-metrics-multiplexer |
Overall issue touches problem of extending kube aggregation to support multiple apiservers either by namespace or by other means. I think this should be first brought to apimachinery who has more broad view on extending K8s APIs. |
Based on @DirectXMan12 's comment 2 years ago I looked into what would be required to implement a service which discovers metrics from multiple metrics apiservers and then routes metric requests to the correct server. It would look something like what @ellistarn described. I've written a proposal on how this would work and implemented a prototype which discovers both custom and external metrics. The advantage of this solution is that it doesn't require any changes to Kubernetes APIs or existing custom metrics servers. Also there's no extra configuration for metrics. There's still the open question of how to deal with metrics which are provided by multiple metrics apiservers but this can be handled in the current design or in later iterations. Before I actually put more work into turning the prototype to something that's production ready I would appreciate any feedback particularly from |
Awesome, Thanks for doing this! I would be happy to help you with KEP process. |
@serathius The plan is to turn it into a KEP if |
@arjunrn definitely, this works for me 👍 |
@s-urbaniak @serathius Here's the KEP PR. Please let me know if there's anything I could add to explain things better. |
@arjunrn that's great, I wanted to implement this, but then I had to deal with something more urgent. Now I am back on the track. I am more than happy to help with the actual implementation/KEP or whathever stuff you need. |
Some additional input on this requirement. I found this issue because we are a DevOps team that supports several K8S clusters (specifically OpenShift) and we are transitioning from one metrics provider to another one over the next year. We ran into this problem of not being able to install our new provider's HPA adapter since the existing provider's one is already installed. How will we migrate HPA's smoothly without having both available concurrently? No idea at this point. I'm open to suggestions. A key feature requirement to consider when implementing this: |
Issues go stale after 90d of inactivity. If this issue is safe to close now please do so with Send feedback to sig-contributor-experience at kubernetes/community. |
/remove-lifecycle stale |
/lifecycle frozen |
I've been working on my own proof concept to test the idea. In case anyone is interested the project is available here: https://github.com/barkbay/metrics-router
There is still a lot to do though:
Feedbacks are welcome, especially if you have a real use case, I think it would help to improve the KEP. I'm also happy to help on any "official" implementation. |
There was multiple PoCs written overtime. but this issue hasn't moved much since the KEP was closed. As a path forward I would be happy to sponsor the metrics router to become one of SIG Instrumetation subprojects, but before that we would need to figure out what's the state of things:
The next things is that we would need enough people to volunteer to drive and maintain the project. At minimum, we would need 2 active maintainers, but the more people we can get, the more likely it is to be accepted as a subproject. @arjunrn @Pluies @barkbay since y'all worked on PoCs in the past, could you enlighten me about the state of things? Also, would any of you be interested in looking into that effort going forward? |
Hi @dgrisonnet ! Since the PoC above, I've set up Keda and never looked back. Granted, it's an external project and it would be nicer to use a pure "out-of-the-box" Kubernetes-native solution, but between supporting multiple scaling sources and scale-to-zero (which in upstream kube has been in alpha since forever), Keda has solved 100% of my autoscaling plumbing needs 🙏 |
That's great to hear! However, KEDA itself would also like to see this happen but we didn't have the engineering yet to contribute this. Scenarios are:
|
Makes sense @Pluies, thank you for the feedback! :) I totally agree that Keda is a good alternative in most cases considering the sheer amount of scalers that it supports. |
@dgrisonnet One issue with a router is that it needs to support all the different ways of authN - including X.509 which cannot be transparently passed through a layer 7 TLS proxy as @Pluies created. The approach there is to give the proxy it's own RBAC, but that's not a good solution for the general case I think (unless the proxy verifies inbound RBAC) This is a corner that I guess most cluster admins will only face a few times, but it's a really unpleasant corner to be in. I imagine it will get a bit more busy as 1.21 is EOL on EKS in February and https://github.com/amazon-archives/k8s-cloudwatch-adapter/ doesn't support rotating service account tokens AFAIK |
Be care @afirth because k8s-cloudwatch-adapter has been deprecated for 5 months, AWS recommends KEDA and the adapter is not longer maintained |
This may be a "dumb question", but I'll ask it anyway. Regarding the problem statement
I understand that this means you can't have multiple metrics servers simultaneously mapped to the path |
@zroubalik , @dgrisonnet , hoping you might have a moment to share the answer. Thanks :-) |
At the moment, we are running Is there any workaround for that? |
Sadly not, there is no easy migration process today because you can't have two different source of external metrics. The safest way today is to manually scale all the HPA targets to the max while doing the migration. |
@JohnRusk the HPA controller assumes the existence of resources coming from For example if you create an HPA with ExternalMetricSource set, the controller will try to get a MetricValue from the |
How hard would it be to modify |
Hi folks! We have a similar need to deploy more than one metrics server - actually. I’m extending that to allow an object to expose its own. What is the status of this / next steps? I’ve implemented operators and various Kubernetes abstractions before so I could definitely help. I also think it would hugely simplify things to just allow a different URL to expose a particular metric (last comment above) but curious about others’ thoughts. |
Currently, we have drafted a KEP: kubernetes/enhancements#4262 |
Beautiful, thank you! I will also follow. |
Thanks for working on this, side note I wrote an article on this issue. I really hope this gets improved upon, as it's been a long-standing UX issue that's been neglected for a long time. |
I see the kubernetes/enhancements#4262 is closed, does it mean the proposal is dropped or there is another kep to follow on this subject ? @JorTurFer |
Currently only one custom or external metrics server in the cluster is supported (because there can be only one
APIService
resouce specified), as already discussed in #3 in #68. This way users are not able use multiple projects that are consuming this framework, eg. KEDA, k8s-prometheus-adapter or Datadog etc.I was thinking about options how to solve this and I'd like to propose, that we will introduce
aggregator
andchild
components.aggregator
- that's basically the adapter that we have today (ie. it is responsible for communication with k8s api server,APIService
registration etc). + additional functionality: it registerschild
components as they are added in the cluster, transferring the requests for particular metrics to the child components and will maintain a cache of metrics that are provided by individualchilds
(which could always fall back to callingListMetrics()
on eachchild
).Could either use:
child
components and forward the REST callaggregator
&child
, this way thechild
components could register themselves in theaggregator
(by initializing the connection) and we won't need a controller and CRD for this partchild
- very lightweight component, that's transferring the metrics to theaggregator
, user will just have to implement the interfacesWith this approach, in the cluster there will be one
aggregator
component which will transfer requests to the individualchild
. Individual projects, that are consuming this framework, will have to just implement thechild
. If grpc is used, the whole communication could be pretty simple and we can even include this change into the existing codebase and allow some mixed scenario, whereaggregator
could provide some metrics as well, but I'd like to avoid this scenario.What do you think about this proposal? Do you think that this is something that could be acceptable by this project? I can elaborate more (and formalize the proposal), if I see an interest in this.
And yeah, I can contribute this 😄
The text was updated successfully, but these errors were encountered: