共计 4678 个字符,预计需要花费 12 分钟才能阅读完成。
作者:大飞哥,视源电子运维工程师,KubeSphere 用户委员会广州站站长
采集落盘日志
日志采集,通常应用 EFK 架构,即 ElasticSearch
,Filebeat
,Kibana
,这是在主机日志采集上十分成熟的计划,但在容器日志采集方面,整体计划就会简单很多。咱们当初面临的需要,就是要采集容器中的落盘日志。
容器日志分为规范输入日志和落盘日志两种。利用将日志打印在容器规范输入 STDOUT
中,由容器运行时 (Docker 或 Containerd) 把规范输入日志写入容器日志文件中,最终由采集器导出。这种日志打印采集是业界举荐计划。但对于不打印规范输入而间接将日志落盘的状况,业界最罕用见的计划是,应用 Sidecar
采集落盘日志,把落盘日志打印到容器规范输入中,再利用规范输入日志的采集形式输入。
对于 KubeSphere 用户,只须要两步即可:第一在我的项目中开启 收集卷上日志
,第二在工作负载中配置落盘文件门路。具体操作见下图所示。
上述两个步骤,会主动在容器中注入 Filebeat Sidecar
作为 logging-agent,将落盘日志打印输出在容器规范输入中。Filebeat 配置可通过 ConfigMap 批改。
$ kubectl get cm -n kubesphere-logging-system logsidecar-injector-configmap -o yaml
## Filebeat 配置
filebeat.inputs:
- type: log
enabled: true
paths:
{{range .Paths}}
- {{.}}
{{end}}
output.console:
codec.format:
string: '%{[log.file.path]} %{[message]}'
logging.level: warning
接入第三方日志服务
默认 KubeSphere 将日志采集到集群内置 Elasticsearch 中,数据保留周期为 7 天,这对于生产服务动辄 180 天的日志存储需要,显然无奈满足。企业运维团队都会建设集中化的日志服务,将集群内日志接入到第三方日志服务中,已是必然选择。咱们来看如何操作。
上文说到,容器运行时会将规范输入日志,落盘写入到集群节点的日志文件中,Linux 零碎默认在 /var/log/containers/*.log
。KubeSphere 应用 FluentBit
以 DemonSet
模式在各集群节点上采集日志,由 FluentBit 输入给 ElasticSearch 服务。具体配置可参考如下两个配置:
$ kubectl get Input -n kubesphere-logging-system tail -o yaml
$ kubectl get Output -n kubesphere-logging-system es -o yaml
咱们把日志导出到第三方日志服务,那就须要定制 FluentBit 输入输出。应用 tail
插件采集 /var/log/containers/flux-wms-*.log
文件中的日志,输入到 Kafka
中。可参考如下配置:
---
apiVersion: logging.kubesphere.io/v1alpha2
kind: Input
metadata:
labels:
logging.kubesphere.io/component: logging
logging.kubesphere.io/enabled: "true"
name: kafka-flux-wms
namespace: kubesphere-logging-system
spec:
tail:
db: /fluent-bit/tail/pos.db
dbSync: Normal
memBufLimit: 5MB
path: /var/log/containers/flux-wms-*.log
refreshIntervalSeconds: 10
tag: fluxwms.*
---
apiVersion: logging.kubesphere.io/v1alpha2
kind: Output
metadata:
annotations:
kubesphere.io/creator: admin
labels:
logging.kubesphere.io/component: logging
logging.kubesphere.io/enabled: "true"
name: kafka-flux-wms
namespace: kubesphere-logging-system
spec:
kafka:
brokers: xxx.xxx.xxx.xxx:9092
topics: my-topic
match: fluxwms.*
值得注意的是,目前 FluentBit 不反对 Kafka 认证。
多行日志的难堪
本来认为至此就可高枕无忧,没想到生产 kafka 日志时忽然看到,某些日志被拆得七零八碎,不忍入目。为了反对多行日志,直观的想法,就是一一组件往前排查。
后方有坑,请小心浏览。
配置 FluentBit 反对多行日志
FluentBit 对多行日志的反对,须要配置 Parser,并通过 parserFirstline
指定日志 Parser,用以解析出多行日志块的第一行。官网参考文档,Parser 正则表达式,依据 Filebeat 日志输入格局而定,可参考上文或间接看这段:string: '%{[log.file.path]} %{[message]}'
。
---
apiVersion: logging.kubesphere.io/v1alpha2
kind: Input
metadata:
labels:
logging.kubesphere.io/component: logging
logging.kubesphere.io/enabled: "true"
name: kafka-flux-wms
namespace: kubesphere-logging-system
spec:
tail:
db: /fluent-bit/tail/pos.db
dbSync: Normal
memBufLimit: 5MB
path: /var/log/containers/flux-wms-*.log
multiline: true
parserFirstline: kafka-flux-wms
refreshIntervalSeconds: 10
tag: fluxwms.*
---
apiVersion: logging.kubesphere.io/v1alpha2
kind: Parser
metadata:
labels:
logging.kubesphere.io/component: logging
logging.kubesphere.io/enabled: "true"
name: kafka-flux-wms
namespace: kubesphere-logging-system
spec:
regex:
regex: '^\/data\/business-logs\/[^\s]*'
配置 Filebeat 反对多行日志
查看 kakfka 音讯,多行日志依然被拆分。难道 Filebeat 没有反对多行日志吗?整个落盘日志采集链条中,只有有一个环节不反对多行日志,就会导致后果不迭预期。查看我的项目原始日志文件,发现多行日志以工夫格局结尾,于是 Filebeat 减少如下配置:
filebeat.inputs:
- type: log
enabled: true
paths:
{{range .Paths}}
- {{.}}
{{end}}
multiline.pattern: '^[0-9]{4}-[0-9]{2}-[0-9]{2}'
multiline.negate: true
multiline.match: after
multiline.max_lines: 100
multiline.timeout: 10s
output.console:
codec.format:
string: '%{[log.file.path]} %{[message]}'
logging.level: warning
进入 Sidecar 容器,应用如下命令测试 Filebeat 输入,确认正确宰割多行日志。
$ filebeat -c /etc/logsidecar/filebeat.yaml
不可漠视的容器运行时
按理说,FluentBit 和 Filebeat 都反对了多行日志,kafka 应该能够正确输入多行日志,但后果令人悲观。必定还有哪个环节被脱漏了,在登录集群节点主机查看容器规范输入日志时,这个被忽视的点被发现啦!
## 此处间接查看你的我的项目容器
$ tail -f /var/log/containers/*.log
你会发现,日志都是 JSON
格局,并且日志是逐行输入的,也就是说,没有反对多行日志块。本地 kubernetes 集群应用 Docker 作为容器运行时,来查看它的配置:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
},
"max-concurrent-downloads": 10,
"max-concurrent-uploads": 10,
"bip": "192.168.100.1/24",
"storage-driver": "overlay2",
"storage-opts": ["overlay2.override_kernel_check=true"]
}
log-driver
配置为json-file
, 这也是官网默认配置,可参考官网阐明,除 json 格局外,还反对如下格局:
- local
- gelf
- syslog
- fluentd
- loki
显然其余格局也并不现实,而且对于生产环境,切换容器运行时日志格局,影响还是蛮大的。摸索至此,这条路子难度偏大危险过高,临时先搁置,待到身心惬意时接着玩。
去掉中间商,中转 kafka
既然下面的路子走不通,那就换个思路。Filebeat 也是 logging-agent,是反对输入日志到 Kafka 的,为何不省去中间环节,直奔主题呢?
$ kubectl edit cm -n kubesphere-logging-system logsidecar-injector-configmap
filebeat.inputs:
- type: log
enabled: true
paths:
{{range .Paths}}
- {{.}}
{{end}}
multiline.pattern: '^[0-9]{4}-[0-9]{2}-[0-9]{2}'
multiline.negate: true
multiline.match: after
multiline.max_lines: 100
multiline.timeout: 10s
output.kafka:
enabled: true
hosts:
- XXX.XXX.XXX.XXX:9092
topic: sycx-cmes-app
## output.console:
## codec.format:
## string: '%{[log.file.path]} %{[message]}'
logging.level: warning
当看到 Kafka 消费者输入完满多行日志块时,脑后传来多巴胺的快感!再看一眼架构图,咱们来做总结!
总结
最后我去 KubeSphere 社区论坛搜寻日志采集相干帖子时,有敌人说无奈实现。看到他的回复,心底一阵失望。现在看来,某种角度上说,他的答复没错,他只是说那条路走不通,但他没说那条路能走通。
本文由博客一文多发平台 OpenWrite 公布!