3. ELK 栈基础:Elasticsearch、Logstash、Kibana 版本选择与安装(Docker 部署)

讲 ELK 栈,版本选择是第一道坎。我见过太多人在这上面翻车——花半天排错,最后发现是版本不匹配。说白了,Elasticsearch、Logstash、Kibana 这哥仨必须用同一个大版本号,差一位小版本都可能出幺蛾子。

3.1 版本选择:别掉进兼容性陷阱

Elastic 官方维护着一个版本兼容性矩阵。我直接给你最省心的方案:统一使用 7.17.x 或者 8.x 的最新稳定版。7.17 是 7 系列的最后一个 LTS 版本,支持到 2024 年底;8.x 已经非常成熟,推荐新项目直接上。我自己在产线用 8.10 跑了半年,没出过兼容问题。

另外注意一点:Logstash 的 input 插件、output 插件版本。比如你用 logstash-input-beats 插件,它跟 Elasticsearch 版本也有耦合。你想想看,这些细节如果漏掉,数据流就断了。

关键原则:三大组件的 major.minor 必须一致。比如 ES 7.17.10,那 Logstash 和 Kibana 也必须选 7.17.10。

下面这张表列出我推荐的生产版本组合,你直接照着选就行:

场景 Elasticsearch Logstash Kibana
稳定生产(推荐) 7.17.28 7.17.28 7.17.28
新项目(8.x) 8.15.3 8.15.3 8.15.3
学习测试 8.10.0 8.10.0 8.10.0

我的经验:曾经有一次我在 7.10 的集群里强行塞了一个 7.16 的 Logstash 实例,结果日志采集正常,但 Kibana 的监控仪表盘一直报「版本不兼容」——最后发现 Logstash 写入 ES 时用的 pipeline 版本不同。从那以后我养成了习惯:先查官方兼容矩阵再动手。

3.2 环境准备:Docker 与 Docker Compose

用 Docker 部署 ELK 是最优雅的方式。当然前提是你已经装好了 Docker 和 Docker Compose。我个人习惯用 Docker Compose v2,命令是 docker compose(注意没有横杠)。

这里有个容易忽略的点:Elasticsearch 需要大量内存。我建议给 ES 容器至少分配 2GB 堆内存,否则启动就 OOM。怎么配置?看下面:

  • 宿主机内存 ≥ 4GB(最好 8GB 以上)
  • Docker 磁盘改用高性能 SSD,ES 的索引写入很吃 I/O
  • 打开系统 vm.max_map_count:sysctl -w vm.max_map_count=262144,否则 ES 会报错退出

避坑:我曾经在一台 2GB 内存的云服务器上跑 ELK 全栈,ES 启动后直接 OOM 被 Docker 杀死。后来才发现单机至少要 4GB 内存才能稳定跑。如果你资源紧张,可以只启 ES + Kibana,Logstash 单独放另一台机器或者用更轻量的 Filebeat 替代。

3.3 Docker Compose 编排文件

直接上配置文件。我用的是 8.15.3 版本,你如果换成其他版本,改 tag 就行。

version: '3.8'

services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.15.3
    container_name: es01
    environment:
      - cluster.name=secrets-audit-cluster
      - node.name=es01
      - discovery.type=single-node
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms2g -Xmx2g"
      - xpack.security.enabled=true
      - xpack.security.authc..enabled=true
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - es_data:/usr/share/elasticsearch/data
    ports:
      - "9200:9200"
      - "9300:9300"
    networks:
      - elk-net

  logstash:
    image: docker.elastic.co/logstash/logstash:8.15.3
    container_name: logstash01
    environment:
      - LS_JAVA_OPTS=-Xms1g -Xmx1g
    volumes:
      - ./logstash/pipeline:/usr/share/logstash/pipeline
      - ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml
    ports:
      - "5044:5044"
      - "9600:9600"
    depends_on:
      - elasticsearch
    networks:
      - elk-net

  kibana:
    image: docker.elastic.co/kibana/kibana:8.15.3
    container_name: kibana01
    environment:
      - SERVER_NAME=kibana
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
      - XPACK_ENCRYPTEDSAVEDOBJECTS_ENCRYPTIONKEY=abc123xyz789
    ports:
      - "5601:5601"
    depends_on:
      - elasticsearch
    networks:
      - elk-net

volumes:
  es_data:
    driver: local

networks:
  elk-net:
    driver: bridge

解释几个关键点:

  • discovery.type=single-node:单节点模式,适合初学者。产线要用多节点集群。
  • xpack.security.enabled=true:开启安全认证,生产必开。8.x 默认就是开启的,初次启动会自动生成密码和 kibana_system 的 。
  • Logstash 的 pipeline 和配置你后续再写,这里先挂载空目录。
  • Kibana 需要 XPACK_ENCRYPTEDSAVEDOBJECTS_ENCRYPTIONKEY,否则保存仪表盘时会报错。我吃了亏才知道这个坑。

3.4 启动与验证

在 docker-compose.yml 同级目录下执行:

docker compose up -d

等待一两分钟,然后验证服务是否正常:

  1. 检查容器状态:docker compose ps,三个容器都应该是 Up 状态。
  2. 测试 ES 是否在线:curl -u elastic:生成的密码 http://localhost:9200。8.x 第一次启动会打印密码到日志里,用 docker logs es01 | grep "generated password" 获取。
  3. 访问 Kibana:浏览器打开 http://localhost:5601,用 elastic 用户登录。

如果 ES 启动失败,最常见原因是 vm.max_map_count 未设置。执行下面命令后重启容器:

sudo sysctl -w vm.max_map_count=262144
echo "vm.max_map_count=262144" >> /etc/sysctl.conf

小提示:你可能注意到我全程没提 Logstash 的配置文件。别急,第 4 章会专门讲 Logstash 的 Secrets 日志采集 pipeline 配置。这里只要把容器跑起来就行。

3.5 部署架构一览

下面这张图直观展示我们 Docker 部署的 ELK 三层结构。数据流从左到右:Secrets 审计日志 → Logstash 清洗 → Elasticsearch 存储 → Kibana 展示。注意,所有容器都在同一个 Docker bridge 网络 elk-net 里。

ELK Docker 部署架构(单节点) Secrets 审计日志 (Filebeat / Raw logs) Logstash 端口 5044 / 9600 Elasticsearch 端口 9200 / 9300 Kibana 端口 5601 网络与依赖 所有容器共用 elk-net 网络 Logstash depends_on ES Kibana depends_on ES

嗯,这张图就是我们的部署蓝图。注意 Kibana 不直接连 Logstash,它只读 ES 里的索引数据。Logstash 从外部接收审计日志(比如通过 beats 协议或直接读文件),处理后写入 ES。

另外提一句:生产环境中,你会给每个容器配独立的持久化卷、资源限制,甚至用 Docker Swarm 或 Kubernetes 编排。但今天我们先把单机跑通再说,后面章节再逐步扩展。