ELK Stack(Elasticsearch + Logstash + Kibana)是主流的开源日志分析平台,广泛应用于系统监控、安全审计和业务分析场景。随着日志数据量增长,索引生命周期管理(ILM)成为保障平台稳定运行的关键能力。本文从ELK架构设计出发,详解集群搭建、日志采集管道配置和ILM自动化管理策略。
ELK Stack架构设计与组件职责
ELK Stack日志处理链路包含四个核心组件:
Elasticsearch:分布式搜索引擎,存储和检索日志数据,支持全文检索和聚合分析
Logstash:日志采集和处理管道,支持多输入源、过滤器和多输出目标
Kibana:Web可视化界面,提供日志查询、仪表盘和数据探索功能
Filebeat/Fluentd:轻量级日志采集器,部署在应用服务器上,转发日志到Logstash或Elasticsearch
生产环境推荐架构:Filebeat(采集)→ Logstash(处理)→ Elasticsearch(存储)→ Kibana(展示)。对于大规模场景,可在Logstash和Elasticsearch之间增加Kafka或Redis作为消息队列缓冲。
Elasticsearch集群部署配置
三节点集群部署,每个节点配置elasticsearch.yml:
# 节点1配置
cluster.name: elk-prod
node.name: node-1
node.roles: [master, data, ingest]
path.data: /data/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 0.0.0.0
http.port: 9200
transport.port: 9300
discovery.seed_hosts: ["10.0.1.101:9300", "10.0.1.102:9300", "10.0.1.103:9300"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]
# 生产环境关键配置
indices.fielddata.cache.size: 40%
indices.memory.index_buffer_size: 20%
thread_pool.write.queue_size: 1000
thread_pool.search.queue_size: 1000
# 安全配置
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true
xpack.security.transport.ssl.verification_mode: certificate
JVM堆内存配置(jvm.options),建议设置为物理内存的50%,不超过32GB:
-Xms16g
-Xmx16g
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:G1ReservePercent=25
Filebeat日志采集配置
Filebeat部署在应用服务器上,采集日志文件并转发到Logstash:
# /etc/filebeat/filebeat.yml
filebeat.inputs:
- type: filestream
id: nginx-access
paths:
- /var/log/nginx/access.log
parsers.json:
keys_under_root: true
add_error_key: true
- type: filestream
id: app-log
paths:
- /opt/app/logs/*.log
multiline.type: pattern
multiline.pattern: '^\d{4}-\d{2}-\d{2}'
multiline.negate: true
multiline.match: after
processors:
- add_fields:
target: ''
fields:
env: production
service: web-api
- drop_fields:
fields: ["agent.ephemeral_id", "agent.id", "agent.type"]
output.logstash:
hosts: ["10.0.1.200:5044"]
loadbalance: true
bulk_max_size: 2048
# 监控
monitoring.enabled: true
monitoring.cluster_uuid: "elk-prod-cluster"
Logstash数据处理管道配置
Logstash接收Filebeat数据后进行解析、过滤和增强:
# /etc/logstash/conf.d/01-beats-input.conf
input {
beats {
port => 5044
ssl => false
}
}
# /etc/logstash/conf.d/10-filter.conf
filter {
# 解析Nginx access日志
if [log][file][path] =~ "access.log" {
grok {
match => {
"message" => '%{IPORHOST:client_ip} - %{DATA:user} \[%{HTTPDATE:timestamp}\] "%{WORD:method} %{URIPATHPARAM:request} HTTP/%{NUMBER:http_version}" %{NUMBER:status} %{NUMBER:bytes} "%{DATA:referrer}" "%{DATA:agent}" rt=%{NUMBER:response_time}'
}
}
mutate {
convert => {
"status" => "integer"
"bytes" => "integer"
"response_time" => "float"
}
}
}
# GeoIP增强
geoip {
source => "client_ip"
target => "geoip"
fields => ["country_name", "region_name", "city_name"]
}
# 添加时间戳
date {
match => ["timestamp", "dd/MMM/yyyy:HH:mm:ss Z"]
target => "@timestamp"
}
# 移除冗余字段
mutate {
remove_field => ["message", "timestamp", "agent"]
}
}
# /etc/logstash/conf.d/90-output.conf
output {
elasticsearch {
hosts => ["https://10.0.1.101:9200", "https://10.0.1.102:9200", "https://10.0.1.103:9200"]
user => "logstash_writer"
password => "${LOGSTASH_PASSWORD}"
index => "logs-%{[@metadata][beat]}-%{+YYYY.MM.dd}"
template => "/etc/logstash/templates/logs-template.json"
template_name => "logs-template"
template_overwrite => true
}
}
Elasticsearch索引模板与映射配置
为日志索引创建模板,自动设置分片数、副本数和字段映射:
PUT _index_template/logs-template
{
"index_patterns": ["logs-*"],
"template": {
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1,
"refresh_interval": "30s",
"index.lifecycle.name": "logs-ilm-policy",
"index.lifecycle.rollover_alias": "logs-alias",
"mapping.total_fields.limit": 2000,
"analysis": {
"analyzer": {
"url_analyzer": {
"type": "pattern",
"pattern": "[/\?&=]"
}
}
}
},
"mappings": {
"properties": {
"@timestamp": { "type": "date" },
"client_ip": { "type": "ip" },
"method": { "type": "keyword" },
"status": { "type": "integer" },
"bytes": { "type": "long" },
"response_time": { "type": "float" },
"request": { "type": "text", "analyzer": "standard" },
"geoip": {
"properties": {
"country_name": { "type": "keyword" },
"city_name": { "type": "keyword" },
"location": { "type": "geo_point" }
}
}
}
}
},
"priority": 100
}
索引生命周期管理ILM策略配置
ILM(Index Lifecycle Management)自动管理索引从创建到删除的完整生命周期,分为五个阶段:
PUT _ilm/policy/logs-ilm-policy
{
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": {
"max_age": "1d",
"max_primary_shard_size": "30gb",
"max_docs": 50000000
},
"set_priority": { "priority": 100 }
}
},
"warm": {
"min_age": "3d",
"actions": {
"shrink": { "number_of_shards": 1 },
"forcemerge": { "max_num_segments": 1 },
"set_priority": { "priority": 50 },
"allocate": {
"number_of_replicas": 0
}
}
},
"cold": {
"min_age": "14d",
"actions": {
"set_priority": { "priority": 25 },
"freeze": {}
}
},
"frozen": {
"min_age": "30d",
"actions": {
"searchable_snapshots": {
"snapshot_repository": "logs-snapshots"
}
}
},
"delete": {
"min_age": "90d",
"actions": {
"delete": {}
}
}
}
}
}
各阶段说明:
Hot阶段:索引处于活跃写入状态,配置rollover触发条件(按天数、分片大小或文档数),满足任一条件即滚动创建新索引。
Warm阶段:索引停止写入,执行shrink减少分片数、force merge合并段、移到warm节点,降低资源消耗。
Cold阶段:索引冻结,查询时按需加载到内存,释放常驻内存。
Frozen阶段:索引转为可搜索快照,数据存储在S3或对象存储中,大幅降低存储成本。
Delete阶段:过期索引自动删除,释放磁盘空间。
ILM与别名绑定操作
# 创建初始索引并绑定别名
PUT logs-000001
{
"aliases": {
"logs-alias": {
"is_write_index": true
}
}
}
# 验证ILM策略
GET logs-000001/_ilm/explain
# 手动触发rollover
POST logs-alias/_rollover
# 查看ILM状态
GET _ilm/status
Kibana日志查询与可视化
Kibana Discover界面支持KQL(Kibana Query Language)语法查询日志:
# 查询5xx错误并按响应时间排序
status >= 500 and response_time > 1.0
# 查询特定IP的请求
client_ip: "192.168.1.100" and method: "POST"
# 聚合查询每分钟错误率
# 使用Lens或Vega可视化工具配置:
# X轴: @timestamp(1分钟间隔)
# Y轴: status >= 500的文档计数
# 按service字段分组
创建监控仪表盘:HTTP状态码分布饼图、响应时间P95/P99折线图、错误日志实时列表、地理访问热力图。
集群运维与故障排查
集群健康状态检查:
# 集群健康状态
GET _cluster/health?pretty
# 分片分配状态
GET _cat/shards?v&h=index,shard,prirep,state,docs,store,node
# 查看未分配分片原因
GET _cluster/allocation/explain
# 节点磁盘使用率
GET _cat/allocation?v
# 强制分配未分配分片
POST _cluster/reroute
{
"commands": [
{
"allocate_replica": {
"index": "logs-2026.08.17",
"shard": 0,
"node": "node-3"
}
}
]
}
常见问题处理:
1. 磁盘水位告警:当磁盘使用率超过85%(watermark.high)时,ES停止分配新分片;超过95%(watermark.flood)时,ES变为只读。调低ILM delete阶段min_age或增加节点磁盘容量。
2. 查询超时:对大时间范围查询使用异步搜索(Async Search)或增加search.max_buckets限制。
3. 滚动失败:检查别名是否正确绑定is_write_index,索引是否匹配ILM策略的index_patterns。
ELK Stack通过完整的日志采集、处理、存储和可视化链路,配合ILM自动化索引管理,支撑大规模日志分析场景。合理配置分片策略、资源限制和生命周期策略,是保障平台长期稳定运行的关键。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/elkstack-ri-zhi-fen-xi-ping-tai-da-jian-yu-elasticsearch/