- 文档/教程
【免费下载链接】90DaysOfDevOps
This repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.
本文以 90DaysOfDevOps 仓库中 elasticsearch-logstash-kibana 示例为主线,完整讲解如何用一条docker-compose up -d命令在单节点上拉起 Elasticsearch、Logstash、Kibana 三件套(ELK),并配合 Logstash pipeline 实时解析 Nginx JSON 日志、写入 Elasticsearch、最终在 Kibana 中检索与可视化。读完本文,你将掌握 ELK 的组件职责、Compose 编排要点、Logstash 管道配置语法以及整套栈的启动、验证与清理流程。
ELK 是什么:三个组件各司其职
ELK 是 Elasticsearch、Logstash、Kibana 三个开源组件的合称,是一套经典的日志聚合与分析方案。仓库的 day79.md 对它的协作关系做了很直观的描述:
- Logstash负责从各类来源采集日志,并从原始消息中"抽取"结构化字段(如时间、用户、动作),把一行文本拆成带标签的对象;
- Logstash 本身不存储数据,它把处理结果写入Elasticsearch——一个擅长全文检索与文本查询的存储引擎;
- Kibana是连接 Elasticsearch 的 Web 服务,运维或值班工程师通过它在浏览器里检索日志、排查生产故障。
三者串联起来就形成了一条完整的数据流水线:日志源 → Logstash(采集/解析)→ Elasticsearch(存储/索引/检索)→ Kibana(展示/搜索)。这也是 day80.md 所展开的 ELK Stack 主题在仓库中的最小可运行落地形态。
项目结构:一个 Compose 文件 + 一条 Logstash 管道
本示例位于 2022/Days/Containers/elasticsearch-logstash-kibana/,整体结构如下:
. └── docker-compose.yml # 编排 elasticsearch / logstash / kibana 三个服务 └── logstash/ └── pipeline/ └── logstash-nginx.config # Logstash 管道配置:读取 Nginx 日志并写入 ESREADME 中声明的结构只包含docker-compose.yml,仓库实际还附带了 Logstash 管道文件 logstash-nginx.config。整个示例被 day46.md 明确引用:"In the above repository, there is a great example which will deploy an Elasticsearch, Logstash, and Kibana (ELK) in single-node",即一个可在单节点上直接运行的 ELK 最小示例。
docker-compose.yml 逐服务解读
完整配置见 docker-compose.yml,三个服务共享同一个elastic桥接网络,编排关系为kibana → elasticsearch、logstash → elasticsearch。
Elasticsearch 服务
services: elasticsearch: image: elasticsearch:7.16.1 container_name: es environment: discovery.type: single-node ES_JAVA_OPTS: "-Xms512m -Xmx512m" ports: - "9200:9200" - "9300:9300" healthcheck: test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"] interval: 10s timeout: 10s retries: 3 networks: - elastic关键参数说明:
image: elasticsearch:7.16.1:当前仓库实际使用的镜像版本。注意 README 中的示例输出显示的是 7.8.0(历史版本),仓库的 Compose 文件已更新为 7.16.1,部署时以仓库文件为准。discovery.type: single-node:以单节点模式启动,跳过生产模式的 bootstrap 检查,是单机学习/演示的标配设置。仓库中 Monitoring/Elastic Stack 的扩展示例也使用了同样的discovery.type: single-node来"disable production mode and avoid bootstrap checks"。ES_JAVA_OPTS: "-Xms512m -Xmx512m":固定 JVM 堆为 512MB,防止容器占用宿主机过多内存。- 端口映射:
9200为 REST 接口,9300为节点间传输端口。 healthcheck:每 10 秒请求一次/_cluster/health,失败重试 3 次即判定不健康。这是本示例比普通 Compose 模板更细致的地方——它让docker ps能直接显示 Elasticsearch 的(healthy)状态(README 的示例输出中es容器就处于Up 42 seconds (healthy))。
Logstash 服务
logstash: image: logstash:7.16.1 container_name: log environment: discovery.seed_hosts: logstash LS_JAVA_OPTS: "-Xms512m -Xmx512m" volumes: - ./logstash/pipeline/logstash-nginx.config:/usr/share/logstash/pipeline/logstash-nginx.config - ./logstash/nginx.log:/home/nginx.log ports: - "5000:5000/tcp" - "5000:5000/udp" - "5044:5044" - "9600:9600" depends_on: - elasticsearch networks: - elastic command: logstash -f /usr/share/logstash/pipeline/logstash-nginx.config关键参数说明:
- 两个挂载点:管道配置文件挂载到容器内
/usr/share/logstash/pipeline/目录;日志文件./logstash/nginx.log挂载到容器内/home/nginx.log,供管道读取。 command: logstash -f ...:显式指定用-f加载管道配置文件启动 Logstash。若不用该命令,Logstash 默认也会扫描/usr/share/logstash/pipeline/下的.conf文件,但这里的写法让启动行为更明确。- 端口映射:
5000(TCP/UDP,预留的数据接入端口)、5044(Beats 输入端口)、9600(Logstash 自身监控 API 端口)。 depends_on:等待 Elasticsearch 服务先启动。
Kibana 服务
kibana: image: kibana:7.16.1 container_name: kib ports: - "5601:5601" depends_on: - elasticsearch networks: - elasticKibana 只暴露5601一个端口,依赖 Elasticsearch。启动后它会自动连接同一网络中的 Elasticsearch(默认通过elasticsearch服务名解析)。
网络
networks: elastic: driver: bridge三个服务全部挂在名为elastic的自定义 bridge 网络上,容器之间通过服务名(es、logstash、kibana)互相解析。这也是 Logstash 管道里能直接写hosts => ["http://es:9200"]的原因——es就是 elasticsearch 容器的container_name。
Logstash 管道配置:从 Nginx JSON 日志到 ES 索引
logstash-nginx.config 是整套示例的灵魂,它由三段标准 Logstash 配置节组成:
input { file { path => "/home/nginx.log" start_position => "beginning" sincedb_path => "/dev/null" } } filter { json { source => "message" } geoip { source => "remote_ip" } useragent { source => "agent" target => "useragent" } } output { elasticsearch { hosts => ["http://es:9200"] index => "nginx" } stdout { codec => rubydebug } }input:文件输入
path => "/home/nginx.log":对应 Compose 中的挂载点./logstash/nginx.log:/home/nginx.log。README 的 Attribution 说明该 Nginx 示例日志来源于上游的 Nginx JSON 日志示例(仓库内未附带此日志文件,运行前需按 README 说明自行准备一份 JSON 格式的 Nginx 日志放到logstash/nginx.log)。start_position => "beginning":从文件开头读取。sincedb_path => "/dev/null":每次启动都从零开始读取,方便反复演示——因为 sincedb 被指向/dev/null,Logstash 不会记录上次读取的偏移量。
filter:三层解析链
管道依次执行三个过滤器,把一行 JSON 日志变成结构化的可检索文档:
json { source => "message" }:把整条消息按 JSON 解析,拆出remote_ip、agent等顶层字段;geoip { source => "remote_ip" }:基于客户端 IP 做地理定位,自动补充经纬度、国家、城市等地理字段;useragent { source => "agent" target => "useragent" }:解析 User-Agent 字符串,拆出浏览器、操作系统、设备类型等信息,并写入useragent字段。
这组过滤器正是 ELK "把非结构化日志变为可搜索结构化数据"的核心价值体现,与 day79.md 描述的"Logstash 抽取 time/message/user 作为标签以便搜索"完全对应。
output:双输出
elasticsearch { hosts => ["http://es:9200"] index => "nginx" }:写入 Elasticsearch 的nginx索引(es:9200即同一网络内的 elasticsearch 容器)。stdout { codec => rubydebug }:同时在容器标准输出打印带字段结构的调试信息,便于观察解析结果——docker logs log即可看到。
部署与验证:一条命令拉起整套栈
在 2022/Days/Containers/elasticsearch-logstash-kibana/ 目录下执行:
$ docker-compose up -d Creating network "elasticsearch-logstash-kibana_elastic" with driver "bridge" Creating es ... done Creating log ... done Creating kib ... doneREADME 给出的预期输出显示网络名elasticsearch-logstash-kibana_elastic由目录名派生,三个容器依次以es、log、kib命名创建成功。
检查容器状态与端口映射
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 173f0634ed33 logstash:7.8.0 "/usr/local/bin/dock…" 43 seconds ago Up 41 seconds 0.0.0.0:5000->5000/tcp, 0.0.0.0:5044->5044/tcp, 0.0.0.0:9600->9600/tcp, 0.0.0.0:5000->5000/udp log b448fd3e9b30 kibana:7.8.0 "/usr/local/bin/dumb…" 43 seconds ago Up 42 seconds 0.0.0.0:5601->5601/tcp kib 366d358fb03d elasticsearch:7.8.0 "/tini -- /usr/local…" 43 seconds ago Up 42 seconds (healthy) 0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp es(上表为 README 中的 7.8.0 版本示例输出,当前仓库 Compose 已使用 7.16.1,端口映射保持不变。)
三个容器的端口映射一览:
| 服务 | 容器名 | 暴露端口 | 用途 |
|---|---|---|---|
| elasticsearch | es | 9200 / 9300 | REST API / 节点传输,并带健康检查状态 |
| logstash | log | 5000 (tcp+udp)、5044、9600 | 数据接入 / Beats 输入 / 监控 API |
| kibana | kib | 5601 | Web 界面 |
浏览器访问验证
启动完成后,在浏览器中分别访问:
- Elasticsearch:
http://localhost:9200(可看到集群名称、版本等 JSON 信息) - Logstash:
http://localhost:9600(监控 API,返回运行状态) - Kibana:
http://localhost:5601/api/status(README 指定的状态接口,可确认 Kibana 与 ES 的连接状态)
数据流验证:从日志文件到 Kibana 可视化
整套流水线的验证路径可以这样走通:
- 将 JSON 格式的 Nginx 日志放入 logstash/nginx.log(挂载到容器
/home/nginx.log); - Logstash 按
start_position => "beginning"从头读取,经json/geoip/useragent解析后写入nginx索引; - 用
docker logs log查看 rubydebug 输出确认解析字段; - 在 Kibana 的
http://localhost:5601创建nginx索引模式后,即可按remote_ip、useragent、地理位置等字段搜索与聚合。
停止与清理
$ docker-compose down该命令停止并移除三个容器及elastic网络。需要说明的是,本示例的 Compose 没有为 Elasticsearch 声明数据卷(相比仓库中 Monitoring/Elastic Stack 使用elasticsearch:/usr/share/elasticsearch/data:z持久化数据的做法),因此docker-compose down后数据不会保留,适合作为教学演示场景;如需持久化,可参考 Monitoring/Elastic Stack 中挂载命名卷的写法。
进一步学习:仓库中的 ELK 扩展资源
本示例是入门版,仓库还提供了更完整的实践素材:
- day79.md:从原理角度讲解 ELK 各组件在日志管理中的角色与协作流程;
- day80.md:ELK Stack 专项学习日;
- Monitoring/Elastic Stack:功能更完整的 ELK 编排,包含
setup初始化服务、.env密码管理、elasticsearch命名卷持久化、Filebeat/Metricbeat/APM Server/Curator 等扩展组件,以及 logstash.conf 中基于beats/tcp输入的带认证写入示例。
从单节点演示到生产级扩展,ELK 的每一步演进都可以在这个仓库中找到对应落地的配置参考。
- 文档/教程
【免费下载链接】90DaysOfDevOps
This repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.
相关推荐
Hugo 模板函数 math.Atan2 详解:双参数反正切与象限判定实战指南
Hugo 模板函数 math.Atan2 详解:双参数反正切与象限判定实战指南 math.Atan2 是 Hugo 模板引擎 math 命名空间下用于计算双参数
文档/教程awesome-compose 实战:用 Docker Compose 一键搭建单节点 Elasticsearch、Logstash、Kibana(ELK)日志分析栈
awesome compose 实战:用 Docker Compose 一键搭建单节点 Elasticsearch、Logstash、Kibana(ELK)日志
示例工程90DaysOfDevOps 的 ELK 日志栈扩展:用 Logspout 将 Docker 容器日志零配置转发至 Logstash
90DaysOfDevOps 的 ELK 日志栈扩展:用 Logspout 将 Docker 容器日志零配置转发至 Logstash 在 90DaysOfDev
文档/教程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考