拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

90DaysOfDevOps 实践:使用 Docker Compose 一键部署单节点 Elasticsearch + Logstash + Kibana(ELK)日志分析栈

90DaysOfDevOps 实践:使用 Docker Compose 一键部署单节点 Elasticsearch + Logstash + Kibana(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.

项目地址:https://gitcode.com/gh_mirrors/90/90DaysOfDevOps
点击查看免费下载

本文以 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 日志并写入 ES

README 中声明的结构只包含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: - elastic

Kibana 只暴露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 日志变成结构化的可检索文档:

  1. json { source => "message" }:把整条消息按 JSON 解析,拆出remote_ip、agent等顶层字段;
  2. geoip { source => "remote_ip" }:基于客户端 IP 做地理定位,自动补充经纬度、国家、城市等地理字段;
  3. 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 ... done

README 给出的预期输出显示网络名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,端口映射保持不变。)

三个容器的端口映射一览:

服务容器名暴露端口用途
elasticsearches9200 / 9300REST API / 节点传输,并带健康检查状态
logstashlog5000 (tcp+udp)、5044、9600数据接入 / Beats 输入 / 监控 API
kibanakib5601Web 界面

浏览器访问验证

启动完成后,在浏览器中分别访问:

  • Elasticsearch:http://localhost:9200(可看到集群名称、版本等 JSON 信息)
  • Logstash:http://localhost:9600(监控 API,返回运行状态)
  • Kibana:http://localhost:5601/api/status(README 指定的状态接口,可确认 Kibana 与 ES 的连接状态)

数据流验证:从日志文件到 Kibana 可视化

整套流水线的验证路径可以这样走通:

  1. 将 JSON 格式的 Nginx 日志放入 logstash/nginx.log(挂载到容器/home/nginx.log);
  2. Logstash 按start_position => "beginning"从头读取,经json/geoip/useragent解析后写入nginx索引;
  3. 用docker logs log查看 rubydebug 输出确认解析字段;
  4. 在 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.

项目地址:https://gitcode.com/gh_mirrors/90/90DaysOfDevOps
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

返回列表