vlambda博客
学习文章列表

K8s容器日志实时收集FileBeat+ES+Kibana

由于logstash过于消耗资源,不利于K8s容器日志获取。作为 Beats 家族的一员,Filebeat 是一个轻量级的日志传输工具,它的存在正弥补了 Logstash 的缺点:Filebeat 作为一个轻量级的日志传输工具可以将日志推送到中心 Logstash。


在版本 5.x 中,Elasticsearch 具有解析的能力(像 Logstash 过滤器)— Ingest。这也就意味着可以将数据直接用 Filebeat 推送到 Elasticsearch,并让 Elasticsearch 既做解析的事情,又做存储的事情。也不需要使用缓冲,因为 Filebeat 也会和 Logstash 一样记住上次读取的偏移:

K8s容器日志实时收集FileBeat+ES+Kibana


如果需要缓冲(例如,不希望将日志服务器的文件系统填满),可以使用 Redis/Kafka,因为 Filebeat 可以与它们进行通信:

K8s容器日志实时收集FileBeat+ES+Kibana


Filebeat 优点:

Filebeat 只是一个二进制文件没有任何依赖。它占用资源极少,尽管它还十分年轻,正式因为它简单,所以几乎没有什么可以出错的地方,所以它的可靠性还是很高的。它也为我们提供了很多可以调节的点,例如:它以何种方式搜索新的文件,以及当文件有一段时间没有发生变化时,何时选择关闭文件句柄。

Filebeat 缺点:

Filebeat 的应用范围十分有限,所以在某些场景下我们会碰到问题。例如,如果使用 Logstash 作为下游管道,我们同样会遇到性能问题。正因为如此,Filebeat 的范围在扩大。开始时,它只能将日志发送到 Logstash Elasticsearch,而现在它可以将日志发送给 Kafka Redis,在 5.x 版本中,它还具备过滤的能力


典型应用场景

Filebeat 在解决某些特定的问题时:日志存于文件
将日志直接传输存储到 Elasticsearch。这仅在我们只是抓去(grep)它们或者日志是存于 JSON 格式(Filebeat 可以解析 JSON)。或者如果打算使用 Elasticsearch 的 Ingest 功能对日志进行解析和丰富。

将日志发送到 Kafka/Redis。所以另外一个传输工具(例如,Logstash 或自定义的 Kafka 消费者)可以进一步丰富和转发。这里假设选择的下游传输工具能够满足我们对功能和性能的要求。

FileBeat工作原理


Filebeat是本地文件的日志数据采集器。作为服务器上的代理安装,Filebeat监视日志目录或特定的日志文件tail -f file并将它们转发给ES、Logstash、Kafka等

Filebeat由二个主要组件组成:prospector和havvester 这些组件一起工作读取文件并将时间数据发送到指定的输出

  1. 启动Filebeat时,它会启动一个或多个查找器,查看您的日志文件指定的本地路径。对**prospector**所在的每个日志文件,prospector启动harvester。每个harvester都会为新内容读取单个日志文件,并将新日志数据发送到libbeat,后者将聚合事件合并聚合数据发送到Filebeat配置的输出

K8s容器日志实时收集FileBeat+ES+Kibana

harvester

负载读取单个文化的内容。读取每个文件,并将内容发送到the output。每个文件启动一个harvester,负责打开和关闭文件,这意味着在运行时文件描述符保持打开状态

如果文件在读取时被删除或重命名,Filebeat将继续读取文件。在harvester关闭之前,磁盘上的空间被保留。默认情况下,Filebeat将文件保持打开状态,直到达到close_inactive状态

关闭harvester会产生以下结果

  1. 1.如果在harvester仍在读取文件时文件被删除,则关闭文件句柄,释放底层资源。

  2. 2.文件的采集只会在scan_frequency过后重新开始

  3. 3.如果在harvester关闭的情况下移动文件,则不会继续处理文件

prospector

负责管理harvester并找到所有要读取的文件来源。

如果输入类型为日志,则查找器将查找路径匹配的所有文件,并为每个文件启动一个harvester。每个prospector都在自己的Go斜程中运行

以下示例将Filebeat配置为从与指定的匹配的所有日志文件中收集行:

  1. filebeat.prospectors:

  2. - type: log

  3.  paths:

  4.    - /data/log/*.log

  5.    - /data/log4j/*.log

Filebeat目前支持两种prospector类型:logstdin

每个prospector类型可以定义多次

日志prospector检查每个文件以查看harvester是否需要启动,是否已经运行

只有在harvest关闭后文件大小发生了变化,才会读到新行

注:Filebeat prospector只能读取本地文件,没有功能可以连接到远程主机来读取存储的日志或文件

Filebeat 保持文件状态

Filebeat 保存每个文件的状态并经常讲状态刷新到磁盘上的注册中心中。该状态用于记录harvest正在读取的最后偏移量,并确保发送所有日志行。

如果输出(例如ES或Logstash)无法访问,Filebeat会跟踪最后发送的行,并在输出再次可用时继续读取文件。

在Filebeat运行时,每个prospector内存中也会保存文件状态信息。由于文件可以被重命名活移动,因为文件名和路径不足易识别文件。对每个文件,Filebeat存储唯一标示符以检测文件是否先前已经采集过

Filebeat如何确保至少一次交付

Filebeat保证事件至少会被传送到配置的输出一次,并且不会丢失数据。Filebeat能够实现此行为,因为它将每个事件的传递状态存储在注册文件中。在输出阻塞或未确认所有事件的情况下,Filebeat将继续尝试发送事件,直到接收端确认已收到。

如果Filebeat在发送事件的过程中关闭,它不会等待输出确认所有收到事件。发送到输出但在Filebeat关闭前未确认的任何事在重新启动Filebeat时会再次发送。这可以确保每个事件至少发送一次,但最终会重复事件发送到输出。也可以通过设置shutdown_timeout选项来配置Filebeat以在关闭之前等待特定事件

Docker安装

  1. wget http://down.i4t.com/docker-ce-17.03.2.ce-1.el7.centos.x86_64.rpm

  2. wget http://down.i4t.com/docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch.rpm

  3.  

  4. yum 安装

  5. yum install docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch.rpm -y

  6. yum install docker-ce-17.03.2.ce-1.el7.centos.x86_64.rpm -y

  7.  

  8. systemctl enable docker

  9. systemctl start docker

  10.  

  11. sed -i '/ExecStart=\/usr\/bin\/dockerd/i\ExecStartPost=\/sbin/iptables -I FORWARD -s 0.0.0.0\/0 -d 0.0.0.0\/0 -j ACCEPT' /usr/lib/systemd/system/docker.service

  12. sed -i '/dockerd/s/$/ \-\-storage\-driver\=overlay2/g' /usr/lib/systemd/system/docker.service

  13.  

  14. systemctl daemon-reload

  15. systemctl restart docker

Tomcat镜像制作

  1. Docker文件内容如下

  2. #这里需要把apache和jdk下载到本地,需要和Dockerfile在同一目录

  3. wget http://down.i4t.com/jdk1.8.0_66.tar.gz

  4. wget http://down.i4t.com/apache-tomcat-8.5.39.tar.gz

  5. [root@i4t tomcat_test]# cat Dockerfile

  6. FROM centos

  7. MAINTAINER www.i4t.com "[email protected]"

  8. WORKDIR /tmp

  9. ## Please see https://i4t.com/3552.html   install JDK

  10. COPY jdk1.8.0_66.tar.gz /tmp

  11.    RUN tar zxf /tmp/jdk1.8.0_66.tar.gz -C /usr/local/ && rm -rf /tmp/jdk1.8.0_66.tar.gz

  12.    RUN ln -s /usr/local/jdk1.8.0_66 /usr/local/jdk

  13. #/etc/profile

  14.    ENV JAVA_HOME /usr/local/jdk

  15.    ENV CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

  16.    ENV PATH $PATH:$JAVA_HOME/bin

  17. # add apache

  18. # Please see i4t.com && baidu.com

  19.    COPY apache-tomcat-8.5.39.tar.gz /tmp

  20.    RUN tar zxf apache-tomcat-8.5.39.tar.gz -C /usr/local  && rm -rf /tmp/apache-tomcat-8.5.39.zip

  21.    RUN mv /usr/local/apache-tomcat-8.5.39 /usr/local/tomcat

  22. #port

  23.    EXPOSE 8080

  24. ###############################################################################

  25. #                                   START

  26. ###########################################################

  27. ENTRYPOINT /usr/local/tomcat/bin/startup.sh && tail -f /usr/local/tomcat/logs/catalina.out

构建tomcat镜像

  1. [root@i4t ~]# docker build -t i4t.com/tomcat/tomcat.v1 /data/tomcat_test/

  2. #更改镜像名称

  3. docker tag [原镜像]  [新镜像]

  4. 例子:docker tag i4t.com/tomcat/tomcatv1  i4t.com/tomcat/i4tv1

镜像打包完成后,我们在docker容器手动启动镜像进行测试

  1. [root@i4t tomcat]# docker run -idt --name i4t_tomcat_test -p 80:8080 i4t.com/tomcat/tomcat.v1

  2. f6f1621d9464ea2d17a4611393b1950e36f5b7b6c9234f322d636d47fee94e10

  3.  

  4. #run 运行容器

  5. -it 进入容器

  6. -d  后台运行

  7. --name 新容器名称

  8. -p 映射端口

  9. i4t.com/tomcat/tomcat.v1 镜像名称

容器正常启动访问说明我们tomcat镜像是没有问题

K8s容器日志实时收集FileBeat+ES+Kibana

这里稍微说明一点,如果是线上环境,需要替换war包操作。可以将上面制作的tomcat镜像为基础镜像,在写一个dockerfile。我这里提供一下

 
   
   
 
  1. # cat dockerfile

  2. FROM i4t.com/tomcat/tomcat.v1

  3. MAINTAINER abcdocker "i4t.com"

  4. COPY ROOT.tgz /data/

  5. RUN tar zxf /data/ROOT.tgz -C /usr/local/tomcat/webapps/ && rm -rf /data/ROOT.tgz

  6.  

  7. # docker build -t tomcat_video:v1

  8. # docker tag tomcat_video:v1 i4t.com/tomcat_video:v1

  9. # docker push i4t.com/tomcat_video:v1


Filebeat 制作镜像

Filebeat Dockerfile内容

 
   
   
 
  1. [root@i4t filebeat]# cat Dockerfile

  2. ###############################################################################

  3. # INSTALLATION

  4. ###############################################################################

  5.  

  6. FROM docker.io/centos

  7. MAINTAINER www.i4t.com <cyh@i4t.com>

  8.  

  9. # Install Filebeat

  10. WORKDIR /usr/local

  11. ENV FILEBEAT_VERSION=5.4.0

  12. RUN set -x \

  13. && curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-${FILEBEAT_VERSION}-linux-x86_64.tar.gz \

  14. && tar xf filebeat-${FILEBEAT_VERSION}-linux-x86_64.tar.gz -C /usr/local \

  15. && ln -s /usr/local/filebeat-${FILEBEAT_VERSION}-linux-x86_64 /usr/local/filebeat \

  16. && chmod +x /usr/local/filebeat/filebeat \

  17. && mkdir -p /etc/filebeat

  18.  

  19. ADD ./docker-entrypoint.sh /usr/bin/

  20. RUN chmod +x /usr/bin/docker-entrypoint.sh

  21.  

  22. ENTRYPOINT ["docker-entrypoint.sh"]

  23.  

  24. CMD ["/usr/local/filebeat/filebeat","-e","-c","/etc/filebeat/filebeat.yml"]

  25.  

  26. ######### 脚本内容

  27. [root@i4t filebeat]# cat docker-entrypoint.sh

  28. #!/bin/bash

  29. config=/etc/filebeat/filebeat.yml

  30. env

  31. echo 'Filebeat init process done. Ready for start up.'

  32. echo "Using the following configuration:"

  33. cat /etc/filebeat/filebeat.yml

  34. exec "$@"

  35.  

  36. ## Dockerfile和脚本在同一个目录下,然后进行build

打包完成后我们push到harbor仓库,和tomcat镜像一样的操作

 
   
   
 
  1. [root@i4t tmp]# docker tag tomcat_filebeat:v2 i4t.com/filebeat/v1

  2. [root@i4t tmp]# docker push i4t.com/filebeat/v1:latest

  1. [root@i4t filebeat]# docker build -t tomcat_filebeat:v2 /data/filebeat/

Elasticsearch安装

参考https://i4t.com/3552.html

kibana安装

https://i4t.com/3552.html

测试镜像

tomcat.yaml

 
   
   
 
  1. [root@yzsjhl82-119 tomcat_test]# cat tomcat_test.yaml

  2. apiVersion: extensions/v1beta1

  3. kind: Deployment

  4. metadata:

  5. name: tomcat-abcdocker

  6. namespace: default

  7. spec:

  8. replicas: 1

  9. template:

  10. metadata:

  11. labels:

  12. k8s-app: tomcat-web

  13. spec:

  14. containers:

  15. imagePullPolicy: Always

  16. name: filebeat

  17. volumeMounts:

  18. - name: app-logs

  19. mountPath: /logs

  20. - name: filebeat-config

  21. mountPath: /etc/filebeat/

  22.  

  23. name : tomcat-web

  24. imagePullPolicy: Always

  25. ports:

  26. - containerPort: 8080

  27. volumeMounts:

  28. - name: app-logs

  29. mountPath: /usr/local/tomcat/logs

  30. volumes:

  31. - name: app-logs

  32. emptyDir: {}

  33. - name: filebeat-config

  34. configMap:

  35. name: filebeat-config

tomcat_server.xml (端口暴露)

 
   
   
 
  1. [root@master tomcat_test]# cat tomcat_server.yaml

  2. apiVersion: v1

  3. kind: Service

  4. metadata:

  5. name: tomcat-web

  6. labels:

  7. k8s-app: tomcat-web

  8. spec:

  9. type: NodePort

  10. ports:

  11. - port: 8080

  12. protocol: TCP

  13. targetPort: 8080

  14. name: http

  15. nodePort: 30001

  16. selector:

  17. k8s-app: tomcat-web

configmap.xml

通过configmap的形式创建filebeat.yml配置文件,指定收集日志的路径、elasticsearch的配置信息及索引名称

  1. [root@master tomcat_test]# cat tomcat_configmap.yaml

  2. apiVersion: v1

  3. kind: ConfigMap

  4. metadata:

  5.  name: filebeat-config

  6. data:

  7.  filebeat.yml: |

  8.    filebeat.prospectors:

  9.    - input_type: log

  10.      paths:

  11.        - "/logs/*"

  12.    output.elasticsearch:

  13.      hosts: ["10.4.82.115:9200"]

  14.      index: "filebeat-tomcat-log"

  15.  

  16. # index 索引名称

创建索引

 
   
   
 
  1. [root@master tomcat_test]# kubectl create -f tomcat_configmap.yaml

  2. configmap/filebeat-config created

  3. [root@master tomcat_test]# kubectl create -f tomcat_test.yaml

  4. deployment.extensions/tomcat-abcdocker created

  5. [root@master tomcat_test]# kubectl create -f tomcat_server.yaml

  6. service/tomcat-web created

服务检查

我们需要检查以下

 
   
   
 
  1. 1.检查pod是否运行正常

  2. 2.检查server是否正常

  3. 3.检查configmap是否创建完成

  4. 4.kubectl常用命令 https://k.i4t.com/15356201695268.html

查看服务整个状态是否正常

 
   
   
 
  1. [root@master tomcat_test]# kubectl get svc,pod,configmap

  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

  3. service/kubernetes ClusterIP 10.254.0.1 443/TCP 97d

  4. service/nginx-service NodePort 10.254.167.71 80:31000/TCP 97d

  5. service/tomcat-web NodePort 10.254.237.208 8080:30001/TCP 3m

  6.  

  7. NAME READY STATUS RESTARTS AGE

  8. pod/tomcat-abcdocker-56f9547997-2zz7c 2/2 Running 0 3m

  9.  

  10. NAME DATA AGE

  11. configmap/filebeat-config 1 3m

查看pod容器是否异常

 
   
   
 
  1. 1.查看tomcat镜像日志

  2. kubectl logs tomcat-abcdocker-56f9547997-2zz7c filebeat

  3.  

  4. #这里的pod名称可能不是这个

  5.  

  6. 2.查看filebeat镜像日志

  7. kubectl logs tomcat-abcdocker-56f9547997-2zz7c tomcat-web

Filebeat log

K8s容器日志实时收集FileBeat+ES+Kibana

tomcat log

K8s容器日志实时收集FileBeat+ES+Kibana

k8s服务是没有问题,我们浏览器访问一下

端口为30001

K8s容器日志实时收集FileBeat+ES+Kibana

接下来查看一下es日志

  1. [root@i4t ~]# curl -XGET '10.4.82.115:9200/_cat/indices?v&pretty'

  2. health status index               uuid                   pri rep docs.count docs.deleted store.size pri.store.size

  3. yellow open   filebeat-tomcat-log jRWrRLQjQ2SPTAe-wmy_EA   5   1        272            0    244.6kb        244.6kb

通过head插件查看是否有数据

K8s容器日志实时收集FileBeat+ES+Kibana

K8s容器日志实时收集FileBeat+ES+Kibana

进入kibana控制台