龙空技术网

运维必备技能:Docker日志管理分析-ELK

删库跑路吧 1798

前言:

目前各位老铁们对“elknginx”大概比较着重,小伙伴们都需要知道一些“elknginx”的相关资讯。那么小编同时在网摘上网罗了一些关于“elknginx””的相关内容,希望大家能喜欢,大家一起来了解一下吧!

技能目标:

· 掌握Docker容器部署elk环境

· 了解Filebeat日志收集原理

· 掌握Logstash过滤模式匹配

6.1 案例分析

6.1.1 案例概述

在前面课程中,已经详细介绍了elk各个组件之间的关系,并且可以通过elk收集简单的系统日志,其中只有Logstash、Elasticsearch 和 Kibana 实例。这种架构非常简单并且有缺陷。初学者可以搭建这个架构,了解 ELK是如何工作的。本章基于 Docker + Filebeat架构详细介绍生产环境下的日志收集与分析。

6.1.2 案例前置知识点

1. ELK(elasticserach、logstash、kibana)

在前面课程中已经详细介绍过,具体原理性知识点这里不再展开,只会体现docker构建ELK环境实现过程。

2. 什么是Filebeat

Filebeat是ELK 组件的新成员也是Beat成员之一。基于Go语言开发,无任何依赖,并且比logstash更加轻量,非常适合安装在生产机器上,不会带来过高的资源占用。轻量意味着简单,所以Filebeat并没有集成和logstash一样的正则处理功能,而是将收集的日志原样输出。

以下是Filebeat的工作流程:当开启Filebeat程序的时候,它会启动一个或多个检测进程(prospectors)找到指定的日志目录或文件。对于探测器找出的每一个日志文件,filebeat启动读取进程(harvester)。每读取一个日志文件的新内容,并发送这些新的日志数据到处理程序(spooler)。最后,Filebeat会发送数据到指定的地点(比如logstash、elasticserach)等。

正式以上原因,目前, Filebeat 已经完全替代了Logstash成为新一代的日志采集器,同时鉴于它轻量、安全等特点,越来越多人开始使用它。

本章节将详细讲解如何部署基于 Filebeat 的 ELK 集中式日志解决方案,具体架构如图6.1所示。

图6.1基于 Filebeat+ELK集群架构

3. Docker日志管理架构缺陷

这种架构适合于日志规模比较庞大的情况。但由于 Logstash 日志解析节点和 Elasticsearch 的负荷比较重,可将他们配置为集群模式,以分担负荷。引入消息队列,均衡了网络传输,从而降低了网络闭塞,尤其是丢失数据的可能性,但依然存在 Logstash 占用系统资源过多的问题。

6.1.3 案例环境

1. 本案例实验环境

本案例环境如表6-1所示。

表5-1 Docker日志管理环境

2. 案例需求

1)利用F-ELK收集容器里面的日志。

2)通过Kibana将收集到日志做图表分析。

3. 案例实现思路

1)准备系统环境。

2)构建F-ELK组件镜像。

3)创建F-ELK容器收集容器里面的Nginx日志。

4)创建Kibana图形展示。

6.2 案例实施

基于Docker环境部署ELK-F日志分析系统,实现日志分析功能。

1. 系统环境准备

1)创建所需要映射目录

[root@localhost ~]# mkdir -p /var/log/elasticsearch // 根据实际情况做修改

[root@localhost ~]# chmod -R 777 /var/log/elasticsearch

2)系统参数修改

[root@localhost ~]# vim /etc/sysctl.conf

vm.max_map_count=655360

[root@localhost ~]# sysctl -p

[root@localhost ~]# vim /etc/security/limits.conf

* soft nofile 65535

* hard nofile 65535

* soft nproc 65535

* hard nproc 65535

* soft memlock unlimited

* hard memlock unlimited

3)单独创建elk-kgc网络桥接

[root@localhost ~]# docker network create elk-kgc

c41651f34b547addf9887ba17303d3fcaf3f8d0bccfad9fd237556ba13c63e9d

[root@localhost ~]# docker network ls

NETWORK ID NAME DRIVER SCOPE

a4c4cdbdf774 bridge bridge local

c41651f34b54 elk-kgc bridge local

8ac6515a8a52 host host local

0ddf902ed096 none null local

2. 准备基于Dockerfile构建Elasticsearch镜像

1)创建Elasticsearch工作目录

[root@localhost ~]# mkdir -p /root/elk/elasticsearch

2)编写Elasticsearch的Dockerfile文件

[root@localhost ~]# cd /root/elk/elasticsearch

[root@localhost elasticsearch]# vim Dockerfile

FROM centos:latest

MAINTAINER k@kgc.cn

RUN yum -y install java-1.8.0-openjdk vim telnet lsof

ADD elasticsearch-6.1.0.tar.gz /usr/local/

RUN cd /usr/local/elasticsearch-6.1.0/config

RUN mkdir -p /data/behavior/log-node1

RUN mkdir /var/log/elasticsearch

COPY elasticsearch.yml /usr/local/elasticsearch-6.1.0/config/

RUN useradd es && chown -R es:es /usr/local/elasticsearch-6.1.0/

RUN chmod +x /usr/local/elasticsearch-6.1.0/bin/*

RUN chown -R es:es /var/log/elasticsearch/

RUN chown -R es:es /data/behavior/log-node1/

RUN sed -i s/-Xms1g/-Xms2g/g /usr/local/elasticsearch-6.1.0/config/jvm.options

RUN sed -i s/-Xmx1g/-Xmx2g/g /usr/local/elasticsearch-6.1.0/config/jvm.options

EXPOSE 9200

EXPOSE 9300

CMD su es /usr/local/elasticsearch-6.1.0/bin/elasticsearch

3)上传elasticsearch源码包和elasticsearch配置文件

上传elasticsearch的源码包和elasticsearch配置文件到/root/elk/elasticsearch目录下,所需文件如下:

[root@localhost elasticsearch]# ll

总用量 27876

-rw-r--r--. 1 root root 1344 5月 9 14:23 Dockerfile

-rw-r--r--. 1 root root 28535876 5月 9 14:23 elasticsearch-6.1.0.tar.gz

-rw-r-----. 1 root root 3017 5月 9 14:33 elasticsearch.yml

4)构建elasticsearch镜像

[root@localhost elasticsearch]# docker build -t elasticsearch .

3. 准备基于Dockerfile构建Kibana镜像

1)创建Kibana工作目录

[root@localhost ~]# mkdir –p /root/elk/kibana

2)编写Kibana的Dockerfile文件

[root@localhost ~]# cd /root/elk/kibana

[root@localhost kibana]# vim Dockerfile

FROM centos:latest

MAINTAINER k@kgc.cn

RUN yum -y install java-1.8.0-openjdk vim telnet lsof

ADD kibana-6.1.0-linux-x86_64.tar.gz /usr/local/

RUN cd /usr/local/kibana-6.1.0-linux-x86_64

RUN sed -i s/"#server.name: \"your-hostname\""/"server.name: kibana-hostname"/g /usr/local/kibana-6.1.0-linux-x86_64/config/kibana.yml

RUN sed -i s/"#server.port: 5601"/"server.port: 5601"/g /usr/local/kibana-6.1.0-linux-x86_64/config/kibana.yml

RUN sed -i s/"#server.host: \"localhost\""/"server.host: 0.0.0.0"/g /usr/local/kibana-6.1.0-linux-x86_64/config/kibana.yml

RUN sed -ri '/elasticsearch.url/ s/^#|"//g' /usr/local/kibana-6.1.0-linux-x86_64/config/kibana.yml

RUN sed -i s/localhost:9200/elasticsearch:9200/g /usr/local/kibana-6.1.0-linux-x86_64/config/kibana.yml

EXPOSE 5601

CMD ["/usr/local/kibana-6.1.0-linux-x86_64/bin/kibana"]

3)上传kibana的源码包

上传kibana的源码包到/root/elk/kibana目录下,所需文件如下:

[root@localhost kibana]# ll

总用量 64408

-rw-r--r--. 1 root root 967 5月 9 14:45 Dockerfile

-rw-r--r--. 1 root root 65947685 5月 9 14:23 kibana-6.1.0-linux-x86_64.tar.gz

4)构建kibana镜像

[root@localhost kibana]# docker build -t kibana .

4. 准备基于Dockerfile构建Logstash镜像

1)创建Logstash工作目录

[root@localhost ~]# mkdir –p /root/elk/logstash

2)编写Logstash的Dockerfile文件

[root@localhost ~]# cd /root/elk/logstash

[root@localhost logstash]# vim Dockerfile

FROM centos:latest

MAINTAINER shikun.zhou@bdqn.cn

RUN yum -y install java-1.8.0-openjdk vim telnet lsof

ADD logstash-6.1.0.tar.gz /usr/local/

RUN cd /usr/local/logstash-6.1.0

ADD run.sh /run.sh

RUN chmod 755 /*.sh

EXPOSE 5044

CMD ["/run.sh"]

3)创建上述Dockerfile中CMD运行的脚本文件

[root@localhost logstash]# vim run.sh

#!/bin/bash

/usr/local/logstash-6.1.0/bin/logstash -f /opt/logstash/conf/nginx-log.conf

4)上传logstash的源码包

上传logstash的源码包到/root/elk/logstash目录下,所需文件如下:

[root@localhost logstash]# ll

总用量 107152

-rw-r--r--. 1 root root 244 5月 10 10:35 Dockerfile

-rw-r--r--. 1 root root 109714065 5月 9 14:51 logstash-6.1.0.tar.gz

-rw-r--r--. 1 root root 88 5月 10 10:35 run.sh

5) 构建logstash镜像

[root@localhost logstash]# docker build -t logstash .

6)logstash配置文件详解

logstash功能非常强大,不仅仅是分析传入的文本,还可以作监控与告警之用。本节介绍配置与使用经验。

logstash默认的配置文件不需要修改,只需要启动的时候指定一个配置文件即可!比如run.sh脚本中指定/opt/logstash/conf/nginx-log.conf。注意文件里面包含了三部分,input、filter、output。其中filter不是必须的。

[root@localhost ~]# mkdir -p /opt/logstash/conf

[root@localhost ~]# vim /opt/logstash/conf/nginx-log.conf

input {

beats {

port => 5044

}

}

filter {

if "www-bdqn-cn-pro-access" in [tags] {

grok {

match => {"message" => '%{QS:agent} \"%{IPORHOST:http_x_forwarded_for}\" - \[%{HTTPDATE:timestamp}\] \"(?:%{WORD:verb}

%{NOTSPACE:request}(?: HTTP/%{NUMBER:http_version})?|-)\" %{NUMBER:response} %{NUMBER:bytes} %{QS:referrer} %{IPORHOST:remote_addr}:%{P

OSINT:port} %{NUMBER:remote_addr_response} %{BASE16FLOAT:request_time}'}

}

}

urldecode {all_fields => true}

date {

match => [ "timestamp" , "dd/MMM/YYYY:HH:mm:ss Z" ]

}

useragent {

source => "agent"

target => "ua"

}

}

output {

if "www-bdqn-cn-pro-access" in [tags] {

elasticsearch {

hosts => ["elasticsearch:9200"]

manage_template => false

index => "www-bdqn-cn-pro-access-%{+YYYY.MM.dd}"

}

}

}

注意:上面nginx-log.conf文件拷贝的时候注意match最长的一行自动换行问题。

(1)关于nginx-log.conf文件中filter部分

下面详细介绍nginx-log.conf文件中filter部分。

输入和输出在logstash配置中是很简单的一步,而对数据进行匹配处理则显得异常复杂。匹配单行日志是入门水平需要掌握的,而多行甚至不规则的日志则可能需要ruby的协助。这里主要展示使用grok插件。

以下是某生产环境nginx的access日志格式:

log_format main '"$http_user_agent" "$http_x_forwarded_for" '

'$remote_user [$time_local] "$request" '

'$status $body_bytes_sent "$http_referer" '

'$upstream_addr $upstream_status $upstream_response_time';

下面是对应上述nginx日志格式的grok捕获语法:

'%{QS:agent} \"%{IPORHOST:http_x_forwarded_for}\" - \[%{HTTPDATE:timestamp}\] \"(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:http_version})?|-)\" %{NUMBER:response} %{NUMBER:bytes} %{QS:referrer} %{IPORHOST:remote_addr}:%{POSINT:port} %{NUMBER:remote_addr_response} %{BASE16FLOAT:request_time}'}

在filter段内的第一行是判断语句,如果www-bdqn-cn-pro-access自定义字符在tags内,则使用grok段内的语句对日志进行处理。

① geoip:使用GeoIP数据库对client_ip字段的IP地址进行解析,可得出该IP的经纬度、国家与城市等信息,但精确度不高,这主要依赖于GeoIP数据库。

② date:默认情况下,elasticsearch内记录的date字段是elasticsearch接收到该日志的时间,但在实际应用中需要修改为日志中所记录的时间。这时,需要指定记录时间的字段并指定时间格式。如果匹配成功,则会将日志的时间替换至date字段中。

③ useragent:主要为web app提供的解析,可以解析目前常见的一些useragent。

关于更多相关的语法可以参考以下GitHub页面:

在编写grok捕获规则时,可以使用以下网站进行辅助(但是前提是能翻墙):

如果语法没问题,会显示的界面效果如图6.2所示。

图6.2

(2)关于output部分

本案例中logstash服务节点只有一个,所以输出配置如下:

logstash可以在上层配置一个负载均衡器实现集群。在实际应用中,logstash服务需要处理多种不同类型的日志或数据。处理后的日志或数据需要存放在不同的elasticsearch集群或索引中,需要对日志进行分类。

output {

if "www-bdqn-cn-pro-access" in [tags] {

elasticsearch {

hosts => ["elasticsearch:9200"]

manage_template => false

index => "www-bdqn-cn-pro-access-%{+YYYY.MM.dd}"

}

}

}

通过在output配置中设定判断语句,将处理后的数据存放到不同的索引中。而这个tags的添加有以下三种途径:

① 在filebeat读取数据后,向logstash发送前添加到数据中。

② logstash处理日志的时候,向tags标签添加自定义内容。

③ 在logstash接收传入数据时,向tags标签添加自定义内容。

从上面的输入配置文件中可以看出,这里采用的第一种途径,在filebeat读取数据后,向logstash发送数据前添加www-bdqn-cn-pro-access的tag。

这个操作除非在后续处理处理数据的时候手动将其删除,否则将永久存在该数据中。

elasticsearch字段中的各参数的意义如下:

· hosts:指定elasticsearch地址,如有多个节点可用,可以设为array模式,可实现负载均衡;

· manage_template:如果该索引没有合适的模板可用,默认情况下将由默认的模板进行管理;

· index:指定存储数据的索引。

Logstash配置文件配置完成后即可启动logstash容器服务,需要注意的是logstash启动时间较长,请耐心等待。

5. 准备基于Dockerfile构建Filebeat镜像

1)创建Filebeat工作目录

[root@localhost ~]# mkdir –p /root/elk/filebeat

2)编写Filebeat的Dockerfile文件

[root@localhost ~]# cd /root/elk/filebeat

[root@localhost filebeat]# vim Dockerfile

FROM centos:latest

MAINTAINER k@kgc.cn

RUN yum -y install java-1.8.0-openjdk vim telnet lsof

ADD filebeat-6.1.0-linux-x86_64.tar.gz /usr/local/

RUN cd /usr/local/filebeat-6.1.0-linux-x86_64

RUN mv /usr/local/filebeat-6.1.0-linux-x86_64/filebeat.yml /root/

COPY filebeat.yml /usr/local/filebeat-6.1.0-linux-x86_64/

ADD run.sh /run.sh

RUN chmod 755 /*.sh

CMD ["/run.sh"]

3)创建上述Dockerfile里面CMD运行的脚本文件

[root@localhost filebeat]# vim run.sh

#!/bin/bash

/usr/local/filebeat-6.1.0-linux-x86_64/filebeat -e -c /usr/local/filebeat-6.1.0-linux-x86_64/filebeat.yml

4)上传filebeat的源码包和filebeat配置文件

上传filebeat的源码包和filebeat配置文件到/root/elk/filebeat目录下,所需文件如下:

[root@localhost filebeat]# ll

总用量 11660

-rw-r--r--. 1 root root 380 5月 10 09:42 Dockerfile

-rw-r--r--. 1 root root 11926942 5月 9 16:02 filebeat-6.1.0-linux-x86_64.tar.gz

-rw-r--r--. 1 root root 186 5月 10 09:58 filebeat.yml

-rwxr-xr-x. 1 root root 118 5月 10 09:40 run.sh

5)构建filebeat镜像

[root@localhost filebeat]# docker build -t filebeat .

6)Filebeat配置文件详解

filebeat的配置文件:

[root@localhost filebeat]# cat filebeat.yml

filebeat.prospectors:

- input_type: log

paths:

- /var/log/nginx/

tags: ["www-bdqn-cn-pro-access"]

clean_*: true

output.logstash:

hosts: ["logstash:5044"]

每个filebeat可以根据需求的不同拥有一个或多个prospectors,其他配置信息含义如下:

· input_type:输入内容,主要为逐行读取的log格式与标准输入stdin。

· paths:指定需要读取日志的路径,如果路径拥有相同的结构,则可以使用通配符。

· tags:为该路径的日志添加自定义tags。

· clean_:filebeat在/var/lib/filebeat/registry下有一个注册表文件,它记录着filebeat读取过的文件,还有已经读取的行数等信息。如果日志文件是定时分割,而且数量会随之增加,那么该注册表文件也会慢慢增大。随着注册表文件的增大,会导致filebeat检索的性能下降。

· output.logstash:定义内容输出的路径,这里主要输出到elasticsearch。

· hosts:指定服务器地址。

Filebeat配置文件配置完成后即可启动filebeat容器服务。

6. 启动一个 nginx 容器做为日志输入源

[root@localhost ~]# docker run -itd -p 80:80 --network elk-kgc -v /var/log/nginx:/var/log/nginx --name nginx-elk nginx:latest

本地目录/var/log/nginx必须挂载到 filebeat 容器里面,让filebeat 可以采集到日志目录。

手动模拟生产环境6条日志文件作为nginx容器所产生的站点日志,同样注意拷贝的时候换行的问题。

[root@localhost ~]# vim /var/log/nginx/

"YisouSpider" "106.11.155.156" - [18/Jul/2018:00:00:13 +0800] "GET /applier/position?gwid=17728&qyid=122257 HTTP/1.0" 200 9197 "-" 192.168.168.108:80 200 0.032

"-" "162.209.213.146" - [18/Jul/2018:00:02:11 +0800] "GET //tag/7764.shtml HTTP/1.0" 200 24922 "-" 192.168.168.108:80 200 0.074

"YisouSpider" "106.11.152.248" - [18/Jul/2018:00:07:44 +0800] "GET /news/201712/21424.shtml HTTP/1.0" 200 8821 "-" 192.168.168.110:80 200 0.097

"YisouSpider" "106.11.158.233" - [18/Jul/2018:00:07:44 +0800] "GET /news/201301/7672.shtml HTTP/1.0" 200 8666 "-" 192.168.168.110:80 200 0.111

"YisouSpider" "106.11.159.250" - [18/Jul/2018:00:07:44 +0800] "GET /news/info/id/7312.html HTTP/1.0" 200 6617 "-" 192.168.168.110:80 200 0.339

"Mozilla/5.0 (compatible; SemrushBot/2~bl; +)" "46.229.168.83" - [18/Jul/2018:00:08:57 +0800] "GET /tag/1134.shtml HTTP/1.0" 200 6030 "-" 192.168.168.108:80 200 0.079

7. 启动Filebeat+ELK日志收集环境

注意:启动顺序和查看启动日志。

1)启动elasticsearch

[root@localhost ~]# docker run -itd -p 9200:9200 -p 9300:9300 --network elk-kgc -v /var/log/elasticsearch:/var/log/elasticsearch --name elasticsearch elasticsearch

2)启动kibana

[root@localhost ~]# docker run -itd -p 5601:5601 --network elk-kgc --name kibana kibana

3)启动logstash

[root@localhost ~]# docker run -itd -p 5044:5044 --network elk-kgc -v /opt/logstash/conf:/opt/logstash/conf --name logstash logstash

4)启动filebeat

[root@localhost ~]# docker run -itd --network elk-kgc -v /var/log/nginx:/var/log/nginx --name filebeat filebeat

8. Kibana图形展示

kibana的数据需要从elasticsearch中读取,所以需要elasticsearch中有数据才能创建索引,创建不同的索引区分不同的数据集。

1)浏览器输入访问kibana控制台。在Management中找到Index patterns,点击进去可以看到类似以下图片中的界面,填写www-bdqn-cn-pro-access-*作为索引,如图6.3所示。

图6.3

2)在Time Filter field name选项框中选中@timestemp这个选项,如图6.4所示。在kibana中,默认通过时间戳来排序。如果将日志存入elasticsearch的时候没有指定@timestamp这个字段的内容,则elasticsearch会为该日志分配接收到该日志时的时间为@timestamp的值。

图6.4

3)点击"Create index pattern"按钮,创建www-bdqn-cn-pro-access索引后界面效果如图6.5所示。

图6.5

4)点击Discover标签,可能会看不到数据。需要将时间轴选中为"This year"才可以看到的内容,显示的条数和日志的条数一致。具体时间轴的选择可以根据当前时间和日志里面的访问时间进行推算,如图6.6。

图6.6

5)从图6.6中看到有数据不代表就正常,因为数据都会通过logstash处理进入elasticsearch中存储。但是不一定是通过上面编写的正则处理后的数据,所以还需要观察左侧的字段是否含义正则里面定义的字段。如果有,则说明正常,界面的效果如图6.7所示。

图6.7

9. Kibana图形按字段分析

接下来,只需要打开kibana的管理界面 –>visualize标签->Create a visualization->选择饼状图pie->添加索引www-bdqn-cn-pro-access-*->点开Split Slices->选择Terms->再从Field选择 –> http_x_forworded_for.keyword->最后点上面三角按钮即可生成访问最多的5个公网IP,如图6.8所示:

图6.8

第 12 页 共 13 页

标签: #elknginx