Skip to content

[Discussion] Every (log?) integration should deal with Kubernetes fields like the Kubernetes integration (or vice-versa)#9808

Description

@herrBez

馃毄 In the following only the logs use-case have been considered. It is not excluded we may have similar issues with metrics.

Problem Statement

It is not uncommon to read logs from Kubernetes and send them into different integrations (e.g., if I am reading the data from an Nginx Pod I want to use the NGINX integration etc.). To accomplish this goal we have at least two alternatives:

Autodiscoery works perfectly fine for Filebeat, where all kubernetes metadata fields are specified in the template, in the integration case it can lead to unwanted consequences, i.e., creation of unexpected fields and potentially mapping differences between (kubernetes.container_logs and other integration datasets).

Indeed, since the kubernetes dynamic template rules and static fields are not defined, we may end up in having different mappings in different datastreams. A couple of examples:

  1. kubernetes.pod.name: it has always been a keyword. However, if the data is rerouted to another integration it will result in the creation of kubernetes.pod.name.text field because of the dynamic template rule ecs_path_match_keyword_and_match_only_text

  2. The kubernetes.container_logs integration contains kubernetes.node.labels, kubernetes.node.annotations, kubernetes.namespace_labels, kubernetes.labels, kubernetes.namespace_annotations and kubernetes.selectors dynamic template rules that match every type and map them as keyword (note that nested fields like kuberntes.labels.test.foo are not accepted. The fields are dedoted by Beats https://www.elastic.co/guide/en/fleet/current/kubernetes-provider.html).

Potential Impact

  1. Creating unnecessary fields is a potential waste of resources and can slow down ingestion

  2. If users starts accidentally use the field kubernetes.pod.name.text to define their alerts or to query data they may unwillingly filter out the kubernetes.container_logs

  3. If for some reasons we have a label of type integer (not sure it can actually happen) we may have different mappings between NGINX and Kubernetes integration. Labels are used as identifier for Kubernetes and can be used to group together all logs for a given application. Having different mappings can make a field not usable in Kibana or not viable for certain types of queries.

# This will be mapped as long
POST logs-nginx.access-testissue/_doc?op_type=create
{
  "@timestamp": "2024-01-01",
  "kubernetes": {
    "annotations": {
      "foo": 34
    }
  }
}

# This will be mapped as keyword
POST logs-kubernetes.container_logs-testissue/_doc?op_type=create
{
  "@timestamp": "2024-01-01",
  "kubernetes": {
    "annotations": {
      "foo": 34
    }
  }
}
  1. If for some reasons (it should not happen if using beats) one of the labels contain a subfield it may lead to the fact that the nginx integration will accept the field, while the kubernetes integration not.
    Example:
# kubernetes.annotations.foo will be indexed as an integer
POST logs-nginx.access-testissue/_doc?op_type=create
{
  "@timestamp": "2024-01-01",
  "kubernetes": {
    "annotations": {
      "foo": {
        "bar": 34
      }
    }
  }
}

# kubernetes.annotations.foo will not be indexed (the document will be rejected in 8.13.3)
POST logs-kubernetes.container_logs-testissue/_doc?op_type=create
{
  "@timestamp": "2024-01-01",
  "kubernetes": {
    "annotations": {
      "foo": {
        "bar": 34
      }
    }
  }
}

How similar fields are treated elsewhere

If we take the example of container and cloud metadata, these are defined in every single integration. Because in the end these are metadata to identify the source object sending data.

Potential Solutions Identified so far

  • Add the kubernetes dynamic template rules and core kubernetes fields like kubernetes.pod.name, kubernetes.namespace in the template of each and every integration like container and cloud metadata

  • Rely everywhere on the ecs@mapping component template to avoid mismatches between kubernetes and the other datasets (and hopefully find a way to map the kubernetes.pod.name and similar fields to keyword). As of now the ecs@mapping component template would map also host.name as text and keyword.

  • Add an infra component template containing all infrastructure fields and their dynamic template rules counterparts (e.g., host, cloud, kubernetes)

  • Somehow reuse/nest the logs-kubernetes.container_logs into another component template

Current Workaround

The current workaround would be to define in each and every integration @custom template the fields. The workaround is viable if the amount of integration is small. Ideally, having a global@custom, (and especially) logs@custom, logs-dataset@custom component templates as described elastic/kibana#149484 , would make the workaround viable even when using many integrations.

CC @ruflin, @philippkahr, @flash1293 . Please chime-in if I forgot something.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Integration:AllApplies to all integrations [Integration not found in source]Stalleddiscuss

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions