⚡️: 日志采集器Logstash其功能虽然强大,但是它依赖java、在数据量大的时候,Logstash进程会消耗过多的系统资源,这将严重影响业务系统的性能,而filebeat就是一个完美的替代者,它基于Go语言没有任何依赖,配置文件简单,格式明了,
简介
用于转发和集中日志数据的轻量级托运器。filebeat比logstash更加轻量级,所以占用系统资源极少,非常适合安装在生产机器上。这就是推荐使用filebeat,也是 ELK Stack 在 Agent 的第一选择。
采集流程:
- container log --> Kafka topic
镜像构建
官方拉取的镜像,时区是 UTC ,我们想要获取到 CST 时间,并使用 filebeat
用户访问,就需要我们自己重新打镜像,下面是所用的Dockerfile
FROM elastic/filebeat:8.5.1
MAINTAINER ycloud
USER root
RUN apt-get update && apt-get install -y tzdata && rm -rf /var/lib/apt/lists/*
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
USER filebeat
Helm部署
- helm repo add elastic https://helm.elastic.co
- helm install filebeat elastic/filebeat
部署十分简单,但是我们可能需要调整Helm chart配置,所以建议把包拉取到本地调整之后再进行部署,下面是详细流程
[root@ycloud ~]# helm repo add elastic https://helm.elastic.co
"elastic" already exists with the same configuration, skipping
[root@ycloud ~]# helm pull elastic/filebeat
[root@ycloud ~]# tar -zxvf filebeat-8.5.1.tgz
filebeat/Chart.yaml
filebeat/values.yaml
filebeat/templates/NOTES.txt
filebeat/templates/_helpers.tpl
filebeat/templates/clusterrole.yaml
filebeat/templates/clusterrolebinding.yaml
filebeat/templates/configmap.yaml
filebeat/templates/daemonset.yaml
filebeat/templates/deployment.yaml
filebeat/templates/role.yaml
filebeat/templates/rolebinding.yaml
...
[root@ycloud ~]# cd filebeat/ ; ls
Chart.yaml examples Makefile README.md templates values.yaml
配置调整
删除赘余部分
我们刚刚拉取了官方的Chart包,中间默认是指定input到Elastic,所以我们需要调整下Deployment模板
[root@ycloud filebeat]# vim templates/daemonset.yaml
...
{{- if .Values.extraEnvs | default .Values.daemonset.extraEnvs }}
{{ toYaml ( .Values.extraEnvs | default .Values.daemonset.extraEnvs ) | indent 8 }}
{{- end }}
...
...
{{- range .Values.secretMounts | default .Values.daemonset.secretMounts }}
- name: {{ .name }}
mountPath: {{ .path }}
{{- if .subPath }}
subPath: {{ .subPath }}
{{- end }}
{{- end }}
...
...
{{- range .Values.secretMounts | default .Values.daemonset.secretMounts }}
- name: {{ .name }}
secret:
secretName: {{ .secretName }}
{{- end }}
...
⚡️:这里的secrets
是挂的elastic的用户名密码,因为我这边是把数据先推到 kafka
而不是 es中,所以这个secrets 部分可以去掉。大家可以根据自己的情况调节。
更新Values
image 部分改为我们自己新build的镜像名称及tag
其余没什么太大改动的,剩下就是filebeat的配置文件,根据自己的情况进行配置,下面是我的一个配置情况
[root@ycloud filebeat]# vim values.yaml
...
filebeat.inputs:
- type: container
paths:
- /var/log/containers/*gstrain*.log
scan_frequency: 1s
processors:
- add_kubernetes_metadata:
in_cluster: true
namespace: "gstrain"
matchers:
- logs_path:
logs_path: "/var/log/containers"
identifier: "container.id"
enrichers:
- deployment
- drop_fields:
fields:
- "/^kubernetes\\.labels\\..*/"
- "/^kubernetes\\.namespace_labels\\..*/"
- "/^kubernetes\\.node\\..*/"
- "/^(agent\\.name|agent\\.id|agent\\.type)$/"
- drop_event:
when:
or:
- equals:
kubernetes.container.name: "istio-proxy"
- equals:
kubernetes.container.name: "istio-init"
logging.level: debug
output.kafka:
hosts: ["10.189.6.130:9092","10.189.6.131:9092","10.189.6.132:9092"]
topic: "gstrainpod-devel"
partition.round_robin:
reachable_only: true
required_acks: 1
compression: gzip
max_message_bytes: 1000000
...
filebeat.inputs
参数指定要监视的输入类型。在这个配置中,Filebeat监视Docker容器日志,并根据给定的路径来查找所有符合条件(包含“gstrain”字符串的)的容器日志文件。scan_frequency
参数设置Filebeat扫描容器日志文件的频率。processors
参数指定应该对事件进行的任何预处理步骤。在这个配置中,有几个处理器被定义,包括添加Kubernetes元数据,删除某些字段和事件过滤器等。add_kubernetes_metadata
处理器通过查询Kubernetes API来添加Kubernetes标签和注释等元数据信息,使得在后续处理流程中可以更好地对日志进行分类和分析。drop_fields
处理器通过正则表达式删除日志事件中不需要的字段,比如Kubernetes相关的字段。drop_event
处理器可以丢弃事件,例如当事件来自特定容器时,此处当事件来源于Istio Sidecar容器(istio-proxy和istio-init)时将其丢弃。logging.level
参数设置Filebeat的日志级别,这里设置为debug。output.kafka
参数定义要将收集的日志数据发送到Kafka的设置。在这个配置中,输出Kafka的地址以及要使用的主题名称等信息都被指定。还可以看到诸如轮询分区、压缩等其他设置。
挂载文件
❌: 这里有一点需要注意,这也是我疑惑的地方,filebeat采集日志,但是配置中的paths路径确实容器内部的路径,也可能中间哪些步骤没有了解清楚,我暂时是将宿主机目录挂载到Pod中,暂时解决这个问题
。
⭕️: 还有一个地方需要注意,了解的朋友可能知道 /var/log/containers 其实是个软连接,如果我们调整了容器日志的存储路径,也记得要把更改的路径挂上去,不然查询不到实际日志。
下面给出挂载案例,以Docker为 Runtime为例,并且日志路径为 /data/docker/
[root@ycloud filebeat]# vim template/DaemonSet.yaml
...
volumeMounts:
- mountPath: /usr/share/filebeat/filebeat.yml
name: filebeat-config
readOnly: true
subPath: filebeat.yml
- mountPath: /var/log/
name: log
readOnly: true
- mountPath: /data/docker/containers
name: dockerlog
readOnly: true
...
...
volumes:
- configMap:
defaultMode: 384
name: filebeat-filebeat-deployment-config
name: filebeat-config
- hostPath:
path: /var/log/
type: ''
name: log
- hostPath:
path: /data/docker/containers
type: ''
name: dockerlog
...
主流程
✌️: 我们filebaet采集Pod日志就可以正常运行了,不过我们前面也说了,我这边根据业务实际情况,将日志采集到Kafka 队列中去,通过现有日志系统中的Logstash将日志转发到 ES 中去。
下面就十分简易了,就直接贴个配置好了
input {
kafka {
id => "pod_k2e_id"
bootstrap_servers => "192.168.100.10:9092,192.168.100.20:9092,192.168.100.30:9092"
topics => "pod"
auto_offset_reset => "earliest"
group_id => "group_pod"
consumer_threads => 90
codec => json { charset => "UTF-8" }
}
}
filter {
json {
source => "message"
}
mutate {
remove_field => ["tags","host","^host.*"]
}
ruby {
code => "event.set('index_day', event.get('@timestamp').time.localtime.strftime('%Y.%m.%d'))"
}
mutate {
convert => {
"index_day" => "string"
}
}
}
output {
if ( [kubernetes][deployment][name] == "ycloud") {
elasticsearch {
id => "es_pod_id"
hosts => ["http://192.168.100.10:9200","http://192.168.100.20:9200","http://192.168.100.30:9200"]
index => "ycloud_crawl-%{index_day}"
user => "elastic"
password => "xxxxxxxxxx"
codec => json { charset => "UTF-8" }
}
}else {
elasticsearch {
id => "es_pod2_id"
hosts => ["http://192.168.100.10:9200","http://192.168.100.20:9200","http://192.168.100.30:9200"]
index => "ycloud_pod-%{index_day}"
user => "elastic"
password => "xxxxxxxxxx"
codec => json { charset => "UTF-8" }
}
}
}
结果
这里我们就可以成功采集到我们想要的日志了,不需要的字段也跟使用过滤器来delete掉。