本文将详细介绍如何在Centos7系统下使用docker-compose部署ELK(Elasticsearch、Logstash、Kibana)的过程。其实部署很简单,重要的是要学会怎么使用,用在哪里,学习是一种过程,如果你看到这篇文章,请耐心的跟着我操作步骤一起做下去,这样你就能大概的入门到了ELK,当然我也是刚学习ELK,有什么不对的请多多指教~
本篇文章从实际使用角度出发,先部署,后应用,再收集,再分析(这一块后面我做出来了再完善进去)
先对ELK 三剑客进行一个用途简介:
ELK三剑客是指Elasticsearch、Logstash和Kibana。它们是一组广泛使用的开源工具,主要用于处理和分析大规模日志数据。
Elasticsearch:Elasticsearch是一个分布式、可扩展、实时的搜索和分析引擎。它基于Apache Lucene构建,提供了强大的全文搜索功能和分布式数据存储能力。Elasticsearch能够快速地索引和搜索大量的结构化和非结构化数据,支持实时数据分析、复杂查询和聚合操作。
Logstash:Logstash是一个用于收集、处理和转发日志数据的工具。它能够从各种来源(如日志文件、数据库、消息队列等)收集数据,并对数据进行过滤、转换和增强,然后将其发送到目标位置(如Elasticsearch、文件、数据库等)。Logstash具有灵活的插件系统,可以支持各种数据源和目标。
Kibana:Kibana是一个用于数据可视化和分析的Web界面。它能够与Elasticsearch进行无缝集成,提供了丰富的图表、仪表盘和搜索功能,帮助用户更直观地理解和分析存储在Elasticsearch中的数据。Kibana可以创建实时监控、日志分析、业务指标等各种可视化展示,帮助用户从数据中发现有价值的信息。
环境准备 :
一台Centos7系统安装了Docker和Docker Compose
容器:2个Elk node节点,1个Logstash,1个Kibana
操作步骤 :
由于是测试环境,所以我将node1和node2节点都容器化放到一台服务器上,节省资源,那么可能有兄台会问为什么要搞多节点?因为我开始单节点部署后,发现elk会报副本分片异常,node状态一直是yellow状态。做了多节点就有副本分片了,状态也就正常了。
一.安装docker及docker-compose
curl -fsSL https://get.docker.com/ | sh
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose -v
二.创建配置文件目录及编写相关配置文件
第一步,我们先要用临时配置的Docker Compose Yml文件启动ELK集群,从临时启动的容器里面拷贝各类原始配置文件到本地目录,用与目录挂载,方便后续的修改及调试工作,因为如果你在容器里面直接改,在进行docker-compose重启的时候配置就会清空,比较麻烦;另外这里我还使用了一个网络路径挂载到本地,作为数据目录,这样就不用担心空间不足的问题。
1.创建目录,并编写Docker Compose Yml文件(临时性的单一节点集群,用于配置拷贝,后续会修改),这里下载的镜像可以在后续正式环境使用,也相当于提前做了一些正式工作。
mkdir /opt/docker_elk
touch /opt/docker_elk/docker-compose.yml.baktmp
vi docker-compose.yml
将以下配置文件复制粘贴后写入:
version: '3.7'
services:
elasticsearch:
image: elasticsearch:7.6.2
container_name: elasticsearch
privileged: true
user: root
environment:
#设置集群名称为elasticsearch
- cluster.name=elasticsearch
#以单一节点模式启动
- discovery.type=single-node
#设置使用jvm内存大小
- ES_JAVA_OPTS=-Xms512m -Xmx512m
ports:
- 9200:9200
- 9300:9300
logstash:
image: logstash:7.6.2
container_name: logstash
ports:
- 4560:4560
- 5044:5044
privileged: true
environment:
- TZ=Asia/Shanghai
depends_on:
- elasticsearch
links:
#可以用es这个域名访问elasticsearch服务
- elasticsearch:es
kibana:
image: kibana:7.6.2
container_name: kibana
ports:
- 5601:5601
privileged: true
links:
#可以用es这个域名访问elasticsearch服务
- elasticsearch:es
depends_on:
- elasticsearch
environment:
#设置访问elasticsearch的地址
- elasticsearch.hosts=http://es:9200
2.启动临时ELK集群
systemctl start docker
docker-compose -f /opt/docker_elk/docker-compose.yml.baktmp up -d
docker ps
3.创建配置命令,拷贝容器内的原始配置文件
这里是创建目录
mkdir -p /opt/docker_elk/logstash/
mkdir -p /opt/docker_elk/elasticsearch/plugins
mkdir -p /opt/docker_elk/elasticsearch/config
mkdir -p /opt/docker_elk/elasticsearch/config2
mkdir -p /opt/docker_elk/kibana/config
然后,我们根据之前docker ps看到的容器ID(CONTAINER ID )确认每个服务对应的容器,从容器中拷贝配置文件,这个容器id大家都不会是一样的,所以请参考我的命令格式修改。只修改容器id部分就行,这里我只拷贝了Elasticsearch和Kibana,Logstash我准备自己写。后3条命令是移动原始配置文件及为node2节点做配置文件,图片忘截了,参考命令即可。
docker cp 127683b0fe71:/opt/kibana/config/kibana.yml /opt/docker_elk/kibana/config/
docker cp 8aeccaca462b:/usr/share/elasticsearch/config/ /opt/docker_elk/elasticsearch/config/
mv /opt/docker_elk/elasticsearch/config/config/* /opt/docker_elk/elasticsearch/config/
rm -rf /opt/docker_elk/elasticsearch/config/config/
cp /opt/docker_elk/elasticsearch/config/* /opt/docker_elk/elasticsearch/config2/
4.停止临时ELK集群,创建并挂载NFS数据目录,用于后续正式环境的ELK日志存储。大家可以根据自身需求来做,我是觉得我们本地存储资源不够,我们也不是共享存储的结构,所以我只能选择挂载网盘目录。
cd /opt/docker_elk/
docker-compose -f docker-compose.yml.baktmp down
docker ps -a
确认临时集群关闭并清理完了
安装nfs软件包,挂载网络路径到本地,网络路径的IP我稍微脱敏了一下,有需要的参考命令格式自行调整。
sudo yum -y install nfs-utils
mkdir /data
mount -t nfs 10.11.1.1:/volume2/IT-NFS/ /data
df -h
将这串命令 10.11.1.1:/volume2/IT-NFS/ /data nfs defaults 0 0
写入到/etc/fstab中,用于系统重启后自动挂载
vi /etc/fstab
cat /etc/fstab
创建数据目录,这里一定要注意,目录的权限问题,要可读可写,不然会导致ELK集群无法启动
mkdir -p /data/elk/Elasticsearch
mkdir -p /data/elk/Elasticsearch2
mkdir -p /data/elk/Logstash
mkdir -p /data/elk/Kibana
5.编写各类正式的配置文件,这里我一个一个写出来和说明,每一步都必须要做,才能正常启动ELK集群。
创建并编写正式的docker-compose.yml文件(/opt/docker_elk/内)
cd /opt/docker_elk/
touch /opt/docker_elk/docker-compose.yml
vi docker-compose.yml
将以下代码写入
version: '3.7'
services:
node-1:
image: elasticsearch:7.6.2
container_name: node-1
hostname: node-1
privileged: true
user: root
environment:
# 设置集群名称为elasticsearch
- cluster.name=elasticsearch
# 以单一节点模式启动
#- discovery.type=single-node
# 设置使用jvm内存大小
- ES_JAVA_OPTS=-Xms512m -Xmx512m
volumes:
# 挂载插件目录
- /opt/docker_elk/elasticsearch/plugins:/usr/share/elasticsearch/plugins
# 挂载数据目录
- /data/Elasticsearch:/usr/share/elasticsearch/data
# 挂载配置文件目录
- /opt/docker_elk/elasticsearch/config/:/usr/share/elasticsearch/config/
ports:
# 映射9200端口,用于访问Elasticsearch HTTP API
- 9200:9200
# 映射9300端口,用于Elasticsearch节点间通信
- 9300:9300
node-2:
image: elasticsearch:7.6.2
container_name: node-2
hostname: node-2
privileged: true
user: root
environment:
# 设置集群名称为elasticsearch
- cluster.name=elasticsearch
# 设置使用jvm内存大小
- ES_JAVA_OPTS=-Xms512m -Xmx512m
volumes:
# 挂载插件目录
- /opt/docker_elk/elasticsearch/plugins:/usr/share/elasticsearch/plugins
# 挂载数据目录
- /data/Elasticsearch2:/usr/share/elasticsearch/data
# 挂载配置文件目录
- /opt/docker_elk/elasticsearch/config2/:/usr/share/elasticsearch/config/
ports:
# 映射9201端口,用于访问Elasticsearch HTTP API
- 9201:9200
# 映射9301端口,用于Elasticsearch节点间通信
- 9301:9300
logstash:
image: logstash:7.6.2
container_name: logstash
ports:
# 映射4560端口,用于接收日志数据
- 4560:4560
# 映射5044端口,用于输出到Elasticsearch
- 5044:5044
privileged: true
environment:
# 设置时区为亚洲上海
- TZ=Asia/Shanghai
volumes:
# 挂载Logstash配置文件
- /opt/docker_elk/logstash/logstash.conf:/usr/share/logstash/pipeline/logstash.conf
# 挂载Logstash数据目录
- /data/Logstash:/usr/share/logstash/data
depends_on:
- node-1
- node-2
links:
# 可以使用es这个域名访问Elasticsearch服务
- node-1:9200
- node-2:9200
kibana:
image: kibana:7.6.2
container_name: kibana
volumes:
# 挂载Kibana配置文件
- /opt/docker_elk/kibana/config/kibana.yml:/opt/kibana/config/kibana.yml
# 挂载Kibana数据目录
- /data/Kibana:/usr/share/kibana/data
ports:
# 映射5601端口,用于访问Kibana界面
- 5601:5601
privileged: true
links:
# 可以使用es这个域名访问Elasticsearch服务
- node-1:9200
- node-2:9200
depends_on:
- node-1
- node-2
environment:
# 设置访问Elasticsearch的地址为http://elasticsearch:9200
- elasticsearch.hosts=http://elasticsearch:9200
编写正式的elasticsearch.yml文件
因为是多节点,所以我这边是写了2个配置文件,前面也创建了2个配置文件的目录
node1(/opt/docker_elk/elasticsearch/config/内)
cd /opt/docker_elk/elasticsearch
vi config/elasticsearch.yml
将以下代码写入
cluster.name: "elasticsearch" # 设置集群名称为docker-cluster
node.name: node-1 # 设置节点名称为node-1
network.host: 0.0.0.0 # 监听所有网络接口
network.bind_host: 0.0.0.0 # 绑定到所有网络接口
cluster.initial_master_nodes: ["node-1","node-2"] # 初始主节点列表,包括node-1和node-2
discovery.seed_hosts: ["node-1:9300","node-2:9300"] # 发现种子主机列表,包括node-1和node-2的9300端口
node2(/opt/docker_elk/elasticsearch/config2/内)
cd /opt/docker_elk/elasticsearch
vi config2/elasticsearch.yml
将以下代码写入
cluster.name: "elasticsearch"
node.name: node-2
network.host: 0.0.0.0
network.bind_host: 0.0.0.0
cluster.initial_master_nodes: ["node-1","node-2"]
discovery.seed_hosts: ["node-1:9300","node-2:9300"]
创建并编写正式的logstash.conf文件(/opt/docker_elk/logstash/内)
cd /opt/docker_elk/logstash/
touch /opt/docker_elk/logstash/logstash.conf
vi logstash.conf
将以下代码写入
input {
beats {
port => 5044 # 接收来自Beats的日志数据的端口
}
}
filter {
if [source] == "/var/log/messages" { # 如果日志来源是/var/log/messages
# 处理/var/log/messages的过滤逻辑
grok {
match => { "message" => "%{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:host} %{DATA:program}(?:\[%{POSINT:pid}\])?: %{GREEDYDATA:message}" } # 使用Grok模式匹配对日志进行解析
}
# 可选:解析日期和时间字段
date {
match => [ "timestamp", "MMM d HH:mm:ss", "MMM dd HH:mm:ss" ] # 解析时间戳字段
}
}
}
output {
elasticsearch {
hosts => "192.168.1.1:9200" # Elasticsearch服务器的主机和端口
index => "messages-%{+YYYY.MM}" # 将日志数据索引到以年月为后缀的索引中
}
}
编写正式的kibana.yml文件(/opt/docker_elk/kibana/config/内)
cd /opt/docker_elk/kibana/config/
vi kibana.yml
将以下代码写入
server.name: kibana # 设置Kibana服务器的名称为"kibana"
server.host: "0" # 监听所有网络接口
elasticsearch.hosts: [ "http://192.168.1.1:9200" ] # 设置Elasticsearch的主机和端口
xpack.monitoring.ui.container.elasticsearch.enabled: true # 启用监控界面连接到Elasticsearch容器
i18n.locale: zh-CN # 设置界面语言为中文
6.给所有配置文件赋权
chmod 777 /opt/docker_elk/elasticsearch/config/elasticsearch.yml
chmod 777 /opt/docker_elk/elasticsearch/config2/elasticsearch.yml
chmod 777 /opt/docker_elk/kibana/config/kibana.yml
chmod 777 /opt/docker_elk/logstash/logstash.conf
7.编写/etc/hosts文件,写入10.11.1.1 elasticsearch
添加集群解析记录,IP是主机IP,后面紧跟的是集群域名。
vi /etc/hosts
cat /etc/hosts
三.启动正式ELK集群
配置虚拟内存,过低会导致无法启动,配置完后再启动集群。
sysctl -w vm.max_map_count=262144
cd /opt/docker_elk/
docker-compose -f docker-compose.yml up -d
docker ps
Windows日志收集(Winlogbeat)
安装包下载,建议下载压缩包,msi安装包安装完之后我找不到配置文件,尝试几次都这样,也可能是我不太熟悉。这里我使用的是官方压缩包安装的。
下载地址:https://www.elastic.co/cn/downloads/beats/winlogbeat(自行对照版本下载)
1.下载完后放到C盘根目录(其实都可以),然后用管理员权限打开powershell,cd切换到解压后的文件目录,输入安装命令,执行安装。
cd C:\winlogbeat-7.6.2-windows-x86_64\
.\install-service-winlogbeat.ps1
2.打开windows的服务(控制面板-服务)可以看到这里已经注册了一个系统服务。如果是没有注册成功,请检查你是不是在解压的目录里面用管理员权限执行的安装命令。
3.接下来是编写Winlogbeat配置文件,配置文件的名称是winlogbeat.yml,这里我把我的配置文件贴出来,大家可以参考一下。
winlogbeat.event_logs:
- name: Security
level: Error, Critical, Warning
tags: ["securitylog"]
- name: Application
level: Error, Critical, Warning
tags: ["applicationlog"]
- name: System
level: Error, Critical, Warning
tags: ["systemlog"]
output.logstash:
hosts: ["192.168.1.1:5044"]
processors:
- drop_fields:
fields: ["winlog.computer_name", "winlog.event_data.Application", "winlog.event_data.LayerName", "winlog.event_data.LayerRTID", "winlog.event_data.Protocol", "agent.ephemeral_id", "agent.version", "ecs.version", "winlog.event_data.FilterRTID", "_index", "_type", "event.action", "agent.id", "winlog.version", "winlog.task", "winlog.record_id", "winlog.provider_name", "winlog.provider_guid", "winlog.process.thread.id", "agent.type"]
fields:
source_ip: "192.168.1.2"
4.启动服务即可,下图的左侧是他的默认服务日志路径,如果启动失败可以查看一下日志信息,看看是哪里报错,一般都是配置文件格式或者配置编写错误的问题。
5.在kibana查看日志信息,如图:
Linux日志收集(Filebeat)
还是从官网下载安装包,注意版本对应即可
下载地址:https://www.elastic.co/cn/downloads/beats/filebeat(自行对照版本下载)
1.下载完后放到任意目录(这里我是放到了tmp目录),然后rpm -ivh 安装包名
(贴出来的命令有\符号是因为我用tab补全,自动带的),使用命令安装即可启动。
cd /tmp/
rpm -ivh filebeat-7.6.2-x86_64\ \(3\).rpm
2.编辑配置文件,这里老规矩,我还是贴出来大家参考参考。
vi /etc/filebeat/filebeat.yml
配置文件如下:
# ============================== Filebeat inputs ===============================
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/audit/audit.log # 审计日志文件路径
scan_frequency: 25s # 检测文件更改的扫描频率
tags: ["auditlog"] # 日志标签,用于标识审计日志
- type: log
enabled: true
paths:
- /var/log/secure # 安全日志文件路径
scan_frequency: 25s
tags: ["securelog"] # 日志标签,用于标识访问日志
processors:
- drop_event:
when:
contains:
message: "polkitd"
- type: log
enabled: true
paths:
- /var/log/messages # 信息日志文件路径
scan_frequency: 25s
tags: ["messageslog"] # 日志标签,用于标识访问日志
processors:
- drop_event:
when:
contains:
message: "filebeat:"
#============================= Filebeat modules ===============================
filebeat.config.modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: false
#==================== Elasticsearch template setting ==========================
setup.template.settings:
index.number_of_shards: 1
#============================== Kibana =====================================
setup.kibana:
#----------------------------- Logstash output --------------------------------
output.logstash:
hosts: ["192.168.1.1:5044"]
processors:
- add_host_metadata: ~
- add_cloud_metadata: ~
- add_docker_metadata: ~
- add_kubernetes_metadata: ~
- drop_fields:
fields: ["agent.ephemeral_id", "host.os.codename", "_id", "host.name", "host.id", "agent.version", "ecs.version", "agent.id", "@version", "version", "fields.index", "input.type", "_type", "agent.type"] # 删除不需要的字段
fields:
source_ip: "192.168.1.2"