Docker Compose部署ELK系统
# Elasticsearch
# docker compose
version: '3.2'
services:
elasticsearch:
image: elasticsearch:7.17.4
volumes:
- /etc/localtime:/etc/localtime
- ./es/plugins:/usr/share/elasticsearch/plugins #插件文件挂载
- ./es/data:/usr/share/elasticsearch/data #数据文件挂载
- ./es/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
ports:
- '9200:9200'
- '9300:9300'
container_name: elasticsearch
restart: always
environment:
- 'cluster.name=elasticsearch' #设置集群名称为elasticsearch
- 'discovery.type=single-node' #以单一节点模式启动
- 'ES_JAVA_OPTS=-Xms1024m -Xmx1024m' #设置使用jvm内存大小
networks:
- elk
networks:
elk:
name: elk
driver:
bridge
# ik 分词器的安装
# 集群 docker-compose exec elasticsearch elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.17.4/elasticsearch-analysis-ik-7.17.4.zip
# 单点 bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.17.4/elasticsearch-analysis-ik-7.17.4.zip
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 目录结构
├──elk
├────es
├──────config
├────────elasticsearch.yml
├──────data
├──────plugins
1
2
3
4
5
6
2
3
4
5
6
# elasticsearch.yml
cluster.name: "docker-cluster"
network.host: 0.0.0.0
1
2
2
# Logstash
# docker compose
logstash:
image: logstash:7.17.4
container_name: logstash
restart: always
volumes:
- /etc/localtime:/etc/localtime
- './logstash/pipelines.yml:/usr/share/logstash/config/pipelines.yml'
- './logstash/logstash-read-write.conf:/usr/share/logstash/pipeline/logstash-read-write.conf'
# 记录读取日志的位置
- './logstash/source:/app/source'
# 记录日志的位置
- '/d/app/log:/app/target/log'
ports:
- '5044:5044'
- '50000:50000/tcp'
- '50000:50000/udp'
- '9600:9600'
environment:
LS_JAVA_OPTS: -Xms1024m -Xmx1024m
TZ: Asia/Shanghai
MONITORING_ENABLED: false
links:
- elasticsearch:es #可以用es这个域名访问elasticsearch服务
networks:
- elk
depends_on:
- elasticsearch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 目录结构
├──elk
├────logstash
├──────logstash.yml
├──────logstash-read-write.conf
├──────pipelines.yml
├──────source
├────────sincedb
1
2
3
4
5
6
7
2
3
4
5
6
7
# logstash.yml
# 允许其他机器访问
http.host: "0.0.0.0"
#
xpack.monitoring.elasticsearch.hosts: [ "elasticsearch:9200" ]
1
2
3
4
2
3
4
# pipelines.yml
- pipeline.id: read-write
path.config: /usr/share/logstash/pipeline/logstash-read-write.conf
pipeline.workers: 3
1
2
3
2
3
可以配置多个pipeline,每个pipeline都有一个唯一的id,并指定配置文件的路径。
# logstash-read-write.conf
input {
file {
# 读取日志的路径
path => "/app/target/log/read-write/info.log"
# 首次读取时的起始位置。如果设置为 beginning,会从文件的开始位置读取。如果设置为 end,会从文件的结束位置开始读取,只有新添加到文件的数据才会被读取。
start_position => "beginning"
# 记录 Logstash 上次读取每个文件的位置,这样 Logstash 在重启后可以从上次读取的位置继续读取。
sincedb_path => "/app/source/sincedb"
}
}
output {
elasticsearch {
hosts => [ "es:9200"]
#es中创建索引的名称(注意 index里面不能存在大写字符)
index => "read-write-%{+YYYY.MM.dd}"
}
if "ERROR" in [message] {
http {
url => "http://localhost:8081/sendNotice"
http_method => "post"
format => "form"
content_type => "application/x-www-form-urlencoded"
mapping => ["content", "%{message}","phone","17826873177","title","异常报警"]
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
output
可以指定多个输出,根据if
条件判断输出到不同的地方。
# Kibana
# docker compose
kibana:
image: kibana:7.17.4
container_name: kibana
restart: always
volumes:
- /etc/localtime:/etc/localtime
- ./kibana/config/kibana.yml:/usr/share/kibana/config/kibana.yml
ports:
- '5601:5601'
links:
- elasticsearch:es #可以用es这个域名访问elasticsearch服务
environment:
- ELASTICSEARCH_URL=http://elasticsearch:9200 #设置访问elasticsearch的地址
- 'elasticsearch.hosts=http://es:9200' #设置访问elasticsearch的地址
- I18N_LOCALE=zh-CN
networks:
- elk
depends_on:
- elasticsearch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 目录结构
├──elk
├────kibana
├──────config
├────────kibana.yml
1
2
3
4
2
3
4
# kibana.yml
server.host: "0.0.0.0"
server.shutdownTimeout: "5s"
elasticsearch.hosts: [ "http://es:9200" ]
monitoring.ui.container.elasticsearch.enabled: true
1
2
3
4
2
3
4
# ElastAlert
# docker compose
elastalert:
image: bitsensor/elastalert:3.0.0-beta.0
container_name: elastalert
links:
- elasticsearch:es
volumes:
- ./elastalert/config/elastalert.yaml:/opt/elastalert/config.yaml
- ./elastalert/config/elastalert-test.yaml:/opt/elastalert/config-test.yaml
- ./elastalert/rules:/opt/elastalert/rules
- ./elastalert/templates:/opt/elastalert/templates
- ./elastalert/config/smtp_auth_file.yaml:/home/elastalert/config/smtp_auth_file.yaml
networks:
- elk
depends_on:
- elasticsearch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 目录结构
├──elk
├────elastalert
├──────config
├────────elastalert.yaml
├────────smtp_auth_file.yaml
├──────rules
├────────error.yaml
1
2
3
4
5
6
7
2
3
4
5
6
7
# elastalert.yaml
rules_folder: /opt/elastalert/rules #指定告警规则文件目录
run_every:
seconds: 10 #查询Elasticsearch的时间间隔
buffer_time:
minutes: 3
es_host: es #elasticsearch IP
es_port: 9200 #elasticsearch端口
writeback_index: elastalert_status
writeback_alias: elastalert_alerts
#失败重试次数
alert_time_limit:
days: 2
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# error.yaml
name: error-alert rule #规则名称, 若重复只会运行最新的一条
type: frequency #规则类型 frequency表示频率
index: read-write-* #要监控的索引 app*表示匹配所有以app开头的索引
num_events: 3 #触发事件数
timeframe:
minutes: 2 #触发时间间隔
compare_key: message #要监控的字段
filter:
- query:
query_string:
query: "message:*ERROR*" #过滤条件
smtp_host: smtp.163.com #邮箱host 这里用的的是163邮箱,不同邮箱配置有差异
smtp_port: 25
#指定邮箱的认证文件 这里主要是邮箱名和授权码 授权码需要登录邮箱去设置
smtp_auth_file: /home/elastalert/config/smtp_auth_file.yaml
from_addr: [email protected] #配置发出告警信息的邮箱 一般为公司或部门邮箱
# 配置告警方式 可以指定多种方式
alert:
- "email"
- "post"
http_post_url: "http://localhost:8081/sendNotice"
http_post_headers:
Content-Type: "application/json"
http_post_static_payload:
phone: "13511111111"
title: "监控告警"
content: "您有一条告警信息:"
email:
- "[email protected]" #配置接收告警信息的邮箱 可以指定多个
alert_text_type: alert_text_only #配置告警信息类型,一般为alert_text_only若不指定会把所有字段都返回
alert_subject: "监控告警" #配置告警标题
#配置告警内容
alert_text: "您有一条告警信息: \n时间:{0}\n级别:高\n关键字:ERROR \n轮询时间:2分钟 \n限制次数:{3}次\n出现次数: {2}次 \n主要信息如下:\n\n{1} \n "
#指定输出字段
alert_text_args:
- "@timestamp"
- message
- num_hits
- num_events
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# smtp_auth_file.yaml
user:xxx
password:xxx
1
2
2
# Filebeat
Logstash
可以直接读取日志文件,并发送到Elasticsearch
,但是对于分布式系统,在每台机器上部署Logstash
会比较重,损耗性能。这时候可以使用Filebeat
,Filebeat
功能单一,只是读取日志并发送到Logstash
,Logstash
再发送到Elasticsearch
。
# docker compose
filebeat:
image: docker.elastic.co/beats/filebeat:7.17.1
container_name: filebeat
restart: always
volumes:
- /etc/localtime:/etc/localtime
- ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml
- /app/logs:/logs'
user: root
# 默认为true,filebeat会检查配置文件的权限,如果除了启动用户外,其他用户或用户组也有读写权限,会拒绝启动。在Windows系统上运行demo时修改权限比较麻烦可以设置为false,关闭权限检查
command: ["filebeat", "-e", "-strict.perms=false"]
networks:
- elk
depends_on:
- logstash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 目录结构
├──elk
├────filebeat
├──────config
├────────filebeat.yml
1
2
3
4
2
3
4
# filebeat.yml
filebeat.inputs:
- type: log
enabled: false
paths:
- /logs/*/error.log
- /logs/*/sys-error.log
multiline.pattern: '^\d{4}-\d{2}-\d{2}'
multiline.negate: true
multiline.match: after
fields:
type: error
- type : log
enabled: true
paths:
- /logs/read-write/info.log
multiline.pattern: '^\d{4}-\d{2}-\d{2}'
multiline.negate: true
multiline.match: after
fields:
type: info
output.logstash:
hosts: ["logstash:5044"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
filebeat
默认将一行数据看作一条日志,对于多行日志,需要配置multiline
,将多行日志合并为一条日志。
multiline.pattern
:匹配多行日志的正则表达式。
multiline.negate
:定义匹配模式,true
表示匹配不到的行合并到上一行,false
表示匹配到的行合并到上一行。
multiline.match
:定义匹配模式,before
表示遇到符合匹配的行时,下一行为新的开始。after
表示遇到符合匹配的行时,当前行为新的开始。
# logstash配置
新建配置文件,可以命名为logstash-filebeat.conf
,用于定义接收filebeat
发送的日志。并在pipelines.yml
中引入配置。
input {
beats{
type => "beats"
port => 5044
}
}
filter {
grok {
#用于解析 message 字段的内容,将 message 字段解析为三个部分:timestamp,loglevel 和 message。
#match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:loglevel} %{GREEDYDATA:message}" }
match => { "message" => "\[%{DATA:timestamp}\] \[%{DATA:thread}\] %{LOGLEVEL:loglevel} %{DATA:class} : %{GREEDYDATA:content}" }
}
#用于解析日期和时间。在这个例子中,它将 timestamp 字段的值解析为 Logstash 的 @timestamp 字段。这个字段是 Logstash 事件的标准字段,通常用于存储事件的时间戳。
date {
match => [ "timestamp" , "yyyy-MM-dd HH:mm:ss.SSS" ]
target => "@timestamp"
}
#用于对事件进行各种转换。在这个例子中,它将 timestamp 字段从事件中移除,因为这个字段的值已经被复制到 @timestamp 字段。
mutate {
remove_field => [ "timestamp", "message" ]
}
}
output {
if [fields][type] == "error"{
elasticsearch {
hosts => ["es:9200"]
index => "read-write-%{+YYYY.MM.dd}"
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
编辑 (opens new window)
上次更新: 2024/01/09, 14:03:19