被一位读者赶超,手摸手 Docker 部署 ELK Stack

被一位读者赶超,容器化部署 ELK Stack

你好,我是悟空。

被奇幻“催更”

最近有个读者,他叫“老王“,外号“茴香豆泡酒”,找我崔更 ELK 的文章。

因之前我用的是软件安装 Logstash + Filebeat 的方式:

7000 字 | 20 图 | 一文带你搭建一套 ELK Stack 日志平台

他想知道如何用容器化部署 ELK,于是我先写了一半,因为要写其他文章所以耽搁了。没想到过了几天后,老王说他已经部署好了,还写了篇文章,恐怖如斯啊!

那可不行,我不能输给他,必须自己安排一篇。那么我写的这篇有哪些特色内容呢?

  • 支持离线环境部署 ELK。
  • 支持离线安装 Logstash 多行插件。
  • 生产级别 Logstash 配置。
  • 生产级别 Filebeat 配置。
  • Filebeat 如何做到重新同步导入。
  • 一步一图,手摸手教程了。

本文主要内容如下:

被一位读者赶超,手摸手 Docker 部署 ELK Stack

前言

这次我们演示在单机上用 Docker 部署 ELK Stack,大家可以参照这个教程部署在集群环境中。

ELK Stack 整体的工作流程如下:

被一位读者赶超,手摸手 Docker 部署 ELK Stack

流程如下:

  • 1、微服务写入日志到本地文件中。
  • 2、Filebeat 组件监控日志文件变化,将日志收集起来。
  • 3、Filebeat 把数据传给 Logstash 组件。
  • 4、Logstash 具有强大的数据清洗和过滤功能,然后写入到 Elasticsearch 中。
  • 5、Kibana 可视化工具从 Elasticsearch 中查询数据并展示出来。

演示环境:

  • Ubuntu 18.04 虚拟机一台
  • Elasticsearch、Logstash、Kibana、Filebeat、容器的版本为 7.6.2

最后启动了 5 个容器:

被一位读者赶超,手摸手 Docker 部署 ELK Stack

一、Docker 方式部署 Elasticsearch 数据库

1.1 安装 Elasticsearch

方案一:从互联网下载 Elasticsearch 镜像

docker pull elasticsearch:7.6.2 

方案二:离线安装加载 Elasticsearch 镜像

# 从有互联网的机器上下载 Elasticsearch  镜像 sudo docker pull elasticsearch:7.6.2 # 从有互联网的机器上保存 logstash 镜像 sudo docker save -o es.tar es # 设置 logstash 镜像的权限,保证能有权限拷贝到其他机器 sudo chmod 777 es.tar # 在离线的机器上加载 logstash 镜像 sudo docker load -i es.tar 

被一位读者赶超,手摸手 Docker 部署 ELK Stack

1.2 配置 ES

创建挂载目录

mkdir -p /data/elk/es/{config,data,logs,plugins} 

被一位读者赶超,手摸手 Docker 部署 ELK Stack

赋予权限

sudo chown -R 1000:1000 /data/elk/es 

创建配置文件

cd /data/elk/es/config sudo touch elasticsearch.yml -----------------------配置内容---------------------------------- cluster.name: "my-es" network.host: 0.0.0.0 http.port: 9200 http.cors.enabled: true http.cors.allow-origin: "*" 

1.3 启动 elasticsearch 容器

docker run -it  -d  -p 9200:9200  -p 9300:9300  --name es01  -e ES_JAVA_OPTS="-Xms1g -Xmx1g"  -e "discovery.type=single-node"  --restart=always  -v /data/elk/es/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml  -v /data/elk/es/data:/usr/share/elasticsearch/data  -v /data/elk/es/logs:/usr/share/elasticsearch/logs  -v /data/elk/es/plugins:/usr/share/elasticsearch/plugins  elasticsearch:7.6.2 

被一位读者赶超,手摸手 Docker 部署 ELK Stack

1.4 验证 elasticsearch 是否启动成功

curl http://localhost:9200 

被一位读者赶超,手摸手 Docker 部署 ELK Stack

1.5 安装 ES 辅助工具

这个工具安装好了后,相当于启动了一个服务,这个服务是一个站点,通过在站点里面访问 ES 的 API,就可以获取到 ES 的当前信息了。

安装步骤如下:

  • 下载 elasticsearch-head 镜像
sudo docker pull mobz/elasticsearch-head:5  
  • 运行 elasticsearch-head 容器

docker run -d -p 9100 9100 mobz/elasticsearch-head:5

  • 用浏览器访问 elasticsearch-head 网址
http://192.168.56.11:9100/ 
  • 修改网站中的 ES 的连接地址
http://192.168.56.11:9200/ 

被一位读者赶超,手摸手 Docker 部署 ELK Stack

就可以看到 ES 的集群和索引信息了,这个要比在 Kibana 中用 DevTools 查看更方便。

1.6 IK 分词器

https://github.com/medcl/elasticsearch-analysis-ik/releases 

选择 ES 对应版本的 IK 分词器,我的 ES 版本为 7.6.2。

被一位读者赶超,手摸手 Docker 部署 ELK Stack

解压后,拷贝到 /data/elk/es/plugins/ik/ 目录

被一位读者赶超,手摸手 Docker 部署 ELK Stack

二、Docker 方式部署 Kibana 可视化工具

2.1 安装 Kibana

获取 kibana 镜像

docker pull kibana:7.7.1 

获取elasticsearch容器 ip

docker inspect --format '{{ .NetworkSettings.IPAddress }}' es01 

结果:172.17.0.2

创建 kibana 配置文件

mkdir -p /data/elk/kibana/ vim /data/elk/kibana/kibana.yml 

配置内容:

#Default Kibana configuration for docker target server.name: kibana server.host: "0" elasticsearch.hosts: ["http://172.17.0.2:9200"] xpack.monitoring.ui.container.elasticsearch.enabled: true 

2.2 运行 kibana

docker run -it -d  --restart=always  --name kibana -p 5601:5601 -v /data/elk/kibana/kibana.yml:/usr/share/kibana/config/kibana.yml kibana:7.6.2  

访问 http://192.168.56.10:5601 。这个 IP 是服务器或虚拟机的 IP。Kibana 控制台的界面如下所示,打开 kibana 时,首页会提示让你选择加入一些测试数据,点击 try our sample data 按钮就可以了。

被一位读者赶超,手摸手 Docker 部署 ELK Stack

Kibana 界面上会提示你是否导入样例数据,选一个后,Kibana 会帮你自动导入,然后就可以进入到 Discover 窗口搜索日志了。

被一位读者赶超,手摸手 Docker 部署 ELK Stack

离线方式安装 Kibana 方式

sudo docker save -o kibana.tar kibana sudo chmod 777 kibana.tar sudo docker load -i kibana.tar 

被一位读者赶超,手摸手 Docker 部署 ELK Stack

三、Docker 方式安装 Logstash

3.1 拉取 Logstash 镜像

方案一:从互联网下载镜像

sudo docker pull logstash:7.6.2 

方案二:离线安装镜像

# 从有互联网的机器上下载 logstash 镜像 sudo docker save -o logstash.tar logstash # 设置 logstash 镜像的权限,保证能有权限拷贝到其他机器 sudo chmod 777 logstash.tar # 在离线的机器上加载 logstash 镜像 sudo docker load -i logstash.tar 

临时方式启动,主要是为了映射整个 Logstash 目录,后面方便安装 logstash 插件

docker run -d --name=logstash logstash:7.6.2 

将容器内的文件夹拷贝到宿主机磁盘上

sudo docker cp logstash:/usr/share/logstash /data/elk 

被一位读者赶超,手摸手 Docker 部署 ELK Stack

添加 logstash 文件夹的权限

cd /data/elk/ sudo chmod 777 logstash -R 

3.2 创建采集配置文件

创建 logstash.conf 采集配置文件

sudo mkdir -p /data/elk/logstash/conf.d cd /data/elk/logstash/conf.d sudo vim logstash.conf 

配置内容如下:

input {   beats {     port => 5044   } }  filter {      grok {       match => [ "message", "(?<logTime>d{4}-d{2}-d{2}sd{2}:d{2}:d{2}.d{3})s+[(?<thread>.*)]s+(?<level>w*)s{1,2}+(?<class>S*)s+-s+(?<content>.*)s*"]       match => [ "message", "(?<logTime>d{4}-d{2}-d{2}sd{2}:d{2}:d{2}.d{3})s{1,2}+(?<level>w*)s{1,2}+.s---+s[(?<thread>.*)]+s(?<class>S*)s*:+s(?<content>.*)s*"]       match => [            "source", "/home/passjava/logs/(?<logName>w+)/.*.log"        ]       overwrite => [ "source"]       break_on_match => false   }    mutate {     convert => {       "bytes" => "integer"     }     remove_field => ["agent","message","@version", "tags", "ecs", "_score", "input", "[log][offset]"]   }    useragent {     source => "user_agent"     target => "useragent"   }    date {     match => ["logTime", "MMM d HH:mm:ss", "MMM dd HH:mm:ss", "ISO8601"]     timezone => "Asia/Shanghai"   } }  output {   stdout { }    elasticsearch {     hosts => ["192.168.56.11:9200"]     index => "passjava_log"   } } 

3.3 创建 logstash 配置文件

创建 logstash.yml 配置文件

cd /data/elk/logstash/config sudo vim logstash.yml 

配置内容如下:

# 指定管道配置的目录,在此目录下的所有管道配置文件都将被 logstash 读取,除管道配置外,不要放任何文件 path.config: /usr/share/logstash/conf.d/*.conf # logstash 日志目录位置,默认为 logstash 路径下的 logs path.logs: /var/log/logstash http.host: "0.0.0.0" xpack.monitoring.elasticsearch.hosts: [ "http://192.168.56.11:9200" ] 

3.4 启动 logstash 容器

# 删除 logstash 容器 docker rm -f logstash # 启动 logstash 容器 docker run -it -d  -p 5044:5044  --name logstash  --restart=always  -v /data/elk/logstash:/usr/share/logstash  logstash:7.6.2 

被一位读者赶超,手摸手 Docker 部署 ELK Stack

查看日志

被一位读者赶超,手摸手 Docker 部署 ELK Stack

3.5 安装 multiline 插件

还有一个坑的地方是错误日志一般都是很多行的,会把堆栈信息打印出来,当经过 logstash 解析后,每一行都会当做一条记录存放到 ES,那这种情况肯定是需要处理的。这里就需要使用 multiline 插件,对属于同一个条日志的记录进行拼接。

3.5.1 安装 multiline 插件

multiline 不是 logstash 自带的,需要单独进行安装。我们的环境是没有外网的,所以需要进行离线安装。

介绍在线和离线安装 multiline 的方式:

  • 在线安装插件。

在 logstash 根目录执行以下命令进行安装。

bin/logstash-plugin install logstash-filter-multiline 

被一位读者赶超,手摸手 Docker 部署 ELK Stack

  • 离线安装插件。

在有网的机器上在线安装插件,然后打包。

bin/logstash-plugin install logstash-filter-multiline bin/logstash-plugin prepare-offline-pack logstash-filter-multiline 

拷贝到服务器,/data/elk/logstash/mutiline

被一位读者赶超,手摸手 Docker 部署 ELK Stack

进入到容器中

docker exec -it logstash /bin/bash 

执行安装命令

cd /usr/share/logstash bin/logstash-plugin install file:///usr/share/logstash/mutiline/logstash-offline-plugins-7.6.2.zip 

安装插件需要等待 2 分钟左右的时间,控制台界面会被 hang 住,当出现 Install successful 表示安装成功。

被一位读者赶超,手摸手 Docker 部署 ELK Stack

检查下插件是否安装成功,可以执行以下命令查看插件列表。当出现 multiline 插件时则表示安装成功。

bin/logstash-plugin list 
被一位读者赶超,手摸手 Docker 部署 ELK Stack

3.5.2 添加 mutiline 配置

编辑 logstash.conf 配置文件

cd /data/elk/logstash/conf.d/ sudo vim logstash.conf 

filter 节点下添加 mutiline 配置。

input {   beats {     port => 5044   } }  filter {    multiline {     pattern => "^d{4}-d{1,2}-d{1,2}sd{1,2}:d{1,2}:d{1,2}.d{3}"     negate => true     what => "previous"   }    grok {       match => [ "message", "(?<logTime>d{4}-d{2}-d{2}sd{2}:d{2}:d{2}.d{3})s+[(?<thread>.*)]s+(?<level>w*)s{1,2}+(?<class>S*)s+-s+(?<content>.*)s*"]       match => [ "message", "(?<logTime>d{4}-d{2}-d{2}sd{2}:d{2}:d{2}.d{3})s{1,2}+(?<level>w*)s{1,2}+.s---+s[(?<thread>.*)]+s(?<class>S*)s*:+s(?<content>.*)s*"]       match => [            "source", "/home/passjava/logs/(?<logName>w+)/.*.log"        ]       overwrite => [ "source"]       break_on_match => false   }    mutate {     convert => {       "bytes" => "integer"     }     remove_field => ["agent","message","@version", "tags", "ecs", "_score", "input", "[log][offset]"]   }    useragent {     source => "user_agent"     target => "useragent"   }    date {     match => ["logTime", "MMM d HH:mm:ss", "MMM dd HH:mm:ss", "ISO8601"]     timezone => "Asia/Shanghai"   } }  output {   stdout { }    elasticsearch {     hosts => ["192.168.56.11:9200"]     index => "passjava_log"   } } 

关于 Logstash 如何配置的内容,请查看这篇:

深入理解 ELK 中 Logstash 的底层原理 + 填坑指南

3.5.4 重新启动 logstash 容器

docker restart logstash 

四、Docker 方式安装 Filebeat

4.1 拉取 filebeat 镜像

docker pull elastic/filebeat:7.6.2 

被一位读者赶超,手摸手 Docker 部署 ELK Stack

临时方式启动,主要是为了映射整个 filebeat 目录,后面可以修改同步进度以及查看日志文件。

docker run -d --name=filebeat elastic/filebeat:7.6.2 

将容器内的文件夹拷贝到宿主机磁盘上

docker cp filebeat:/usr/share/filebeat /data/elk 

被一位读者赶超,手摸手 Docker 部署 ELK Stack

创建日志目录作为测试

sudo mkdir -p /data/passjava/logs 

4.2 配置 filebeat

创建日志目录作为测试

sudo mkdir -p /data/passjava/logs 

创建 filebeat 配置文件

vim /data/elk/filebeat/filebeat.yml 

配置内容如下:

filebeat.inputs: - type: log   enabled: true   paths:     - /usr/share/filebeat/passjava/logs/*/info*.log     - /usr/share/filebeat/passjava/logs/*/warn*.log     - /usr/share/filebeat/passjava/logs/*/error*.log   fields:     log_catagory: service   fields_under_root: true   multiline.type: pattern   multiline.pattern: '^d{4}-d{1,2}-d{1,2}sd{1,2}:d{1,2}:d{1,2}.d{3}'   multiline.negate: true   multiline.match: after   multiline.max_lines: 52  output.logstash:   hosts: ["192.168.56.11:5044"] 

这里配置的 paths 日志文件路径用来映射宿主机上的日志文件。

paths:     - /usr/share/filebeat/logbeat/*.log 

设置权限

sudo chmod 777 -R /data/elk/filebeat sudo chmod go-w /data/elk/filebeat/filebeat.yml 

被一位读者赶超,手摸手 Docker 部署 ELK Stack

启动 filebeat

# 删除 filebeat 容器 docker rm -f filebeat # 启动 filebeat 容器 docker run -d    --name=filebeat    --restart=always  	-v /data/passjava/logs:/usr/share/filebeat/passjava/logs/  	-v /data/elk/filebeat:/usr/share/filebeat    elastic/filebeat:7.6.2 

查看启动日志

docker logs -f filebeat 

被一位读者赶超,手摸手 Docker 部署 ELK Stack

4.3 Filebeat 重新同步日志文件

当我们想要完全重新同步日志文件时,可以将 Filebeat 这个文件夹删掉:

/data/elk/filebeat/data/registry/filebeat 

这个目录下的 data.json 文件会记录同步的进度,删掉后,重启 Filebeat 后就会重新开始同步。

五、测试日志文件写入 ES

5.1 创建日志文件

sudo vim /data/passjava/logs/wukong/error.log 

模拟后端输出的日志:

被一位读者赶超,手摸手 Docker 部署 ELK Stack

5.2 观察 logstash 容器中的日志

docker logs logstash 

可以看到 logstash 收集到了 filebeat 传输的日志。

被一位读者赶超,手摸手 Docker 部署 ELK Stack

5.3 观察 Filebeat 容器中的日志

docker logs filebat 

可以看到 Filebeat 采集日志文件,并同步到 Logstash 的日志。

被一位读者赶超,手摸手 Docker 部署 ELK Stack

5.4 创建 ES 索引

当 Logstash 将日志同步到 Elasticsearch 中后,就会自动在 Elasticsearch 中创建索引。然后我们需要在 Kibana 可视化控制台中创建一个对应的索引来查看日志。步骤如下所示:

  • 打开 Kibana 控制台

被一位读者赶超,手摸手 Docker 部署 ELK Stack

  • 创建 passjava_log 索引

被一位读者赶超,手摸手 Docker 部署 ELK Stack

5.5 查询日志

在 Kibana 搜索大楼 关键字,可以查到日志输出。需要注意的是,要选择对应的过滤时间段。

被一位读者赶超,手摸手 Docker 部署 ELK Stack

六、报错问题排查

Filebeat 出现报错,但是过一会 Filebeat 和 Logstash 又成功建立了连接,而且日志也输出到了 Logstash 了。暂时未找到原因。

 Failed to publish events caused by: EOF 

被一位读者赶超,手摸手 Docker 部署 ELK Stack

发表评论

评论已关闭。

相关文章