CSDN 完整教程:内网 Docker Compose 一键部署 ELK7.17,SpringBoot 接入日志(单机 + 集群完整版)
·
文章前言
需求背景
本地开发机器 192.168.1.8,内网服务器 192.168.1.140(大磁盘),需要搭建轻量化 ELK 日志平台收集 SpringBoot 应用日志。
踩坑记录:根分区 Docker 日志暴涨 42G 触发 ES 磁盘洪水只读锁、ES 单节点 yellow 分片告警、版本不兼容、内网 TCP 日志采集不通等问题,完整记录从 0 到日志可视化全流程,同时补充SpringBoot 集群接入、ELK 三节点集群生产拓展方案,后续复用直接复制配置即可。
环境版本统一(避免版本报错)
- Elasticsearch:7.17.14
- Kibana:7.17.14
- Logstash:7.17.14
- SpringBoot:2.7.x/ 3.x 通用
- 部署方式:Docker Compose
一、单机 ELK 部署(内网 Demo 可用,本次实操完整版)
1.1 服务器目录结构(192.168.1.140)
plaintext
/home/tlrobot/elk
├── docker-compose.yml # ELK编排文件
├── elasticsearch/
│ ├── plugins # ES插件挂载目录
│ └── data # ES持久化数据目录
├── kibana/config/
│ └── kibana.yml # Kibana配置
└── logstash/
└── logstash.conf # 日志采集输出规则
1.2 docker-compose.yml 完整配置(修复所有报错版本)
version: '3.8'
networks:
my-network:
services:
elasticsearch:
image: elasticsearch:7.17.14
ports:
- '19200:9200'
- '19300:9300'
container_name: elasticsearch
restart: always
environment:
- "cluster.name=docker-cluster"
- 'discovery.type=single-node'
- 'ES_JAVA_OPTS=-Xms512m -Xmx512m'
# 单节点关闭副本,消除yellow分片告警
- index.number_of_replicas=0
# 调低磁盘洪水水位,提前预警
- cluster.routing.allocation.disk.watermark.low=85%
- cluster.routing.allocation.disk.watermark.high=90%
- cluster.routing.allocation.disk.watermark.flood_stage=92%
volumes:
- ./elasticsearch/plugins:/usr/share/elasticsearch/plugins
- ./elasticsearch/data:/usr/share/elasticsearch/data
networks:
- my-network
kibana:
image: kibana:7.17.14
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
environment:
- ELASTICSEARCH_URL=http://elasticsearch:9200
- elasticsearch.hosts=http://es:9200
- I18N_LOCALE=zh-CN
networks:
- my-network
depends_on:
- elasticsearch
logstash:
image: logstash:7.17.14
container_name: logstash
restart: always
volumes:
- /etc/localtime:/etc/localtime
- ./logstash/logstash.conf:/usr/share/logstash/pipeline/logstash.conf
ports:
- '4560:4560'
- '50000:50000/tcp'
- '50000:50000/udp'
- '9600:9600'
environment:
LS_JAVA_OPTS: -Xms512m -Xmx512m
TZ: Asia/Shanghai
MONITORING_ENABLED: false
links:
- elasticsearch:es
networks:
- my-network
depends_on:
- elasticsearch
1.3 Logstash 采集配置 logstash/logstash.conf
监听 4560 端口 TCP JSON 日志,按天分索引存储
input {
tcp {
mode => "server"
host => "0.0.0.0"
port => 4560
codec => json_lines
type => "info"
}
}
filter {}
output {
elasticsearch {
action => "index"
hosts => "es:9200"
index => "springboot-demo-log-%{+YYYY.MM.dd}"
}
}
1.4 服务器初始化 & 启动命令
1)创建目录并授权(ES 数据目录必须 777,启动报错根源)
mkdir -p elasticsearch/plugins elasticsearch/data kibana/config logstash
chmod 777 elasticsearch/data
2)防火墙放行内网端口
firewall-cmd --add-port=4560/tcp --permanent
firewall-cmd --add-port=19200/tcp --permanent
firewall-cmd --add-port=5601/tcp --permanent
firewall-cmd --reload
3)启动 ELK
docker compose up -d
# 查看启动状态
docker ps
启动成功截图:
1.5 踩坑 1:磁盘爆满触发 ES 429 洪水只读锁报错
报错日志:
disk usage exceeded flood-stage watermark, index has read-only-allow-delete block
根因
Docker 默认存储在根分区 /,容器日志暴涨 42G 占满磁盘,ES 自动上锁拒绝写入。
解决方案
- 清空超大容器日志(不删除镜像、容器)
# 截断42G日志文件,瞬间释放42G空间
truncate -s 0 /var/lib/docker/containers/xxx/json.log
- 解锁 ES 只读锁
curl -XPUT -H "Content-Type: application/json" http://127.0.0.1:19200/_all/_settings -d '{"index.blocks.read_only_allow_delete": null}'
- 长期根治:Docker 全局限制日志大小,避免日志暴涨
vim /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "500m",
"max-file": "3"
}
}
systemctl restart docker
二、SpringBoot 应用接入 ELK(单机 / 集群通用)
2.1 Maven 依赖 pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Logstash JSON日志编码器 -->
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>7.0.1</version>
</dependency>
</dependencies>
2.2 日志配置 resources/logback-spring.xml
内网 Logstash 地址:192.168.1.140:4560
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<!-- TCP输出到内网Logstash -->
<appender name="LOGSTASH_TCP" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>192.168.1.140:4560</destination>
<reconnectionDelay>3000</reconnectionDelay>
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<includeMdcKeyName>appName</includeMdcKeyName>
</encoder>
</appender>
<root level="info">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="LOGSTASH_TCP"/>
</root>
</configuration>
2.3 应用配置 application.yml
spring:
application:
name: elk-springboot-demo
2.4 测试日志 Controller
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LogTestController {
private static final Logger log = LoggerFactory.getLogger(LogTestController.class);
@GetMapping("/demo/log")
public String printLog() {
log.info("测试普通日志,参数={}", 666);
log.warn("警告日志测试");
log.error("异常日志测试", new Exception("demo模拟报错"));
return "日志发送完成,请访问Kibana查看";
}
}
2.5 验证链路
- 本地启动 SpringBoot,访问
http://localhost:8080/demo/log - Kibana 索引管理页面查看自动生成日志索引
三、Kibana 可视化查看日志完整操作
3.1 创建索引模式
左侧菜单栏「Kibana」→「索引模式」→ 创建索引模式,匹配规则填写:
springboot-demo-log-*
时间字段选择 @timestamp 完成创建。
3.2 Discover 日志检索页面(最终效果图)
点击左上角汉堡菜单,展开主菜单→「数据」→「Discover」,即可查看所有采集日志,支持过滤、检索、查看异常堆栈。
常用检索语法
- 只查看错误日志:
level: ERROR - 检索包含指定关键词日志:
message: 测试异常 - 筛选当前服务日志:
appName: elk-springboot-demo
四、拓展 1:SpringBoot 集群接入 ELK 高可用方案
4.1 多台 Logstash 做故障转移
内网部署 2 台 Logstash 服务器:
- 192.168.1.140
- 192.168.1.141 修改 logback 的 destination,多地址逗号分隔,自动故障转移:
<destination>192.168.1.140:4560,192.168.1.141:4560</destination>
4.2 多应用集群区分日志
每个微服务配置独立 spring.application.name,Kibana 通过 appName 字段筛选不同服务日志。
4.3 生产优化:新增 Redis/Kafka 缓冲
高并发场景建议在 SpringBoot 和 Logstash 中间增加 Kafka,避免 Logstash 宕机丢失日志。
五、拓展 2:ELK 三节点集群部署方案(生产容灾)
5.1 ES 集群核心改动
- 删除
discovery.type=single-node单节点配置 - 开启副本分片
index.number_of_replicas=1,集群状态变为 Green - 配置集群节点发现、主节点选举
- 三个 ES 容器独立端口、独立数据卷
Logstash 输出多 ES 节点(负载均衡)
output {
elasticsearch {
hosts => ["es-node1:9200","es-node2:9200","es-node3:9200"]
index => "springboot-demo-log-%{+YYYY.MM.dd}"
load_balancing => true
}
}
5.2 Kibana 集群配置
连接多个 ES 节点,防止单 ES 节点宕机无法访问日志
environment:
elasticsearch.hosts: ["http://es-node1:9200","http://es-node2:9200"]
5.3 单机 vs 集群核心差异对比
| 维度 | 单机 ELK(Demo) | 三节点 ELK 集群(生产) |
|---|---|---|
| 分片状态 | yellow(副本 1)/green(副本 0) | Green,分片有副本容灾 |
| 数据安全 | 单磁盘故障日志全部丢失 | 分片多副本,单节点宕机不丢日志 |
| 并发能力 | 单 ES 节点性能有限 | 分片分散多节点,支持高并发写入 |
| 部署复杂度 | 极简,单 compose 文件 | 多节点编排,需配置集群发现 |
| SpringBoot 配置 | 单 Logstash 地址 | 多 Logstash 地址故障转移 |
六、总结 & 复用指南
- Demo 快速搭建:直接复制第一章节单机 docker-compose,执行初始化命令即可一键启动 ELK;
- 日志采集链路:SpringBoot TCP 输出 JSON → Logstash 4560 端口接收 → ES 按天分索引 → Kibana 可视化检索;
- 核心踩坑点:根分区 Docker 日志爆满、ES 数据目录权限不足、ELK 版本不一致、单节点 yellow 分片;
- 生产拓展:多 Logstash 高可用、ES 三节点集群、Kafka 缓冲削峰。
更多推荐
所有评论(0)