馃毄 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:
-
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
-
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
-
Creating unnecessary fields is a potential waste of resources and can slow down ingestion
-
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
-
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
}
}
}
- 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.
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:
kubernetes.pod.name: it has always been a keyword. However, if the data is rerouted to another integration it will result in the creation ofkubernetes.pod.name.textfield because of the dynamic template ruleecs_path_match_keyword_and_match_only_textThe
kubernetes.container_logsintegration containskubernetes.node.labels,kubernetes.node.annotations,kubernetes.namespace_labels,kubernetes.labels,kubernetes.namespace_annotationsandkubernetes.selectorsdynamic template rules that match every type and map them as keyword (note that nested fields likekuberntes.labels.test.fooare not accepted. The fields are dedoted by Beats https://www.elastic.co/guide/en/fleet/current/kubernetes-provider.html).Potential Impact
Creating unnecessary fields is a potential waste of resources and can slow down ingestion
If users starts accidentally use the field
kubernetes.pod.name.textto define their alerts or to query data they may unwillingly filter out the kubernetes.container_logsIf 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.
Example:
How similar fields are treated elsewhere
If we take the example of
containerandcloudmetadata, 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.namespacein the template of each and every integration likecontainerandcloudmetadataRely 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
infracomponent template containing all infrastructure fields and their dynamic template rules counterparts (e.g.,host,cloud,kubernetes)Somehow reuse/nest the
logs-kubernetes.container_logsinto another component templateCurrent Workaround
The current workaround would be to define in each and every integration
@customtemplate the fields. The workaround is viable if the amount of integration is small. Ideally, having aglobal@custom, (and especially)logs@custom,logs-dataset@customcomponent 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.