Docker ELKF平台搭建 单机
申明
本文是基于 hub.docker.com 站点提供的 Docker 容器进行搭建的,且是 单机 ,仅用于学习。
简介
ELKF 是 Elasticsearch 、 Logstash 、 Kibana 、 Filebeat。
filebeat 是轻量级的开源日志文件数据搜集器,负责对服务的日志进行收集。
logstash 是数据收集引擎,可以对数据进行过滤、分析、丰富、统一格式等操作,存储到用户指定的位置,包含但不限于文件、 elasticsearch 。
elasticsearch 是存储、搜索和分析引擎,特点是高可伸缩、高可靠和易管理等。
kibana 是数据分析和可视化平台,通常依赖 elasticsearch 。

图片来源于网络
说明
为了能够达到更好的学习效果,这里将 elasticsearch 设置成了无需密码的状态。
同时,elasticsearch 也用的是免费版。
仓库
镜像版本
Docker 镜像版本: 7.1.1。
logstash:7.1.1kibana:7.1.1elasticsearch:7.1.1store/elastic/filebeat:7.1.1
配置文件目录
elkf
├─elasticsearch
│ └─elasticsearch.yml
├─filebeat
│ └─filebeat.yml
├─kibana
│ └─kibana.yml
└─logstash
├─logstash.yml
└─pipeline
└─logstash.conf编写 docker-compose.yml
version: "3"
services:
filebeat:
image: store/elastic/filebeat:7.1.1
volumes:
- ./logs:/var/log
- ./elkf/filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
user: "root"
elasticsearch:
image: elasticsearch:7.1.1
ports:
- "9200:9200"
- "9300:9300"
volumes:
- ./elkf/elasticsearch/data:/usr/share/elasticsearch/data
- ./elkf/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:ro
environment:
ELASTICSEARCH_USERNAME: "root"
ELASTICSEARCH_PASSWORD: "123456"
ES_JAVA_OPTS: "-Xmx256m -Xms256m"
discovery.type: single-node
xpack.security.enabled: 'false'
logstash:
image: logstash:7.1.1
ports:
- "5044:5044"
volumes:
- ./elkf/logstash/pipeline:/usr/share/logstash/pipeline:ro
- ./elkf/logstash/logstash.yml:/usr/share/logstash/config/logstash.yml:ro
environment:
LS_JAVA_OPTS: "-Xmx256m -Xms256m"
depends_on:
- elasticsearch
kibana:
image: kibana:7.1.1
ports:
- "5601:5601"
volumes:
- ./elkf/kibana/kibana.yml:/usr/share/kibana/config/kibana.yml:ro
environment:
I18N_LOCALE: zh-CN
depends_on:
- elasticsearchfilebeat部分
filebeat:
image: store/elastic/filebeat:7.1.1
volumes:
- ./logs:/var/log
- ./elkf/filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
user: "root"./logs:/var/log 是将本地的 log 映射到容器中。我这里是将日志存储在容器外的
./elkf/filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro 是将容器外的配置映射到容器内。
filebeat.yml 文件:
filebeat.config:
modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: false
filebeat.inputs:
- type: log
enabled: true
fields:
log_source: nginx_access_log
paths:
- /var/log/nginx/access.log
- type: log
enabled: true
fields:
log_source: nginx_error_log
paths:
- /var/log/nginx/error.log
output.logstash:
hosts: ['logstash:5044']elasticsearch部分
elasticsearch:
image: elasticsearch:7.1.1
ports:
- "9200:9200"
- "9300:9300"
volumes:
- ./elkf/elasticsearch/data:/usr/share/elasticsearch/data
- ./elkf/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:ro
environment:
ELASTICSEARCH_USERNAME: "root"
ELASTICSEARCH_PASSWORD: "123456"
ES_JAVA_OPTS: "-Xmx256m -Xms256m"
discovery.type: single-node
xpack.security.enabled: 'false'ports 用于端口映射。
./elkf/elasticsearch/data:/usr/share/elasticsearch/data 将 elasticsearch 的数据存储到容器外,防止容器重新创建,造成数据丢失。
environment 设置一些容器所需要的一些环境变量。
xpack.security.enabled: 'false' 这个是设置使用 elasticsearch 的 基本许可证。因为默认的有使用时间限制。
elasticsearch.yml 文件:
## Default Elasticsearch configuration from Elasticsearch base image.
## https://github.com/elastic/elasticsearch/blob/master/distribution/docker/src/docker/config/elasticsearch.yml
#
cluster.name: "docker-cluster"
network.host: 0.0.0.0
## X-Pack settings
## see https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-xpack.html
#
# xpack.license.self_generated.type: triallogstash部分
logstash:
image: logstash:7.1.1
ports:
- "5044:5044"
volumes:
- ./elkf/logstash/pipeline:/usr/share/logstash/pipeline:ro
- ./elkf/logstash/logstash.yml:/usr/share/logstash/config/logstash.yml:ro
environment:
LS_JAVA_OPTS: "-Xmx256m -Xms256m"
depends_on:
- elasticsearchdepends_on 是因为 logstash 将解析之后的数据存储到 elasticsearch 中,所以 logstash 依赖 elasticsearch 。
logstash.yml 文件:
## Default Logstash configuration from Logstash base image.
## https://github.com/elastic/logstash/blob/master/docker/data/logstash/config/logstash-full.yml
#
http.host: "0.0.0.0"
xpack.monitoring.elasticsearch.hosts: [ "http://elasticsearch:9200" ]
## X-Pack security credentials
#
xpack.monitoring.enabled: true
path.logs: /var/log/logstash
pipeline.workers: 4logstash.conf 文件:
input {
beats {
port => 5044
}
}
## Add your filters / logstash plugins configuration here
filter {
if [fields][log_source] == "nginx_access_log" {
grok {
match => {
"message" => '%{IPV4:remote_addr} - %{USERNAME:remote_user} \[%{HTTPDATE:timestamp}\] \"%{WORD:request_method} %{URIPATHPARAM:request_uri} HTTP/%{BASE10NUM:http_version}\" %{IPORHOST:http_host} %{INT:status} %{INT:request_length} %{INT:body_bytes_sent} %{QS:http_referer} %{QS:http_user_agent} %{BASE10NUM:request_time} (?<upstream_response_time>([0-9]+.[0-9]+)|-)'
}
remove_field => "message"
}
mutate {
convert => ["upstream_response_time", "float"]
convert => ["request_time", "float"]
convert => ["http_version", "float"]
convert => ["status", "integer"]
}
}
if [fields][log_source] == "nginx_error_log" {
grok {
match => [
"message", '%{TIMESTAMP_ISO8601:timestamp} \[%{DATA:log_level}\] %{NUMBER:pid:int}#%{NUMBER}: %{DATA:error_message}, client: %{IP:client_ip}, server: %{HOSTNAME:request_server}, request: \"%{WORD:request_method} %{URIPATHPARAM:request_uri} HTTP/%{BASE10NUM:http_version}\", upstream: \"%{URI:upstream}\", host: \"%{HOSTNAME:request_host}\", referrer: \"%{URI:request_referrer}\"',
"message", '(?<timestamp>%{YEAR}/%{MONTHNUM}/%{MONTHDAY}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})?%{ISO8601_TIMEZONE}?) \[%{DATA:log_level}\] %{NUMBER:pid:int}#%{NUMBER}: %{DATA:error_message}, client: %{IP:client_ip}, server: %{HOSTNAME:request_server}, request: \"%{WORD:request_method} %{URIPATHPARAM:request_uri} HTTP/%{BASE10NUM:http_version}\", upstream: \"%{URI:upstream}\", host: \"%{HOSTNAME:request_host}\", referrer: \"%{URI:request_referrer}\"',
"message", "%{TIMESTAMP_ISO8601:timestamp} \[%{LOGLEVEL:log_level}\]\s{1,}%{GREEDYDATA:error_message}"
]
remove_field => "message"
}
}
}
output {
elasticsearch {
index => "%{[fields][log_source]}-%{+YYYY.MM.dd}"
hosts => "elasticsearch:9200"
}
}kibana部分
kibana:
image: kibana:7.1.1
ports:
- "5601:5601"
volumes:
- ./elkf/kibana/kibana.yml:/usr/share/kibana/config/kibana.yml:ro
environment:
I18N_LOCALE: zh-CN
depends_on:
- elasticsearch同样, kafka 依赖 elasticsearch 。
kabana.yml 文件:
## Default Kibana configuration from Kibana base image.
## https://github.com/elastic/kibana/blob/master/src/dev/build/tasks/os_packages/docker_generator/templates/kibana_yml.template.js
#
server.name: kibana
server.host: 0.0.0.0
elasticsearch.hosts: [ "http://elasticsearch:9200" ]可能需要扩展的部分
logstash将行日志转换成json
通过 grok 来解析
grok正则的编写验证
官方有一部分预定义 grok 的表达式,可以参考,我们也可以编写一些预定义的表达式供后续使用。
Grok Debugger 可以帮助我们验证调试解日志的正则。(可能需要自备梯子)

Kibana 也提供了相应的工具,只不过没那么好用罢了。
filebeat多行解析
直接上 Demo :
filebeat.config:
modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: false
filebeat.inputs:
- type: log
enabled: true
fields:
log_source: lumen_log
paths:
- /var/log/lumen/lumen.log
multiline.pattern: '^\[[0-9]{4}-[0-9]{2}-[0-9]{2}'
multiline.negate: true
multiline.match: after
output.logstash:
hosts: ['logstash:5044']这个的意思是根据 multiline.pattern 匹配到的为日志的开头, multiline.match 追加的位置, multiline.negate 是是否为否定模式。
| multiline.negate | multiline.match | 描述 |
|---|---|---|
| true | after | 不符合 multiline.pattern 的,追加 上一个匹配 的一行后面 |
| false | after | 符合 multiline.pattern 的,追加到 上一个不匹配的一行后面 |
| true | before | 不符合 multiline.pattern 的,追加 下一个匹配 的一行前面 |
| false | before | 符合 multiline.pattern 的,追加到 上一个不匹配的一行前面 |
为了方便理解,我们使用的是 true、 after 模式,大致意思是, multiline.pattern 匹配的一行开始,只要不匹配的,都追加到匹配的那一行,直至找到下一个匹配的一行结束。
filebeat不读取某些行
有时候,我们日志中会有一些框架层面的日志,这个我们是不需要看到的,可以通过某些关键字来排除(有利有弊)
Demo 如下:
filebeat.config:
modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: false
filebeat.inputs:
- type: log
enabled: true
fields:
log_source: lumen_log
paths:
- /var/log/lumen/lumen.log
exclude_lines: ["不需要的关键字1", "不需要的关键字2"]
multiline.pattern: '^\[[0-9]{4}-[0-9]{2}-[0-9]{2}'
multiline.negate: true
multiline.match: after
output.logstash:
hosts: ['logstash:5044']使用
创建索引
1、设置 -> 索引模式 -> 创建索引模式。

2、检索索引

3、配置、创建

4、创建成功,尽情使用吧

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!