概述
ELK Stack 是一个用于日志管理和分析的开源工具组合,是业界最流行的分布式日志分析平台。ELK Stack 可以将系统日志、网站日志、应用系统日志等各种日志进行收集、过滤、清洗、然后进行集中存放并可用于实时检索、分析。
核心组件
ELK Stack 由三个核心开源项目组成,现在通常被称为 Elastic Stack,因为加入了 Beats 系列:
| 组件 | 作用 | 描述 |
|---|---|---|
| Elasticsearch | 存储和搜索 | 分布式搜索和分析引擎,提供数据存储、索引和搜索能力 |
| Logstash | 数据处理 | 数据收集、处理和传输管道,支持数据转换和过滤 |
| Kibana | 可视化 | 数据可视化和管理界面,提供图表、仪表板和分析工具 |
| Beats | 数据采集 | 轻量级数据采集器系列,包括 Filebeat、Metricbeat 等 |
技术优势
- 实时性能: 近实时的日志处理和搜索能力
- 高扩展性: 支持水平扩展,可处理 PB 级数据
- 灵活架构: 模块化设计,可根据需求灵活组合
- 丰富生态: 强大的插件生态系统和社区支持
- 开源免费: 基础功能完全开源,成本可控
应用场景
| 场景 | 描述 | 适用性 |
|---|---|---|
| 日志分析 | 应用日志、系统日志集中管理和分析 | ⭐⭐⭐⭐⭐ |
| 监控告警 | 实时监控系统状态和业务指标 | ⭐⭐⭐⭐⭐ |
| 安全审计 | 安全日志分析和威胁检测 | ⭐⭐⭐⭐ |
| 业务分析 | 用户行为分析和业务指标统计 | ⭐⭐⭐⭐ |
| 性能分析 | 应用性能监控和性能瓶颈分析 | ⭐⭐⭐⭐ |
环境准备
系统要求
| 组件 | 最低配置 | 推荐配置 | 说明 |
|---|---|---|---|
| CPU | 2 核心 | 4 核心以上 | 计算密集型,特别是数据处理 |
| 内存 | 4GB | 8GB 以上 | Elasticsearch 内存需求较高 |
| 存储 | 50GB | 200GB 以上 SSD | 快速 I/O 对性能至关重要 |
| 网络 | 100Mbps | 1Gbps | 大量数据传输需要高带宽 |
支持的操作系统
- Linux: CentOS 7+, Ubuntu 18.04+, RHEL 7+
- Windows: Windows Server 2016+
- macOS: 10.14+
- Docker: 推荐使用容器化部署
架构设计
典型 ELK 架构
[数据源] → [Beats/Logstash] → [Elasticsearch] → [Kibana] → [用户]
↓ ↓ ↓ ↓
应用日志 数据采集 数据存储 可视化分析
系统日志 格式转换 索引检索 监控告警
网络日志 过滤清洗 聚合计算 仪表盘
数据流程
-
数据收集阶段
- Beats: 轻量级数据采集器,直接在数据源部署
- Logstash: 重量级数据处理器,支持复杂的数据转换
-
数据存储阶段
- Elasticsearch: 分布式搜索引擎,提供数据索引和存储
- 分片机制: 数据分布在多个节点,实现水平扩展
-
数据分析阶段
- Kibana: Web 界面,提供搜索、可视化和分析功能
- 仪表盘: 实时监控和业务分析
高可用架构
[负载均衡器]
|
┌──────────────┼──────────────┐
| | |
[Kibana-1] [Kibana-2] [Kibana-3]
| | |
└──────────────┼──────────────┘
|
[Elasticsearch 集群]
┌──────────────┼──────────────┐
| | |
[ES-Master] [ES-Data-1] [ES-Data-2]
| | |
└──────────────┼──────────────┘
|
[Logstash 集群]
┌──────────────┼──────────────┐
| | |
[Logstash-1] [Logstash-2] [Logstash-3]
| | |
└──────────────┼──────────────┘
|
[数据源 (Beats)]
Docker 快速部署
单节点部署(开发环境)
1. 创建 Docker Compose 文件
# docker-compose.yml
version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.7
container_name: elasticsearch
environment:
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms1g -Xmx1g"
- xpack.security.enabled=false
ports:
- "9200:9200"
- "9300:9300"
volumes:
- es_data:/usr/share/elasticsearch/data
networks:
- elk
restart: unless-stopped
logstash:
image: docker.elastic.co/logstash/logstash:7.17.7
container_name: logstash
volumes:
- ./logstash/config:/usr/share/logstash/config
- ./logstash/pipeline:/usr/share/logstash/pipeline
ports:
- "5044:5044"
- "9600:9600"
environment:
- "LS_JAVA_OPTS=-Xms512m -Xmx512m"
networks:
- elk
depends_on:
- elasticsearch
restart: unless-stopped
kibana:
image: docker.elastic.co/kibana/kibana:7.17.7
container_name: kibana
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- SERVER_NAME=kibana
- SERVER_HOST=0.0.0.0
ports:
- "5601:5601"
networks:
- elk
depends_on:
- elasticsearch
restart: unless-stopped
filebeat:
image: docker.elastic.co/beats/filebeat:7.17.7
container_name: filebeat
user: root
volumes:
- ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- /var/log:/var/log:ro
networks:
- elk
depends_on:
- elasticsearch
- logstash
restart: unless-stopped
volumes:
es_data:
driver: local
networks:
elk:
driver: bridge
2. 创建配置文件目录
# 创建配置目录
mkdir -p logstash/config logstash/pipeline filebeat
# 创建 Logstash 配置
cat > logstash/config/logstash.yml << EOF
http.host: "0.0.0.0"
xpack.monitoring.elasticsearch.hosts: [ "http://elasticsearch:9200" ]
path.config: /usr/share/logstash/pipeline
EOF
# 创建 Logstash 管道配置
cat > logstash/pipeline/logstash.conf << EOF
input {
beats {
port => 5044
}
}
filter {
if [fields][log_type] == "nginx" {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
date {
match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
}
}
}
output {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
}
}
EOF
# 创建 Filebeat 配置
cat > filebeat/filebeat.yml << EOF
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/*.log
fields:
log_type: system
fields_under_root: true
- type: docker
containers.ids:
- "*"
processors:
- add_docker_metadata:
host: "unix:///var/run/docker.sock"
output.logstash:
hosts: ["logstash:5044"]
logging.level: info
logging.to_files: true
logging.files:
path: /var/log/filebeat
name: filebeat
keepfiles: 7
permissions: 0644
EOF
3. 启动 ELK Stack
# 启动所有服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs -f
4. 验证部署
# 检查 Elasticsearch
curl -X GET "localhost:9200/_cluster/health?pretty"
# 检查 Kibana(在浏览器中访问)
# http://localhost:5601
# 检查 Logstash
curl -X GET "localhost:9600/_node/stats/pipeline?pretty"
Elasticsearch 配置
核心配置文件
# elasticsearch.yml
# 集群名称
cluster.name: elk-cluster
# 节点名称
node.name: es-node-1
# 节点角色
node.roles: [ master, data, ingest ]
# 网络配置
network.host: 0.0.0.0
http.port: 9200
transport.port: 9300
# 集群发现
discovery.seed_hosts: ["es-node-1", "es-node-2", "es-node-3"]
cluster.initial_master_nodes: ["es-node-1"]
# 数据和日志路径
path.data: /usr/share/elasticsearch/data
path.logs: /usr/share/elasticsearch/logs
# 内存设置
bootstrap.memory_lock: true
# 安全配置(可选)
xpack.security.enabled: false
xpack.security.transport.ssl.enabled: false
xpack.security.http.ssl.enabled: false
JVM 优化配置
# jvm.options
# 堆内存设置(推荐设置为物理内存的一半,但不超过32GB)
-Xms2g
-Xmx2g
# GC 配置
-XX:+UseG1GC
-XX:G1HeapRegionSize=16m
-XX:+UnlockExperimentalVMOptions
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
# 其他优化
-Djava.io.tmpdir=${ES_TMPDIR}
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/usr/share/elasticsearch/logs/
索引模板配置
PUT _index_template/logs_template
{
"index_patterns": ["logs-*"],
"template": {
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1,
"index.refresh_interval": "30s",
"index.codec": "best_compression"
},
"mappings": {
"properties": {
"@timestamp": {
"type": "date"
},
"message": {
"type": "text",
"analyzer": "standard"
},
"level": {
"type": "keyword"
},
"service": {
"type": "keyword"
},
"host": {
"properties": {
"name": { "type": "keyword" },
"ip": { "type": "ip" }
}
}
}
}
}
}
Logstash 数据处理
输入插件配置
Beats 输入
input {
beats {
port => 5044
ssl => false
}
}
文件输入
input {
file {
path => "/var/log/nginx/access.log"
start_position => "beginning"
sincedb_path => "/usr/share/logstash/data/sincedb_nginx"
codec => "json"
tags => ["nginx", "access"]
}
}
TCP/UDP 输入
input {
tcp {
port => 5000
codec => json_lines
}
udp {
port => 5001
codec => json
}
}
过滤器插件配置
Grok 模式匹配
filter {
if "nginx" in [tags] {
grok {
match => {
"message" => "%{COMBINEDAPACHELOG}"
}
}
# 解析时间戳
date {
match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
}
# 转换数据类型
mutate {
convert => {
"response" => "integer"
"bytes" => "integer"
}
}
# 添加地理位置信息
geoip {
source => "clientip"
target => "geoip"
}
}
}
JSON 解析
filter {
if [fields][log_type] == "application" {
json {
source => "message"
}
# 移除原始消息字段
mutate {
remove_field => ["message"]
}
# 添加自定义字段
mutate {
add_field => {
"log_source" => "application"
"processed_at" => "%{+yyyy-MM-dd HH:mm:ss}"
}
}
}
}
输出插件配置
Elasticsearch 输出
output {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
# 模板配置
template_name => "logs"
template_pattern => "logs-*"
template_overwrite => true
# 性能优化
workers => 2
flush_size => 1000
idle_flush_time => 5
}
}
多输出配置
output {
# 发送到 Elasticsearch
elasticsearch {
hosts => ["http://elasticsearch:9200"]
index => "logs-%{+YYYY.MM.dd}"
}
# 错误日志发送到文件
if [level] == "ERROR" {
file {
path => "/var/log/logstash/errors.log"
codec => json_lines
}
}
# 调试输出到控制台
if [debug] == "true" {
stdout {
codec => rubydebug
}
}
}
Kibana 可视化分析
基础配置
# kibana.yml
server.port: 5601
server.host: "0.0.0.0"
server.name: "kibana"
# Elasticsearch 配置
elasticsearch.hosts: ["http://elasticsearch:9200"]
elasticsearch.username: "kibana_system"
elasticsearch.password: "changeme"
# 安全配置
xpack.security.enabled: true
xpack.encryptedSavedObjects.encryptionKey: "something_at_least_32_characters"
# 监控配置
monitoring.enabled: true
monitoring.kibana.collection.enabled: true
# 国际化
i18n.locale: "zh-CN"
索引模式创建
-
访问 Kibana 管理界面
http://localhost:5601 -
创建索引模式
- 进入 “Management” → “Stack Management” → “Index Patterns”
- 点击 “Create index pattern”
- 输入索引模式:
logs-*或filebeat-* - 选择时间字段:
@timestamp
数据可视化
1. 创建搜索查询
# 基础搜索
level:ERROR
# 时间范围搜索
@timestamp:[now-1h TO now] AND service:nginx
# 复合查询
(level:ERROR OR level:WARN) AND service:(nginx OR apache)
# 正则表达式搜索
message:/error.*database/
# 聚合搜索
service:nginx AND response:>=400
2. 创建可视化图表
时间序列图:
- 类型:Line/Area chart
- Y轴:Count of records
- X轴:Date histogram on @timestamp
饼图:
- 类型:Pie chart
- 分片:Terms aggregation on service.keyword
数据表:
- 类型:Data table
- 行:Terms on level.keyword
- 指标:Count, Average response time
3. 创建仪表盘
系统监控仪表盘:
{
"version": "7.17.7",
"objects": [
{
"id": "system-logs-dashboard",
"type": "dashboard",
"attributes": {
"title": "系统日志监控",
"hits": 0,
"description": "系统日志实时监控仪表盘",
"panelsJSON": "[{\"version\":\"7.17.7\",\"panelIndex\":\"1\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15}}]"
}
}
]
}
Beats 数据采集
Filebeat 配置
基础配置
# filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
- /var/log/nginx/error.log
fields:
service: nginx
environment: production
fields_under_root: true
multiline.pattern: '^\d{4}-\d{2}-\d{2}'
multiline.negate: true
multiline.match: after
- type: log
enabled: true
paths:
- /var/log/app/*.log
fields:
service: application
log_type: app
json.keys_under_root: true
json.add_error_key: true
# 输出配置
output.logstash:
hosts: ["logstash:5044"]
# 或直接输出到 Elasticsearch
# output.elasticsearch:
# hosts: ["elasticsearch:9200"]
# index: "filebeat-%{+yyyy.MM.dd}"
# 监控配置
monitoring.enabled: true
monitoring.elasticsearch.hosts: ["elasticsearch:9200"]
# 日志配置
logging.level: info
logging.to_files: true
logging.files:
path: /var/log/filebeat
name: filebeat
keepfiles: 7
permissions: 0644
模块化配置
# 启用 Nginx 模块
filebeat modules enable nginx
# 配置 Nginx 模块
# modules.d/nginx.yml
- module: nginx
access:
enabled: true
var.paths: ["/var/log/nginx/access.log"]
error:
enabled: true
var.paths: ["/var/log/nginx/error.log"]
Metricbeat 配置
# metricbeat.yml
metricbeat.config.modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: true
reload.period: 10s
# 系统模块
metricbeat.modules:
- module: system
metricsets:
- cpu
- load
- memory
- network
- process
- process_summary
- socket_summary
enabled: true
period: 10s
processes: ['.*']
# Docker 模块
- module: docker
metricsets:
- container
- cpu
- diskio
- healthcheck
- info
- memory
- network
hosts: ["unix:///var/run/docker.sock"]
period: 10s
enabled: true
# 输出配置
output.elasticsearch:
hosts: ["elasticsearch:9200"]
index: "metricbeat-%{+yyyy.MM.dd}"
# 模板和生命周期管理
setup.template.enabled: true
setup.template.settings:
index.number_of_shards: 1
index.number_of_replicas: 1
setup.ilm.enabled: true
setup.ilm.rollover_alias: "metricbeat"
setup.ilm.pattern: "{now/d}-000001"
Packetbeat 网络监控
# packetbeat.yml
packetbeat.interfaces.device: any
packetbeat.flows:
timeout: 30s
period: 10s
packetbeat.protocols:
dns:
ports: [53]
include_authorities: true
include_additionals: true
http:
ports: [80, 8080, 8000, 5000, 8002]
real_ip_header: "X-Forwarded-For"
mysql:
ports: [3306]
redis:
ports: [6379]
output.elasticsearch:
hosts: ["elasticsearch:9200"]
index: "packetbeat-%{+yyyy.MM.dd}"
相关文章
监控与日志管理
- ELK Stack 完整指南 - ELK Stack 分布式日志管理平台
- GrayLog 分布式日志 - 轻量级日志管理平台
- SkyWalking 链路追踪 - APM 应用性能监控
容器化部署
- Docker 环境部署 - 容器化最佳实践
- Docker 容器引擎安装 - 容器环境搭建
- Docker 基本命令 - 容器操作指南
- Kubernetes 集群部署 - 容器编排
核心组件详解
- Elasticsearch 搜索引擎 - 分布式搜索和分析引擎
- MySQL 关系型数据库 - 传统数据库对比
- Redis 内存数据库 - 高性能缓存方案
中间件集成
- Kafka 消息队列 - 大数据管道集成
- RabbitMQ 消息队列 - 可靠消息传递
大数据技术
- Flink DataStream API - 实时数据处理
总结
ELK Stack 作为业界领先的分布式日志管理和分析平台,为海量数据的收集、存储、分析和可视化提供了完整的解决方案:
🎯 核心价值
- 统一日志管理: 集中收集和管理分布式系统的所有日志
- 实时分析能力: 近实时的搜索、聚合和分析功能
- 可视化监控: 丰富的图表和仪表盘,直观展示数据洞察
- 高可扩展性: 支持水平扩展,处理 PB 级数据
🛠️ 技术要点
- 架构设计: 合理的组件选择和部署架构
- 数据采集: Beats 系列轻量级采集器 + Logstash 数据处理
- 存储优化: Elasticsearch 索引策略和性能调优
- 可视化分析: Kibana 仪表盘和监控告警
- 运维管理: 集群监控、安全配置和故障处理
🚀 应用场景
- DevOps 监控: 应用性能监控和故障诊断
- 安全分析: 安全日志分析和威胁检测
- 业务分析: 用户行为分析和业务指标监控
- 合规审计: 日志审计和合规性报告
💡 最佳实践建议:
- 从小规模单节点开始,逐步扩展到集群
- 合理设计索引策略和数据生命周期
- 重视安全配置和访问控制
- 定期备份重要配置和索引数据
- 监控集群健康状态和性能指标