Docker部署ELK Stack后Kibana无数据的问题排查求助
问题描述
为学校项目首次在Docker中搭建ELK Stack,包含带存储卷的Elasticsearch、Logstash容器,用于向Logstash传输数据的Filebeat容器,以及用于日志可视化的Kibana容器。所有容器配置启动后,Kibana无法从Elasticsearch获取数据,添加索引模式时提示“无匹配的数据流、索引或索引别名”,索引管理页面也无任何内容。
配置文件
docker-compose.yml
version: '3.6' services: Elasticsearch: image: elasticsearch:8.5.3 container_name: elasticsearch restart: always volumes: - elastic_data:/usr/share/elasticsearch/data/ environment: ES_JAVA_OPTS: "-Xmx750m -Xms750m" discovery.type: single-node xpack.security.enabled: false ports: - '9200:9200' - '9300:9300' networks: - elk Logstash: image: logstash:8.5.3 container_name: logstash restart: always volumes: - ./logstash/logstash.conf:/etc/logstash/conf.d/logstash.conf:ro command: logstash -f /etc/logstash/conf.d/logstash.conf depends_on: - Elasticsearch ports: - '9600:9600' environment: LS_JAVA_OPTS: "-Xmx750m -Xms750m" networks: - elk Kibana: image: kibana:8.5.3 container_name: kibana restart: always ports: - '5601:5601' environment: - ELASTICSEARCH_URL=http://elasticsearch:9200 depends_on: - Elasticsearch networks: - elk Filebeat: container_name: filebeat image: "docker.elastic.co/beats/filebeat:8.5.3" restart: always user: root volumes: - ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro - /var/lib/docker:/var/lib/docker:ro - /var/run/docker.sock:/var/run/docker.sock networks: - elk volumes: elastic_data: networks: elk: driver: bridge
logstash/logstash.conf
input { beats { port => 5044 } } output { elasticsearch { hosts => "elasticsearch" codec => "json" index => "logstash-%{indexDay}" } stdout { codec => rubydebug } }
filebeat/filebeat.yml
filebeat.inputs: - type: log enabled: true paths: - '/var/lib/docker/containers/*/*.log' processors: - add_docker_metadata: host: "unix:///var/run/docker.sock" output.logstash: hosts: ["logstash:5044"]
问题排查与修复方案
1. Logstash索引变量未定义(核心问题)
你的Logstash输出配置中使用了%{indexDay}变量,但该字段并未在任何地方定义,导致Elasticsearch无法创建有效索引,最终没有数据写入。
修复方法:将索引名替换为Elasticsearch支持的日期格式,使用Logstash内置的日期变量:
修改logstash/logstash.conf的output部分:
output { elasticsearch { hosts => "http://elasticsearch:9200" # 补充完整协议,避免潜在解析问题 codec => "json" index => "logstash-%{+YYYY.MM.dd}" # 使用内置日期格式生成索引名 } stdout { codec => rubydebug } }
2. 完善Logstash的Beats输入配置
确保Logstash的Beats输入监听所有网络接口(默认可能只监听localhost),避免Filebeat无法连接:
修改logstash/logstash.conf的input部分:
input { beats { port => 5044 host => "0.0.0.0" # 监听所有接口,确保容器内可访问 } }
3. 容器启动依赖优化(解决服务就绪问题)
depends_on仅保证容器启动顺序,不确保Elasticsearch服务完全就绪。给Elasticsearch添加健康检查,让Logstash和Kibana等待其就绪后再启动:
修改docker-compose.yml的Elasticsearch服务配置:
Elasticsearch: image: elasticsearch:8.5.3 container_name: elasticsearch restart: always volumes: - elastic_data:/usr/share/elasticsearch/data/ environment: ES_JAVA_OPTS: "-Xmx750m -Xms750m" discovery.type: single-node xpack.security.enabled: false ports: - '9200:9200' - '9300:9300' networks: - elk healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:9200/_cluster/health | grep -q '\"status\":\"green\"'"] interval: 10s timeout: 10s retries: 5
同时修改Logstash和Kibana的depends_on,添加健康检查依赖:
Logstash: # ... 其他配置 ... depends_on: Elasticsearch: condition: service_healthy Kibana: # ... 其他配置 ... depends_on: Elasticsearch: condition: service_healthy
4. Filebeat配置补充(避免ILM冲突)
由于我们使用自定义索引,禁用Filebeat的索引生命周期管理(ILM),避免自动创建的数据流干扰:
修改filebeat/filebeat.yml,添加以下配置:
setup.ilm.enabled: false setup.template.enabled: false # 禁用自动模板,由Logstash或Elasticsearch管理
验证步骤
- 停止所有容器:
docker-compose down -v(-v会删除存储卷,重置Elasticsearch状态) - 重新启动容器:
docker-compose up -d - 查看Logstash日志,确认有数据输出:
docker logs -f logstash - 访问Elasticsearch查看索引:
curl http://localhost:9200/_cat/indices,应该能看到logstash-YYYY.MM.dd格式的索引 - 打开Kibana(http://localhost:5601),添加索引模式
logstash-*,即可看到数据
内容的提问来源于stack exchange,提问作者Macsh

