Z.S.K.'s Records

Grafana学习(loki日志存在错误的label)

业务中使用的日志架构是基于Loki来搭建的,最近发现了一个很诡异的问题,有些log的label与label之间对应不上,经过一番尝试后虽然解决了问题,但不知道原由。

集群信息

软件 版本
Kubernetes stack v1.15.9
Loki v2.3.0
Promtail v2.3.0
Grafana V8.1.6

日志路径: log location –> promtail –> loki –> grafana

k8s日志结构

先简单了解下k8s集群的日志结构,这样以便引出发现的问题

在v1.14之前及之后会有所区别,表现如下:

  • before 1.14: /var/log/pods/<pod_uid>/<container_name>/<num>.log
  • 1.14 or later: /var/log/pods/<namespace>_<pod_name>_<pod_uid>/<container_name>/<num>.log

详细的解释参考这个PR

另外,<num>.log中的num代表pod重启的次数,参考这个[pull][https://github.com/kubernetes/kubernetes/pull/74441/files], 不过对于本文要解决的问题,num不重要.

问题现象

通过loki收集到的日志,通过grafana UI查询之后,出现如下问题:

从这个图可以看到, pod跟filename是对应不上的, 但从k8s日志结构来看, pod名跟filename中的部分是需要对应上的.

所以问题是: 从这个filename采集到的日志是属于这个pod的吗?

显然, log的label没有对应上最开始需要check一下是否是配置的问题,由于log的label的都是由promtail进行处理的,因此如果有问题,也只能是promtail配置文件的问题

Promtail配置

由于篇幅有限,这里只贴与pod相关的配置进行说明.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
scrape_configs:
# Pods with a label 'app'
- job_name: kubernetes-pods-app
pipeline_stages:
- docker: {}
kubernetes_sd_configs:
- role: pod
relabel_configs:
# 将pod中带有label为app的label重写为app
- action: replace
source_labels:
- __meta_kubernetes_pod_label_app
target_label: app
# 将app为空的值丢弃
- action: drop
regex: ''
source_labels:
- app
# 将pod中带有label为component的label重写为component
- action: replace
source_labels:
- __meta_kubernetes_pod_label_component
target_label: component
# prometheus中预定义的label
- action: replace
source_labels:
- __meta_kubernetes_pod_node_name
target_label: node_name
# prometheus中预定义的label
- action: replace
source_labels:
- __meta_kubernetes_namespace
target_label: namespace
# prometheus中预定义的label
- action: replace
source_labels:
- __meta_kubernetes_pod_name
target_label: pod
# prometheus中预定义的label
- action: replace
source_labels:
- __meta_kubernetes_pod_container_name
target_label: container
# 重点是以下部分
- action: replace
replacement: /var/log/pods/*$1/*.log
separator: /
source_labels:
- __meta_kubernetes_pod_uid
- __meta_kubernetes_pod_container_name
target_label: __path__

promtail的配置是使用了kubernetes的serviceDiscovery及prometheus的relabel机制, 这两部分不是本文的重点,感兴趣的可以参考官网说明,这里只说明两点:

  1. 以__开头的变量会在relabel后从label set中删除
  2. __path__ 是一个特殊标签,最终__path__会变成filename,参考loki File Target Discovery

由于是pod跟filename对应不上,那就只能是这两部分的relabel有问题,由于__meta_kubernetes_pod_container_name为prometheus中预定义的值,出错的可能不大,因此问题概率出在filename, 也就是配置中最下的部分

诈一看也没发现在任何问题,loki stack的helm charts也是这么使用的, 翻阅loki github issue也只发现一个相关问题, 但现象不太一样, 被merge 279 fix了,但是个人对这个issue 的close表示怀疑.

不过作者参照这个mege对应的配置也做过尝试,发现确实无法解决作者的问题.

经过作者的不斷调整promtail的配置,发现有一种情况居然给解决了

问题解决

1
2
3
4
5
6
7
8
- action: replace
replacement: /var/log/pods/$1/**/*.log
separator: _
source_labels:
- namespace
- pod
- __meta_kubernetes_pod_uid
target_label: __path__

由于promtail中使用的对文件的查询是基于一个开源库dobulestar

pod跟filename能正常work后, 作者还是没想明白为何这种配置是work的(作者认为【Promtail配置】中的配置也是没问题)

知其然不知其所以然,是真的很痛苦,作者写记录这篇软文也是想给可能有同样困惑的同学提供一种解决方法.

作者也在loki github中提了 issue,目前未有反馈,如果有知道原因的同学可以联系作者告知,万分感谢

参考文章:

转载请注明出处https://izsk.me

Z.S.K. wechat
Scan Me To Read on Phone
I know you won't do this,but what if you did?