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

Cannot use Kubernetes labels in variable substitutions unless the labels are consistent across the set of monitored pods #4823

Open
cmacknz opened this issue May 28, 2024 · 2 comments
Labels
Team:Cloudnative-Monitoring Label for the Cloud Native Monitoring team Team:Elastic-Agent-Control-Plane Label for the Agent Control Plane team

Comments

@cmacknz
Copy link
Member

cmacknz commented May 28, 2024

If agent is monitoring a set of Kubernetes pods, then ${kubernetes.labels.*} variable substitutions cannot be used in the agent policy unless the complete set of labels used as variables exists together for at least one pod in the cluster. That is, you can only use a set of kubernetes.labels.* combinations that all exist together for at least one pod. Any other combinations will currently lead to the input being silently dropped from the configuration because of #2261.

This is limiting when the set of used Kubernetes labels is not actually consistent in a given cluster. A user would have to know to duplicate the inputs for each unique set of labels.

For example let's imagine a user wants to use labels in processor definitions and the labels kubernetes.labels.service, kubernetes.labels.app, and kubernetes.labels.k8s-app exist.

In this cluster, the labels kubernetes.labels.service and kubernetes.labels.app exist together for some pods so the following configuration works:

          - if:
              has_fields: ['kubernetes.labels.service']
            then:
              - add_fields:
                  target: service
                  fields:
                    type: name
                    name: "${kubernetes.labels.service}"
            else:
              - add_fields:
                  target: service
                  fields:
                    type: name
                    name: "${kubernetes.labels.app}"

The labels kubernetes.labels.app and kubernetes.labels.k8s-app are mutually exclusive of each other, so the following configuration causes the input to be silently dropped from the policy because of #2261. Fixing #2261 likely will lead to the input being in an error state, which is more obvious, but not easy to work with.

          - if:
              has_fields: ['kubernetes.labels.service']
            then:
              - add_fields:
                  target: service
                  fields:
                    type: name
                    name: "${kubernetes.labels.service}"
            else:
              - add_fields:
                  target: service
                  fields:
                    type: name
                    name: "${kubernetes.labels.k8s-app}"

We should come up with a better way to handle this situation than requiring the user to manually determine which combinations of labels exists together. The agent knows the full set of variables available for each pod, it can figure this out on behalf of the user.

A core problem is that in this example the agent does not look inside the input configurations, it can only add or remove inputs. It could not for example remove processor definitions that do not exist given this is a Beat input configuration.

A representative set of diagnostics is attached showing inputs being dropped from the policy in computed-config.yml along with the complete set of labels and pods available in variables.yml.

elastic-agent-diagnostics-2024-05-28T09-09-12Z-00.zip

@cmacknz cmacknz added Team:Elastic-Agent-Control-Plane Label for the Agent Control Plane team Team:Cloudnative-Monitoring Label for the Cloud Native Monitoring team labels May 28, 2024
@elasticmachine
Copy link
Contributor

Pinging @elastic/elastic-agent-control-plane (Team:Elastic-Agent-Control-Plane)

@blakerouse
Copy link
Contributor

blakerouse commented Jun 10, 2024

Variable substitution is done this way on purpose. This is easily solved by providing a fallback value.

${kubernetes.labels.k8s-app|''} see the addition of |'' as a way of providing a fallback value. When a fallback is not provided then it will be removed, but when a fallback is provided if the variable doesn't have a value it uses the fallback and doesn't remove the input.

https://www.elastic.co/guide/en/fleet/current/dynamic-input-configuration.html#_alternative_variables_and_constants

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Team:Cloudnative-Monitoring Label for the Cloud Native Monitoring team Team:Elastic-Agent-Control-Plane Label for the Agent Control Plane team
Projects
None yet
Development

No branches or pull requests

3 participants