kubernetes日志采集与解析

来源:互联网 发布:Python Max iteritem 编辑:程序博客网 时间:2024/06/06 21:44

需求:当我们创建deployment后,我们希望能够收集到这些deployment每个pod的终端日志,并且能够通过deployment的名字以及pod的名字进行过滤

日志方案

filebeat -> kafka -> logstash -> elasticsearch

Filebeat采集

容器中输出到终端(stdout)的日志,都会以*-json.log的命名方式保存在/var/lib/docker/containers/目录下,而且会在/var/log/containers/目录下生成这些日志文件的软链接。所以,我们可以直接在/var/log/containers/目录下采集容器的终端日志。
由于/var/log/containers/目录下除了deployment的pod的日志文件外,还会有其他容器的日志,而我们只需要采集deployment的日志。在/var/log/containers/目录下,deployment的pod的日志文件命名规则为(一个pod只有一个主容器和一个pause容器)

[podName]_[namespace]_[deploymentName]-[containerId].log # 通过deployment生成的pod内的主容器[podName]_[namespace]_POD-[containerId].log # 通过deployment生成的pod内的pause容器

deployment的podName的命名规则为

[deploymentName]-[xxxx]-[yyyy]

所以,deployment的pod的日志文件的命名规则又可以扩展为

[deploymentName]-[xxxx]-[yyyy]_[namespace]_[deploymentName]-[containerId].log [deploymentName]-[xxxx]-[yyyy]_[namespace]_POD-[containerId].log

其中deploymentNamenamespace只能由小写、数字、中划线组成,xxxxyyyycontainerId只能由小写和数字组成。于是,我们采集的匹配规则可以设置为

/var/log/containers/*-*-*_*_*.log

至于为什么匹配规则定义的这么严格,主要是防止采集了不是deployment的pod的日志文件,从而导致logstash在从文件名解析相应字段时报错或者搜索时检索到了不应该检索到的日志。
比如,我们的pod还有可能是由daemonSet生成的,daemonSet的pod的日志文件的格式为

[daemonSetName]-[xxxx]_[namespace]_[daemonSetName]-[containerId].log # 通过daemonSet生成的pod内的主容器[daemonSetName]-[xxxx]_[namespace]_POD-[containerId].log # 通过daemonSet生成的pod内的pause容器

daemonSetName可以由小写、数字、中划线组成。如果我们把匹配规则设置为(1),那么第一个*号代表的daemonSetName不一定有两个中划线,从而解析出错

/var/log/containers/*_*_*.log    # (1)

Logstash解析

Filebeat采集后,我们需要从/var/log/containers/*-*-*_*_*.log这个字符串中解析出deploymentNamepodName两个字段。根据前面的命名规则,先根据斜杠/把字符串拆分成一个数组filepath;取数组最后一个元素,也就是文件名,再根据下划线_进行拆分成一个另一个数组filename;数组filename的第一个元素就为podName,根据中划线-把podName拆分成一个数组,去掉数据后面两个元素,把前面的元素再用中划线-拼接起来便是deploymentName