基于Docker搭建ELK服务
前言
ELK是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana , 它们都是开源软件。
使用ELK做线上日志自动化收集,统计服务访问信息。
服务介绍
ElasticSearch
Elasticsearch是个开源分布式搜索引擎,提供搜集、分析、存储数据三大功能。它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。
Logstash
Logstash 主要是用来日志的搜集、分析、过滤日志的工具,支持大量的数据获取方式。一般工作方式为c/s架构,client端安装在需要收集日志的主机上,server端负责将收到的各节点日志进行过滤、修改等操作在一并发往elasticsearch上去。
Kibana
Kibana 也是一个开源和免费的工具,Kibana可以为 Logstash 和ElasticSearch 提供的日志分析友好的 Web 界面,可以帮助汇总、分析和搜索重要数据日志。
Docker
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
docker-compose
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
环境安装
CentOS Docker 安装
1 自动化安装
# 使用官方安装脚本自动安装
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
# 也可以使用国内 daocloud 一键安装命令
curl -sSL https://get.daocloud.io/docker | sh
2 手动安装
# 添加源
yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装 Docker Engine-Community
yum install docker-ce docker-ce-cli containerd.io
docker-compose安装
# 从微软镜像下载docker-compose安装
curl -L http://mirror.azure.cn/docker-toolbox/linux/compose/1.25.4/docker-compose-Linux-x86_64 -o /usr/local/bin/docker-compose
# 设置权限
chmod +x /usr/local/bin/docker-compose
服务配置
ElasticSearch集群配置
version: '2.0'
services:
elasticsearch:
image: elasticsearch
container_name: es7_01
environment:
- cluster.name=elk
- node.name=es7_01
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- "ELASTIC_PASSWORD=HYSI5SUURDprIz5J"
- discovery.seed_hosts=es7_01
- cluster.initial_master_nodes=es7_01
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- es7data1:/usr/share/elasticsearch/data
ports:
- 9200:9200
networks:
- es7net
elasticsearch2:
image: elasticsearch
container_name: es7_02
environment:
- cluster.name=elk
- node.name=es7_02
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- discovery.seed_hosts=es7_01,es7_02
- cluster.initial_master_nodes=es7_01,es7_02
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- es7data2:/usr/share/elasticsearch/data
networks:
- es7net
logstash:
image: logstash
container_name: logstash
volumes:
- /project/elk/logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml
- /project/elk/logstash/pipeline:/usr/share/logstash/pipeline
- /data/logs:/data/logs
ports:
- 5044:5044
environment:
LS_JAVA_OPTS: "-Xmx256m -Xms256m"
volumes:
es7data1:
driver: local
es7data2:
driver: local
networks:
es7net:
driver: bridge
kibana配置
version: '2.0'
services:
kibana:
image: kibana
container_name: kibana7
environment:
- I18N_LOCALE=zh-CN
- XPACK_GRAPH_ENABLED=true
- TIMELION_ENABLED=true
- XPACK_MONITORING_COLLECTION_ENABLED="true"
- "ELASTICSEARCH_USERNAME=elastic"
- "ELASTICSEARCH_PASSWORD=HYSI5SUURDprIz5J"
ports:
- "5601:5601"
networks:
- es7net
logstash配置
docker-compose.yml配置如下:
version: '2.0'
services:
logstash:
image: logstash
container_name: logstash
volumes:
- /project/elk/logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml
- /project/elk/logstash/pipeline:/usr/share/logstash/pipeline
- /data/logs:/data/logs
- /data/logs/access.log:/var/log/nginx/access.log
ports:
- 5044:5044
environment:
LS_JAVA_OPTS: "-Xmx256m -Xms256m"
logstash.yml配置如下:
xpack.monitoring.elasticsearch.hosts: [ "http://127.0.0.1:9200" ]
logstash.conf配置如下:
input {
file {
path => "/data/logs/info.log"
type=>"runtimelog"
codec => multiline {
charset => "UTF-8" # 设置编码
# 合并多行日志为一行,根据正则匹配出yyyy-mm-dd hh-mm-ss时间格式开头,合并不满足的行
pattern => "^\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2}"
negate => true
what => "previous"
}
start_position => "beginning"
sincedb_path => "/dev/null"
}
file {
# # 使用grok,对日志格式进行格式化,匹配出字段
path => "/var/log/nginx/access.log"
type=>"access"
start_position => "beginning"
}
}
filter {
if[type] == "runtimelog"{
grok{
match=>{
"message" => "%{TIMESTAMP_ISO8601:logtime} %{DATA:level} \[%{DATA:module}\]\[%{DATA:category}\]\[%{DATA:subcategory}\]\[%{DATA:filter1}\]\[%{DATA:filter2}\]:%{GREEDYDATA:log_json}"
}
}
# 对logtime进行匹配处理
date {
match => [ "logtime", "yyyy-MM-dd-HH:mm:ss.SSS" ]
locale => "cn"
}
}
if[type] == "access"{
grok{
match=>{
"message" => '%{DATA:remote_addr} - %{DATA:remote_user} \[%{DATA:time_local}\] \"%{DATA:request}\" %{DATA:status} %{DATA:body_bytes_sent} \"%{DATA:http_referer}\" \"%{DATA:http_user_agent}\" \"%{DATA:http_x_forwarded_for}'
}
}
}
}
output {
if[type] == "runtimelog"{
# 满足条件的数据,写入ES
elasticsearch {
hosts => "http://es:9200"
index => "intent"
}
}
if[type] == "access"{
elasticsearch {
hosts => "http://es:9200"
index => "access-%{+YYYY-MM-dd}"
}
}
}
构建运行
使用docker-compose生成容器
# 构建并后台运行服务
docker-compose up -d
# 关闭并删除服务
docker-compose down -v
# 更新镜像,启动容器
docker-compose up -d --build