4

我正在尝试将日志从 Kubernetes 集群写入 Elasticsearch 索引。Fluent-bit 用于读取标准输出,并使用包括 pod 标签在内的元数据丰富日志。一个简化的示例日志对象是

{
  "log": "This is a log message.",
  "kubernetes": {
    "labels": {
      "app": "application-1"
    }
  }
}

问题是部署到集群的其他一些应用程序具有以下格式的标签:

{
  "log": "This is another log message.",
  "kubernetes": {
    "labels": {
      "app.kubernetes.io/name": "application-2"
    }
  }
}

这些应用程序通过 Helm 图表安装,较新的应用程序遵循此处列出的标签和选择器约定。标签和选择器的命名约定已于 2018 年 12 月更新,见此处,并非所有图表都已更新以反映这一点。

这样做的最终结果是,取决于哪种类型的标签格式首先将其放入弹性索引,尝试发送另一种类型将引发映射异常。如果我创建一个新的空索引并首先发送命名空间标签,则尝试记录简单app标签将引发此异常:

object mapping for [kubernetes.labels.app] tried to parse field [kubernetes.labels.app] as object, but found a concrete value

相反的情况,第二个发布命名空​​间标签,会导致这个异常:

Could not dynamically add mapping for field [kubernetes.labels.app.kubernetes.io/name]. Existing mapping for [kubernetes.labels.app] must be of type object but found [text].

我怀疑正在发生的事情是,Elasticsearch 将字段名称中的句点视为 JSON 点符号,并试图将其充实为一个对象。我能够从 2015 年找到这个 PR,它明确不允许字段名称中出现句点,但它似乎在 2016 年被这个 PR颠倒了。还有一个 2015-2017 年的多年线程讨论这个问题,但我找不到任何涉及最新版本的最新内容。

我目前关于前进的想法是标准化我们使用的 Helm 图表,以使所有标签都使用相同的约定。这似乎是潜在问题的创可贴,尽管我觉得我在 Elasticsearch 和动态字段映射的配置中遗漏了一些明显的东西。

这里的任何帮助将不胜感激。

4

2 回答 2

2

我选择使用带有rename此处描述的选项的 Logstash mutate 过滤器:

https://www.elastic.co/guide/en/logstash/current/plugins-filters-mutate.html#plugins-filters-mutate-rename

最终结果看起来像这样:

filter {
  mutate {
    '[kubernetes][labels][app]'   => '[kubernetes][labels][app.kubernetes.io/name]'
    '[kubernetes][labels][chart]' => '[kubernetes][labels][helm.sh/chart]'
  }
}
于 2020-01-03T23:58:59.717 回答
0

虽然我个人从未遇到过完全相同的问题,但当我为一些测试数据编制索引并随后更改了应该编制索引的文档的结构时(尤其是在“展开”数据结构时),我遇到了类似的问题。

您对错误消息的解释是正确的。当您第一次索引文档时

{
  "log": "This is another log message.",
  "kubernetes": {
    "labels": {
      "app.kubernetes.io/name": "application-2"
    }
  }
}

由于动态映射,Elasticsearch 会将应用程序识别为对象/结构。

当您尝试索引文档时

{
  "log": "This is a log message.",
  "kubernetes": {
    "labels": {
      "app": "application-1"
    }
  }
}

之前动态创建的映射将字段app定义为具有子字段的对象,但 elasticsearch 遇到一个具体值,即“application-1”。

我建议您设置一个索引模板来定义正确的映射。对于“过时”的日志记录版本,我建议通过 elasticsearch 摄取管道或使用例如 Logstash 对特定文档进行预处理,以获取正确格式的文档。

希望有帮助。

于 2019-12-24T20:37:26.570 回答