我试图从Kubernetes集群中将日志写入Elasticsearch索引。Fluent位被用来读取stdout,它用元数据(包括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年起就找到了这个公关,它明确禁止字段名中的句号,但在2016年这个公关中似乎出现了相反的情况。还有一个从2015-2017年开始的多年期线程在讨论这个问题,但我找不到最新版本的最新版本。
我目前对前进的想法是标准化的赫尔姆图表,我们正在使用的所有标签使用相同的约定。这似乎是基本问题上的一个创可贴,但我觉得在Elasticsearch和动态字段映射的配置中,我遗漏了一些明显的东西。
这里的任何帮助都将不胜感激。
发布于 2020-01-03 23:58:59
我选择使用带有rename选项的Logstash过滤器,如下所述:
最终结果如下所示:
filter {
mutate {
'[kubernetes][labels][app]' => '[kubernetes][labels][app.kubernetes.io/name]'
'[kubernetes][labels][chart]' => '[kubernetes][labels][helm.sh/chart]'
}
}发布于 2019-12-24 20:37:26
虽然我个人从未遇到过完全相同的问题,但当我索引一些测试数据时,以及后来更改了应该被索引的文档的结构时(特别是当“非扁平”数据结构时),我遇到了类似的问题。
您对错误信息的解释是正确的。当您第一次索引文档时
{
"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"
}
}
}以前,动态创建的映射将字段应用程序定义为一个具有子字段的对象,但是elasticsearch遇到了一个具体的值,即"application-1“。
我建议您设置一个索引模板来定义正确的映射。对于“过时的”日志版本,我建议通过elasticsearch管道或使用Logstash等方法对特定文档进行预处理,以获得正确的格式。
希望这能有所帮助。
https://stackoverflow.com/questions/59472323
复制相似问题