Elk
概述
ELK 是一套由 Elasticsearch、Logstash 和 Kibana 组成的开源工具栈,用于日志的搜索、分析和可视化展示。
| 组件 | 功能 |
|---|---|
| Elasticsearch | 分布式搜索和分析引擎,负责日志数据的存储与检索 |
| Logstash | 日志采集与处理管道,负责数据的过滤、转换和传输 |
| Kibana | 数据可视化平台,提供图表展示和交互式查询界面 |
部署准备
1. 创建数据目录
mkdir data plugins
chmod 777 data plugins2. 创建 Elasticsearch 配置文件
elasticsearch.yml:
network.host: 0.0.0.03. 创建 ES JVM 配置文件
es-jvm.options:
-Xms1g
-Xmx1g
8-13:-XX:+UseConcMarkSweepGC
8-13:-XX:CMSInitiatingOccupancyFraction=75
8-13:-XX:+UseCMSInitiatingOccupancyOnly
14-:-XX:+UseG1GC
14-:-XX:G1ReservePercent=25
14-:-XX:InitiatingHeapOccupancyPercent=30
-Djava.io.tmpdir=${ES_TMPDIR}
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=data
-XX:ErrorFile=logs/hs_err_pid%p.log
8:-XX:+PrintGCDetails
8:-XX:+PrintGCDateStamps
8:-XX:+PrintTenuringDistribution
8:-XX:+PrintGCApplicationStoppedTime
8:-Xloggc:logs/gc.log
8:-XX:+UseGCLogFileRotation
8:-XX:NumberOfGCLogFiles=32
8:-XX:GCLogFileSize=64m
9-:-Xlog:gc*,gc+age=trace,safepoint:file=logs/gc.log:utctime,pid,tags:filecount=32,filesize=64m4. 创建 Kibana 配置文件
kibana.yml:
server.name: kibana
server.host: "0"
elasticsearch.hosts: [ "http://elasticsearch:9200" ]
xpack.monitoring.ui.container.elasticsearch.enabled: true
i18n.locale: "zh-CN"5. 创建 Kibana JVM 配置文件
kibana-jvm.options:
-Xms1g
-Xmx1g
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=75
-XX:+UseCMSInitiatingOccupancyOnly
-Djava.awt.headless=true
-Dfile.encoding=UTF-8
-Djruby.compile.invokedynamic=true
-Djruby.jit.threshold=0
-Djruby.regexp.interruptible=true
-XX:+HeapDumpOnOutOfMemoryError
-Djava.security.egd=file:/dev/urandom
-Dlog4j2.isThreadContextMapInheritable=true6. 创建 Logstash 配置文件
logstash.conf:
input {
beats {
port => "5044"
}
}
output {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
index => "test"
}
stdout { codec => rubydebug }
}7. 创建 Docker Compose 编排文件
docker-compose.yaml:
services:
elasticsearch:
image: elasticsearch:7.7.0
container_name: elasticsearch
restart: always
environment:
- "discovery.type=single-node"
- "TZ=Asia/Shanghai"
volumes:
- ./data:/usr/share/elasticsearch/data
- ./elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
- ./es-jvm.options:/usr/share/elasticsearch/config/jvm.options
- ./plugins:/usr/share/elasticsearch/plugins
ports:
- 9200:9200
- 9300:9300
deploy:
resources:
limits:
cpus: "1"
memory: "2G"
kibana:
image: kibana:7.7.0
container_name: kibana
restart: always
depends_on:
- elasticsearch
environment:
- i18n.locale=zh-CN
- TZ=Asia/Shanghai
volumes:
- ./kibana.yml:/usr/share/kibana/config/kibana.yml
ports:
- 5601:5601
deploy:
resources:
limits:
cpus: "1"
memory: "1G"
logstash:
image: logstash:7.7.0
container_name: logstash
restart: always
volumes:
- ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
- ./kibana-jvm.options:/usr/share/logstash/config/jvm.options
ports:
- 5044:5044
environment:
- TZ=Asia/Shanghai
depends_on:
- elasticsearch
deploy:
resources:
limits:
cpus: "1"
memory: "1G"启动服务
docker compose up -d查看容器运行状态:
docker compose ps验证访问
# 验证 Elasticsearch
curl http://127.0.0.1:9200
# 验证 Kibana
curl http://127.0.0.1:5601在浏览器中打开 http://<服务器IP>:5601 即可访问 Kibana 界面。
安全配置(设置密码)
步骤一:修改 Elasticsearch 配置
在 elasticsearch.yml 中添加以下内容:
# 开启 X-Pack 安全认证
xpack.security.enabled: true
# 关闭 SSL 证书校验(7.7.0 版本必须配置,否则启动失败)
xpack.security.transport.ssl.enabled: false
# 允许远程访问
network.host: 0.0.0.0
discovery.type: single-node步骤二:重启 Elasticsearch 并设置密码
# 重启 Elasticsearch 容器
docker compose restart elasticsearch
# 进入容器设置密码
docker exec -it elasticsearch /bin/bash
elasticsearch-setup-passwords interactive按提示依次为以下用户设置密码:
| 用户 | 说明 |
|---|---|
elastic |
超级管理员(必设,Kibana/Logstash 连接使用) |
apm_system |
APM 系统用户 |
kibana |
Kibana 连接 ES 使用 |
logstash_system |
Logstash 监控用户 |
beats_system |
Beats 监控用户 |
建议:将所有密码统一设置为相同值,便于管理。
步骤三:配置 Kibana 密码
修改 kibana.yml,添加用户名和密码:
server.name: kibana
server.host: "0"
elasticsearch.hosts: [ "http://elasticsearch:9200" ]
xpack.monitoring.ui.container.elasticsearch.enabled: true
i18n.locale: "zh-CN"
# 配置 ES 认证
elasticsearch.username: "elastic"
elasticsearch.password: "你设置的ES密码"
# 开启 Kibana 登录认证
xpack.security.enabled: true步骤四:配置 Logstash 密码
修改 logstash.conf,在 output 中添加认证信息:
input {
beats {
port => "5044"
}
}
output {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
index => "log-%{+YYYY.MM.dd}"
user => "elastic"
password => "你设置的ES密码"
}
stdout { codec => rubydebug }
}步骤五:重启所有服务
docker compose restartLogstash 高级配置示例
以下是一个完整的 Logstash 配置示例,包含日志解析、字段处理和性能优化:
input {
beats {
port => 5044
}
}
filter {
# 解析日志行,提取时间戳和其他字段
grok {
match => {
"message" => "^<(?<log_level>\d+)> %{TIMESTAMP_ISO8601:log_timestamp} \[%{LOGLEVEL:log_level_str}\] %{IP:client_ip} #%{NUMBER:connection_id} \[%{DATA:api_path}\] \[%{DATA:api_response}\] %{NUMBER:response_time}ms (?<json_data>{.*})$"
}
tag_on_failure => ["_grokparsefailure"]
}
# 将日志时间戳设置为 @timestamp
date {
match => ["log_timestamp", "yyyy-MM-dd HH:mm:ss"]
target => "@timestamp"
timezone => "Asia/Shanghai"
locale => "zh_CN"
tag_on_failure => ["_dateparsefailure"]
}
# 如果日期解析失败,使用当前时间作为备选
if "_dateparsefailure" in [tags] {
mutate {
remove_tag => ["_dateparsefailure"]
add_tag => ["timestamp_fallback"]
}
date {
match => ["@timestamp", "ISO8601"]
timezone => "Asia/Shanghai"
}
}
# 添加计算字段
mutate {
add_field => {
"api_performance" => "%{response_time}"
"status" => "%{response_time}"
}
}
# 清理冗余字段,减少存储开销
mutate {
remove_field => [
"[beat][hostname]",
"[beat][name]",
"[beat][version]",
"[message]"
]
}
}
output {
elasticsearch {
hosts => ["127.0.0.1:9200"]
index => "%{index}-%{+YYYY-MM-dd}"
user => "elastic"
password => "aaabbbccc"
}
}常用管理命令
| 操作 | 命令 |
|---|---|
| 启动所有服务 | docker compose up -d |
| 停止所有服务 | docker compose stop |
| 重启所有服务 | docker compose restart |
| 查看容器状态 | docker compose ps |
| 查看日志 | docker compose logs -f --tail=100 |
| 查看 Elasticsearch 日志 | docker logs elasticsearch -f --tail=50 |
| 查看 Kibana 日志 | docker logs kibana -f --tail=50 |
| 查看 Logstash 日志 | docker logs logstash -f --tail=50 |
| 进入 Elasticsearch 容器 | docker exec -it elasticsearch /bin/bash |
常见问题
Q:Elasticsearch 启动失败,提示内存不足?
检查 JVM 堆内存配置是否超过宿主机可用内存:
# 查看宿主机内存
free -h
# 修改 es-jvm.options 中的 -Xms 和 -Xmx 参数
# 建议设置为宿主机内存的 50%,且不超过 32GQ:Kibana 无法连接到 Elasticsearch?
- 确认 Elasticsearch 已完全启动:
curl http://127.0.0.1:9200- 检查
elasticsearch.hosts配置是否正确:
elasticsearch.hosts: [ "http://elasticsearch:9200" ] # 容器内部使用服务名
# 或
elasticsearch.hosts: [ "http://127.0.0.1:9200" ] # 宿主机访问- 如已开启认证,确认用户名密码配置正确。
Q:Logstash 无法向 Elasticsearch 写入数据?
- 检查 Elasticsearch 是否正常运行
- 确认认证信息(user/password)是否正确
- 查看 Logstash 日志排查错误:
docker logs logstash --tail=100Q:如何升级 ELK 版本?
- 修改
docker-compose.yaml中的镜像版本号(三个组件版本需保持一致) - 备份 Elasticsearch 数据目录
./data - 执行
docker compose down停止服务 - 执行
docker compose up -d启动新版本 - 如遇索引兼容性问题,需执行数据迁移或重建索引
Q:Beats 如何配置输出到 Logstash?
在 Filebeat/Metricbeat 的配置文件中设置:
output.logstash:
hosts: ["<Logstash_IP>:5044"]