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

[receiver/prometheusoperator] Add base structure #6344

Conversation

secustor
Copy link
Member

@secustor secustor commented Nov 16, 2021

Description:

Adding structure for a new receiver based on the prometheus receiver.

Target is the support of a subset of PrometheusOperator CRDs as configuration option. This should give the user the option to gather metrics from targets defined by CRDs such as the ServiceMontitor or PodMonitor. These are provided mostly by applications themselves.
Link to tracking Issue: #6345

Testing: Only standard config parsing test ATM as this PR only contains the structure

Documentation: added README which describes the status and options of this receiver

@secustor secustor requested review from a team and mx-psi November 16, 2021 16:24
@Aneurysm9
Copy link
Member

I like the idea of being able to reuse the CRDs from the Prometheus operator, but I'd like to see some more detail about how this receiver would function and how it would integrate with the existing Prometheus receiver. Can you prepare a design document?

Copy link
Member

@mx-psi mx-psi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@open-telemetry/collector-contrib-approvers (or somebody else) Is someone with Prometheus knowledge able to review this?

receiver/prometheusoperatorreceiver/README.md Show resolved Hide resolved

import (
"go.opentelemetry.io/collector/config"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an unstable dependency; its structs should not be part of the public API of the receiver (otherwise we may not be able to use the latest k8s.io version)

@secustor
Copy link
Member Author

@Aneurysm9 Do you have example of such a document for OpenTelemetry or what is the preferred format for this?
I couldn't find any reference in the contributing guide or during a short google search.

@Aneurysm9
Copy link
Member

I don't think we need anything fancy. A design.md similar to what exists for the prometheus receiver would be good. I'm looking mostly for how this interacts with the existing receiver, pros/cons of having a separate receiver vs. trying to integrate the capability in the existing receiver, alternatives that could have been considered such as the receivercreator receiver, etc. I'd like to have some idea what the end state will look like and some confidence that it is the correct approach to solving the problem at hand before we start creating new components.

@jpkrohling
Copy link
Member

I'd like to have some idea what the end state will look like and some confidence that it is the correct approach to solving the problem at hand before we start creating new components.

Agree. We have multiple pieces of Prometheus support scattered around, including in the operator (like the target allocator feature, of which @Aneurysm9 is the maintainer). It would be great to regroup and define what the ideal solution would look like for different use cases and components.

cc @alolita, as you probably also have an interest in the target allocator (and around Prometheus in general).

@Aneurysm9
Copy link
Member

The target allocation capability in the operator is precisely why this piqued my interest. I had the configuration generation capability of the Prometheus operator exposed so that it could be incorporated there and I'd hope that the approach we take to include it directly in the collector can also be reused and integrated there.

@secustor
Copy link
Member Author

@Aneurysm9 I added a first synopsis, of what my initial thoughts have been.
It's by far not exhaustive and it does not contain any comparisons yet, but I think it is enough to get the general direction I have been investigating.

Should there be still interest, I can further develop the document.

@Aneurysm9 Aneurysm9 self-assigned this Nov 17, 2021
@punya
Copy link
Member

punya commented Nov 17, 2021

cc @dashpole

@alolita
Copy link
Member

alolita commented Nov 17, 2021

@jpkrohling thx! Taking a look at this proposal.

@secustor secustor force-pushed the add_prometheus_receiver_service_monitor branch from 0a01f95 to dbe658c Compare November 19, 2021 23:23
@jpkrohling
Copy link
Member

jpkrohling commented Nov 22, 2021

@secustor, could you add a "when to use what" section? For people getting started with OpenTelemetry, it might be confusing to understand all the available components (this, other Prometheus receivers, otel-operator, ...) and when to use them.

@secustor secustor force-pushed the add_prometheus_receiver_service_monitor branch from dbe658c to cd6f61c Compare November 22, 2021 16:48
@secustor
Copy link
Member Author

@jpkrohling I have added such a section to the README of prometheusoperatorreceiver, but I don't think it is a fitting place for such user guides. In my opinion a file in a docs folder will be easier to find for new users.

Copy link
Contributor

@dashpole dashpole left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only reviewed the design.

What is the plan for managing TLS certs? The prometheus operator adds these to prometheus as a volume, but we need a plan for managing these ourselves.

Instead of writing it onto a disk the configuration is unmarshalled using the Prometheus config loader,
which is already in use by the `prometheusreceiver` resulting in a full Prometheus config.

In case of an [Agent](#Collector vs Agent deployment) deployment, which is signaled with the `limit_to_node` option,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just allow specifying filters for PodMonitor/ServiceMonitor like you can do for prometheus? Seems like something we would want eventually, and would cover this case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had 3 limitation options in mind:

  • namespace(s) which are to be watched for monitor objects
  • a label selector to limit monitor objects in these namespaces( as it is setup in the Prometheus CRD of PrometheusOperator )
  • the node limiter option, which is used for an agent style deployment.

The first two are currently provided by PrometheusOperator ConfigGenerator package and the later one is implemented using the additional relabel configs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just suggesting that we re-use the underlying prometheus namespaces and selector structure. It allows specifying the role (podmonitor or servicemonitor in this case), a label selector, and a field selector. The field selector would allow limiting to podmonitors or servicemonitors on the same node, but is more general than your proposed node limiter option. Because of the "role" field, it would also allow supporting only podmonitors, or only servicemonitors, and allows different label or field selectors for each. Re-using the prometheus server's structure for this config would make it familiar to those already familiar with kubernetes_sd_configs.

which is already in use by the `prometheusreceiver` resulting in a full Prometheus config.

In case of an [Agent](#Collector vs Agent deployment) deployment, which is signaled with the `limit_to_node` option,
only local endpoints will be fetched, endpoints should be filtered so that only pods are scraped which are scheduled
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a note, it is not recommended to watch endpoints (or endpointslices) from each node. The apiserver has a watch index for pods by node name, meaning it is acceptable to watch pods assigned to each node from a daemonset, but does not have the same for endpoints.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, but I'm not sure how to solve this.
The only option other than introducing a new index in Kubernetes I see is the introduction of a shared cache. This could be maybe done as extension.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just noting it; I don't think it is easily solvable. I think we should not recommend using a daemonset with servicemonitors to users because of this.

### Collector
If running as collector the Prometheus config provided by PrometheusOperator can be reused without a change.
Should multiple instances with the same config run in the same cluster, they will act like a
high availability pair of Prometheus. Therefore, all targets will be scraped multiple times and telemetry
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HA is nice, but this means the collector can't shard work at all, and can't scale up replicas to reduce load. Did you consider supporting sharding with the hashmod action, like the prometheus operator does?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't been aware of this till now. This is definitely a useful addition when the receiver is setup as collector!
I will work this into the proposal

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other thing to consider is the OpenTelemetry Operator's prometheus target allocation capability. It is designed to allow running multiple collector instances and distributing targets across them. It will re-allocate targets if a collector instance is added or removed. I think adding the ability to utilize the pod and service monitors there should be considered as an alternative to building this into a receiver.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Aneurysm9 do you have a link to a design document for the target allocator? I couldn't find any in the OpentelemetryOperator repo or on opentelemetry.io.

If the community prefers to implement this first in the target allocator, I will work on that instead.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's the initial outline of the capability and here's the more detailed design doc for the target allocator service.

The target allocation server is set up to reload its server when the config file it uses changes. It should be feasible to add a watch for the Prometheus CRDs and use them to update the config, which will then cause the allocator to start using the generated SD configs.

In every other case other Prometheus receivers should be used.
Below you can find a short description of the available options.

### Prometheus scrape annotations
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you even need to use the receivercreator in this case. You can just use the __meta_kubernetes_pod_annotation_prometheus_io_scrape label to filter pods (use the equivalent for endpoints) directly in the prometheusreceiver.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should work as you describe it. I agree that the prometheusreceiver is in that case preferable.
I will adapt here the section too.

It provides a simplified interface around the `prometheusreceiver`. Use cases could be the federation of Prometheus
instances or scraping of targets outside dynamic setups.

### Prometheus service discovery and manual configuration
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just documenting some investigation i've done in the past: Why not just implement PodMonitor and ServiceMonitor using the prometheus service discovery? That would have the benefit of not needing to shutdown and restart the prometheus receiver when a PodMonitor or ServiceMonitor is modified.

Answer: The prometheus service discovery interface only supports adding new targets, but doesn't support manipulating metrics after they are scraped. So we wouldn't be able to support metricRelabelConfigs with that approach.

@mx-psi mx-psi removed the Stale label Dec 8, 2021
@github-actions
Copy link
Contributor

This PR was marked stale due to lack of activity. It will be closed in 7 days.

@github-actions github-actions bot added the Stale label Dec 16, 2021
@mx-psi mx-psi removed the Stale label Dec 16, 2021
@jpkrohling jpkrohling changed the title feat(receiver/prometheusOperator): add base structure [receiver/prometheusoperator] Add base structure Dec 16, 2021
@github-actions
Copy link
Contributor

This PR was marked stale due to lack of activity. It will be closed in 14 days.

@github-actions
Copy link
Contributor

This PR was marked stale due to lack of activity. It will be closed in 14 days.

@github-actions github-actions bot added the Stale label Jan 27, 2022
@mx-psi mx-psi removed the Stale label Jan 27, 2022
@github-actions
Copy link
Contributor

This PR was marked stale due to lack of activity. It will be closed in 14 days.

@github-actions github-actions bot added the Stale label Feb 11, 2022
@mx-psi
Copy link
Member

mx-psi commented Feb 11, 2022

Is this something that will be worked on in the future? Or should I stop removing the Stale tag?

@secustor
Copy link
Member Author

I think this is still proposal is still valid.

The current focus is to implement the support for this, as described in this comment, in the TargetAllocator.

Is there a way to remove this PR from the lifecycle?

@mx-psi
Copy link
Member

mx-psi commented Feb 11, 2022

Is there a way to remove this PR from the lifecycle?

Not that I know of, other than closing it and re-opening when it can be worked on again

@mx-psi mx-psi removed the Stale label Feb 11, 2022
@github-actions
Copy link
Contributor

This PR was marked stale due to lack of activity. It will be closed in 14 days.

@github-actions github-actions bot added the Stale label Feb 26, 2022
@mx-psi mx-psi removed the Stale label Feb 28, 2022
@github-actions
Copy link
Contributor

This PR was marked stale due to lack of activity. It will be closed in 14 days.

@github-actions
Copy link
Contributor

github-actions bot commented Apr 4, 2022

This PR was marked stale due to lack of activity. It will be closed in 14 days.

@github-actions github-actions bot added the Stale label Apr 4, 2022
@github-actions
Copy link
Contributor

Closed as inactive. Feel free to reopen if this PR is still being worked on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants