ELK-docker 实践

# ELK docker 部署实践

本文主要对 ELK 套件中的 filebeat, logstash, elasticsearch 的安装进行实践,以及简单运行。

# Elasticsearch 安装

这里参照官网给出的docker-compose.yml文件设置elasticsearch集群。elastisearch支持single-nodemulti node cluster两种部署模式。在本文中,实际上两种方式都能达到效果。使用single-node启动的环境,查看集群状态时会出现status:yellow。将docker-compose.yml文件放置在一个单独的目录下,然后创建data01, data02, data03目录。依据实际需要,还可创建plugins目录映射。

 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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
version: '2'
services:
  es01:
    container_name: es01
    image: docker.elastic.co/elasticsearch/elasticsearch:7.15.0
    ports:
      - 9200:9200
      - 9300:9300
    volumes:
      - ./data01:/usr/share/elasticsearch/data
    environment:
      - node.name=es01
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es02
      - cluster.initial_master_nodes=es01,es02
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms128m -Xmx128m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    networks:
      - elastic

  es02:
    container_name: es02
    image: docker.elastic.co/elasticsearch/elasticsearch:7.15.0
    environment:
      - node.name=es02
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01
      - cluster.initial_master_nodes=es01,es02
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms128m -Xmx128m"
    volumes:
      - ./data02:/usr/share/elasticsearch/data
    ulimits:
      memlock:
        soft: -1
        hard: -1
    networks:
      - elastic

  es03:
    container_name: es03
    image: docker.elastic.co/elasticsearch/elasticsearch:7.15.0
    environment:
      - node.name=es03
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es02
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms128m -Xmx128m"
    volumes:
      - data03:/usr/share/elasticsearch/data
    ulimits:
      memlock:
        soft: -1
        hard: -1
    networks:
      - elastic

volumes:
  data01:
    driver: local
  data02:
    driver: local
  data03:
    driver: local

networks:
  elastic:
    driver: bridge
    external: true

注意这里将集群的网络设置为external,这样后续的logstash才能找到服务节点。此外,由于笔者的机器可用存储较小,因此设置es的存储占用设置为128m。实际使用时,可以按照需求进行调整。 运行docker-compose up -d即可后台启动。启动后,curl -X GET "localhost:9200/_cat/nodes?v=true&pretty" 判断集群状态。

# Logstash 安装

collect, parse transform logs

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
version: '2'
services:
  logstash:
    image: docker.elastic.co/logstash/logstash:7.15.0
    container_name: logstash
    user: root
    ports:
      - 5004:5004
    volumes:
      - ./config:/usr/share/logstash/config/
      - /etc/localtime:/etc/localtime
    command: bash -c "cd /usr/share/logstash && logstash -f config/online.conf"
    networks:
      - elastic

networks:
  elastic:
    driver: bridge
    external: true
 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
# ./config/online.conf
input {
  # 这里支持多种 input
  beats {
    port => 5004
    codec => "json"
  }
}

filter {
  # 这里基于 ruby 脚本进行过滤
  ruby {
    path => "./config/filter.rb"
  }
}

output {
  # 这里将过滤后的结果输出到标准输出及 es 中
  stdout {
    codec => json
  }
  elasticsearch {
    hosts => ["es01:9200"]
    index => "logstash"
    #user => ""
    #password => ""
  }
}
 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
# config/filter.rb
# 按照 online.conf 中的配置,logstash 启动后,会读取 filter.rb,并使用 filter 函数作为过滤函数。
require "json"

BEGIN{
  puts "start event filter"
}

END{
  puts "end event filter"
}

def filter(event)
  puts event
  if event.get("[errno]") != 0
    return []
  end
  valid_age = 0
  event.get("[data]").each{ | info |
    if info["age"] < 10
      valid_age += info["age"]
    end
  }
  event.set("[data]", valid_age)
  return [event]
end

logstash 启动后,会监听容器内的 5004 接口(配置于online.conf中),如果有信息传入,则会经过filter.rb中的 filter() 函数对数据进行处理。而后输出到标准输出及 es01容器5004端口的elasticsearch服务。由于elasticsearchlogstash容器使用了相同的网络,因此可以互相感知。

# filebeat 安装

filebeat 作为轻量级的日志收集器,仅占用很少的资源,即可完成日志的采集,并且转发至配置的logstash进行后续的处理、归档等操作。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
version: '2'
services:
  filebeat:
    image: docker.elastic.co/beats/filebeat:7.16.0
    container_name: filebeat
    user: root
    environment:
      - strict.perms=false
    volumes:
      - ./filebeat.yml:/usr/share/filebeat/filebeat.yml
      - ./data:/usr/share/filebat/data
    networks:
      - elastic
    command: bash -c "cd /usr/share/filebeat && filebeat -e -c ./filebeat.yml"

networks:
  elastic:
    driver: bridge
    external: true
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# filebeat.yml
filebeat.inputs:
  - type: log
    enabled: true
    paths:
      - /usr/share/filebeat/input.log

filebeat.config:
  modules:
    path: ${path.config}/modules.d/*.yml
    reload.enabled: false

filbeat.autodiscover:
  providers:
    - type: docker
      hints.enabled: true

output.logstash:
  hosts: "logstash:5004"

容器启动后,会监听/usr/share/filebeat/input.log文件。当该文件发生变更时,filebeat会读取增量的内容并进行转发。

# let it run

经过上述步骤,一个简单的日志监听、采集、处理、存档的流程就构建了。为了测试,可以在filebeat容器的/usr/share/filebeat/input.log中写入:

1
{"errno": 0,"data": [{"age": 9,"name": "tt"},{"age": 8,"name": "gg"}]}

按照logstash:online.conf的逻辑,会向elasticsearchlogstash写入信息。

# 参考文献

  1. Linux-ELK日志收集
  2. Install Elasticsearch with Docker
  3. Logstash介绍
Licensed under CC BY-NC-SA 4.0
Hello, World!
使用 Hugo 构建
主题 StackJimmy 设计