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

# 目录结构

├──elk
├────es
├──────config
├────────elasticsearch.yml
├──────data
├──────plugins
1
2
3
4
5
6

# elasticsearch.yml

cluster.name: "docker-cluster"
network.host: 0.0.0.0
1
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

# 目录结构

├──elk
├────logstash
├──────logstash.yml
├──────logstash-read-write.conf
├──────pipelines.yml
├──────source
├────────sincedb                    
1
2
3
4
5
6
7

# logstash.yml

# 允许其他机器访问
http.host: "0.0.0.0"
# 
xpack.monitoring.elasticsearch.hosts: [ "elasticsearch:9200" ]
1
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

可以配置多个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

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

# 目录结构

├──elk
├────kibana
├──────config
├────────kibana.yml
1
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

# 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

# 目录结构

├──elk
├────elastalert
├──────config
├────────elastalert.yaml
├────────smtp_auth_file.yaml
├──────rules
├────────error.yaml
1
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

# error.yaml

官方文档 (opens new window)

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

# smtp_auth_file.yaml

user:xxx
password:xxx
1
2

# Filebeat

Logstash可以直接读取日志文件,并发送到Elasticsearch,但是对于分布式系统,在每台机器上部署Logstash会比较重,损耗性能。这时候可以使用FilebeatFilebeat功能单一,只是读取日志并发送到LogstashLogstash再发送到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

# 目录结构

├──elk
├────filebeat
├──────config
├────────filebeat.yml
1
2
3
4

# filebeat.yml

官方文档 (opens new window)

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

filebeat默认将一行数据看作一条日志,对于多行日志,需要配置multiline,将多行日志合并为一条日志。

multiline.pattern:匹配多行日志的正则表达式。

multiline.negate:定义匹配模式,true表示匹配不到的行合并到上一行,false表示匹配到的行合并到上一行。

multiline.match:定义匹配模式,before表示遇到符合匹配的行时,下一行为新的开始。after表示遇到符合匹配的行时,当前行为新的开始。

官方解释图表 (opens new window)

# 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
上次更新: 2024/01/09, 14:03:19
最近更新
01
go-admin-ui项目仿写练手1-登录页
06-29
02
maven依赖问题
06-17
03
JVM相关命令
02-21
更多文章>