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.1
kibana:7.1.1
elasticsearch:7.1.1
store/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:
- elasticsearch
filebeat部分
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: trial
logstash部分
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
depends_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: 4
logstash.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 协议 ,转载请注明出处!