一、前言

Filebeat是一个非常轻量级的日志收集工具,可以将其和应用程序部署至一个Pod中,通过Volume进行日志文件的共享,之后Filebeat即可采集里面的数据,并推送至日志平台。

下面环境基于EFK环境进行的,EFK环境搭建请参考EFK技术栈收集k8s日志

本文主要以下几方面介绍Filebeat如何采集容器内部自定义文件日志:

  • 创建 Kafka 和 Logstash
  • 注入 Filebeat Sidecar
  • Kibana查看日志
  • 清理环境

二、创建Kafka和Logstash

部署 Kafka 和 Logstash 至 Kubernetes 集群,将Filebeat 的输出指向外部 Kafka 集群

1.下载需要的部署文件

$ git clone https://gitee.com/jeckjohn/k8s.git
$ cd k8s/efk-7.10.2/

2.部署zookeeper

[root@k8s-master01 ~]# cd /root/k8s/efk-7.10.2/filebeat/zookeeper
[root@k8s-master01 zookeeper]#  helm install zookeeper zookeeper/ -n logging
[root@k8s-master01 filebeat]# kubectl get po -n logging -l app.kubernetes.io/name=zookeeper
NAME          READY   STATUS    RESTARTS   AGE
zookeeper-0   1/1     Running   0          2m38s

3.部署kafka

[root@k8s-master01 ~]# cd /root/k8s/efk-7.10.2/filebeat/kafka
[root@k8s-master01 kafka]# helm install kafka kafka/ -n logging
[root@k8s-master01 kafka]#  kubectl get po -n logging -l app.kubernetes.io/component=kafka
NAME      READY   STATUS    RESTARTS   AGE
kafka-0   1/1     Running   0          58s

4.待 Pod 都正常后,创建 Logstash 服务

[root@k8s-master01 ~]# cd /root/k8s/efk-7.10.2/filebeat
[root@k8s-master01 filebeat]# kubectl create -f logstash-service.yaml -f logstash-cm.yaml -f logstash.yaml -n logging

其中关于logstash-cm.yaml文件配置说明:

  • input:数据来源,这里配置的是Kakfa
  • input.kafka.bootstrap_servers:Kafka地址,由于是安装在集群内部的,可以直接使用Kafka集群的Service接口,如果是外部地址,按需配置即可。
  • input.kafka.topics:Kafka的topic,需要和Filebeat输出的topic一致
  • input.kafka.type:定义一个type,可以用于Logstash输出至不同的Elasticsearch集群
  • output:数据输出至哪里,本示例输出至Elasticsearch集群,在里面配置了一个判断语句,当type为filebeat-sidecar时,将会输出至Elasticsearch集群,并且index为filebeat-%{+YYYY.MM.dd}

三、注入Filebeat Sidecar

1.创建一个模拟程序,该程序会一直在/opt/date.log 文件输出当前日期

[root@k8s-master01 ~]# cd /root/k8s/efk-7.10.2/filebeat
[root@k8s-master01 filebeat]# kubectl create -f app.yaml -n logging

2.给k8s-node02节点打上标签fluentd="true"

[root@k8s-master01 filebeat]# kubectl label node k8s-node02 fluentd="true"

3.成功启动后,可以查看该文件的内容

[root@k8s-master01 efk-7.10.2]# kubectl get po -n logging
NAME                                   READY   STATUS              RESTARTS       AGE
app-ddf4b6db9-28q5t                    1/1     Running             0              5h22m
elasticsearch-logging-0                1/1     Running             0              8m10s
fluentd-es-v3.1.1-xm9tl                1/1     Running             0              6m41s
kafka-0                                1/1     Running             0              14h
kibana-logging-7bf48fb7b4-bzdzt        1/1     Running             0              3h4m
logstash-deployment-6485f5d5b5-8f2n4   1/1     Running             0              5h23m
zookeeper-0                            1/1     Running             0              14h

4.观察app程序正在输出日期信息

[root@k8s-master01 filebeat]#  kubectl exec app-ddf4b6db9-28q5t -n logging -- tail -f /opt/date.log
Tue Jul 18 01:07:28 UTC 2023
Tue Jul 18 01:07:30 UTC 2023
Tue Jul 18 01:07:32 UTC 2023
...
...

5.查看Kibana 服务暴露端口30533,并在浏览器上输入节点IP+port登录检索该日志,发现是无法查到该日志的,这是因为 Fluentd 无法采集内部的日志文件,至于怎么出现下面的界面,请参考EFK技术栈收集k8s日志

[root@k8s-master01 loki-stack]# kubectl get svc -n logging
NAME                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE
elasticsearch-logging   ClusterIP   None           <none>        9200/TCP,9300/TCP            6h59m
kafka                   ClusterIP   10.0.213.116   <none>        9092/TCP                     21h
kafka-headless          ClusterIP   None           <none>        9092/TCP,9093/TCP            21h
kibana-logging          NodePort    10.0.155.36    <none>        5601:30533/TCP               9h
logstash-service        ClusterIP   10.0.86.168    <none>        5044/TCP                     12h
zookeeper               ClusterIP   10.0.215.45    <none>        2181/TCP,2888/TCP,3888/TCP   21h
zookeeper-headless      ClusterIP   None           <none>        2181/TCP,2888/TCP,3888/TCP   21h

注入 Filebeat Sidecar-1

6.创建一个app-filebeat.yaml 文件,添加 Filebeat 至该部署文件。可以看到在 Deployment 部署文件中,添加了 Volumes 配置,并配置了一个名为 logpath 的 volume,将其挂载到了应用容器的/opt/目录和 Filebeat 的/data/log/app/目录,这样同一个 Pod 内的两个容器就实现了目录的共享

[root@k8s-master01 ~]# cd /root/k8s/efk-7.10.2/filebeat
[root@k8s-master01 filebeat]# vim app-filebeat.yaml

应用配置文件

[root@k8s-master01 filebeat]# kubectl apply -f app-filebeat.yaml -n logging

注入 Filebeat Sidecar-2

7.创建一个 Filebeat 的配置文件,采集该目录下的日志即可。需要注意 paths 是配置的共享目录,output.kafka 需要和 logstash 的 kafka 为同一个集群, 并且 topic 和 logstash 消费的 topic 为同一个。

[root@k8s-master01 ~]# cd /root/k8s/efk-7.10.2/filebeat
[root@k8s-master01 filebeat]# vim filebeat-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: filebeatconf
data:
  filebeat.yml: |-
    filebeat.inputs:
    - input_type: log
      paths:
        - /data/log/*/*.log
      tail_files: true
      fields:
        pod_name: '${podName}'
        pod_ip: '${podIp}'
        pod_deploy_name: '${podDeployName}'
        pod_namespace: '${podNamespace}'
    output.kafka:
      hosts: ["kafka:9092"]
      topic: "filebeat-sidecar"
      codec.json:
        pretty: false
      keep_alive: 30s

上面参数说明:

(1)data:存储在 ConfigMap 中的实际数据。在这里,有一个条目,其键为 "filebeat.yml"

(2)filebeat.yml:实际的 Filebeat 配置,使用 YAML 格式表示。该配置设置 Filebeat 从指定路径读取日志,添加额外的字段,并将日志数据输出到 Kafka

(3)filebeat.inputs:这个部分定义了 Filebeat 将收集日志数据的输入源

  • input_type: log:指定 Filebeat 将从日志文件收集日志数据
  • paths:指定 Filebeat 将读取日志文件的路径。在这里,它将读取位于 /data/log/*/*.log 下的所有 .log 扩展名的日志文件。
  • tail_files: true:启用 Filebeat 持续监视并读取日志文件中新增的日志行,如果是false,则表示把日志文件从头读到尾
  • fields:添加到日志事件的附加字段。这些字段似乎是使用环境变量(例如 ${podName}${podIp} 等)动态填充的。当 ConfigMap 在 Pod 中使用时,Kubernetes 可能会动态替换这些变量

(4)output.kafka:这个部分配置了日志数据的输出目标,这里是 Kafka

  • hosts: ["kafka:9092"]:指定 Filebeat 将日志数据发送到哪个 Kafka broker。Kafka broker 的地址为 "kafka:9092"
  • topic: "filebeat-sidecar":指定 Filebeat 将日志数据发布到 Kafka 中的主题名称
  • codec.json:配置 Kafka 数据的编码格式,这里是使用 JSON 格式
  • keep_alive: 30s:指定 Kafka 连接的保持活跃时间。每隔 30 秒检查一次连接是否保持活跃

应用配置文件

[root@k8s-master01 filebeat]# kubectl apply -f filebeat-cm.yaml -n logging

8.查看Pod状态

[root@k8s-master01 filebeat]# kubectl get po -n logging
NAME                                   READY   STATUS              RESTARTS          AGE
app-b8677899d-7nzv9                    2/2     Running             0                 44s
elasticsearch-logging-0                1/1     Running             0                 8h
fluentd-es-v3.1.1-xm9tl                1/1     Running             0                 8h
kafka-0                                1/1     Running             0                 22h
kibana-logging-7bf48fb7b4-bzdzt        1/1     Running             0                 10h
logstash-deployment-6485f5d5b5-8f2n4   1/1     Running             0                 13h
zookeeper-0                            1/1     Running             0                 22h

9.进入容器中查看容器日志,观察到日志内容已经共享

[root@k8s-master01 filebeat]# kubectl exec app-b8677899d-7nzv9 -c filebeat -n logging --  tail -f /data/log/app/date.log
Tue Jul 18 12:26:54 UTC 2023
Tue Jul 18 12:26:56 UTC 2023
Tue Jul 18 12:26:58 UTC 2023
Tue Jul 18 12:27:00 UTC 2023
Tue Jul 18 12:27:02 UTC 2023
Tue Jul 18 12:27:04 UTC 2023
Tue Jul 18 12:27:06 UTC 2023
Tue Jul 18 12:27:08 UTC 2023
Tue Jul 18 12:27:10 UTC 2023
Tue Jul 18 12:27:12 UTC 2023
Tue Jul 18 12:27:14 UTC 2023
...
...

四、Kibana查看日志

1.重新登录Kibana,查看到Kibana已经能读取到上面日志信息

Tue Jul 18 12:26:54 UTC 2023
Tue Jul 18 12:26:56 UTC 2023
Tue Jul 18 12:26:58 UTC 2023
Tue Jul 18 12:27:00 UTC 2023
Tue Jul 18 12:27:02 UTC 2023
Tue Jul 18 12:27:04 UTC 2023
Tue Jul 18 12:27:06 UTC 2023
Tue Jul 18 12:27:08 UTC 2023
Tue Jul 18 12:27:10 UTC 2023
Tue Jul 18 12:27:12 UTC 2023
Tue Jul 18 12:27:14 UTC 2023
...
...

Kibana查看日志-1

2.这里我们添加Filebeat 的索引

点击【Management】-【Stack Management】

Kibana查看日志-2

点击【Index Patterns】-【Create index patterns】

Kibana查看日志-3

输入filebeat*内容点击【Next Step】

Kibana查看日志-4

选择【@timestamp】-【Create index pattern】

Kibana查看日志-5

点击【Discover】

Kibana查看日志-6

切换filebeat*,查看日志信息

Kibana查看日志-7

此时你可以输入自己想查询内容进行查询

"Tue Jul 18 12:26:56 UTC 2023"

Kibana查看日志-8

五、清理环境

删除以上安装环境

[root@k8s-master01 ~]# cd /root/k8s/efk-7.10.2/filebeat
[root@k8s-master01 filebeat]# helm delete kafka zookeeper -n logging
[root@k8s-master01 filebeat]#  kubectl delete -f . -n logging
[root@k8s-master01 filebeat]# cd ..
[root@k8s-master01 efk-7.10.2]# kubectl delete -f . -n logging
[root@k8s-master01 efk-7.10.2]# kubectl label node k8s-node02 fluentd-