Elk

概述

ELK 是一套由 Elasticsearch、Logstash 和 Kibana 组成的开源工具栈,用于日志的搜索、分析和可视化展示。

组件 功能
Elasticsearch 分布式搜索和分析引擎,负责日志数据的存储与检索
Logstash 日志采集与处理管道,负责数据的过滤、转换和传输
Kibana 数据可视化平台,提供图表展示和交互式查询界面

部署准备

1. 创建数据目录

mkdir data plugins
chmod 777 data plugins

2. 创建 Elasticsearch 配置文件

elasticsearch.yml

network.host: 0.0.0.0

3. 创建 ES JVM 配置文件

es-jvm.options

-Xms1g
-Xmx1g
8-13:-XX:+UseConcMarkSweepGC
8-13:-XX:CMSInitiatingOccupancyFraction=75
8-13:-XX:+UseCMSInitiatingOccupancyOnly
14-:-XX:+UseG1GC
14-:-XX:G1ReservePercent=25
14-:-XX:InitiatingHeapOccupancyPercent=30
-Djava.io.tmpdir=${ES_TMPDIR}
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=data
-XX:ErrorFile=logs/hs_err_pid%p.log
8:-XX:+PrintGCDetails
8:-XX:+PrintGCDateStamps
8:-XX:+PrintTenuringDistribution
8:-XX:+PrintGCApplicationStoppedTime
8:-Xloggc:logs/gc.log
8:-XX:+UseGCLogFileRotation
8:-XX:NumberOfGCLogFiles=32
8:-XX:GCLogFileSize=64m
9-:-Xlog:gc*,gc+age=trace,safepoint:file=logs/gc.log:utctime,pid,tags:filecount=32,filesize=64m

4. 创建 Kibana 配置文件

kibana.yml

server.name: kibana
server.host: "0"
elasticsearch.hosts: [ "http://elasticsearch:9200" ]
xpack.monitoring.ui.container.elasticsearch.enabled: true
i18n.locale: "zh-CN"

5. 创建 Kibana JVM 配置文件

kibana-jvm.options

-Xms1g
-Xmx1g
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=75
-XX:+UseCMSInitiatingOccupancyOnly
-Djava.awt.headless=true
-Dfile.encoding=UTF-8
-Djruby.compile.invokedynamic=true
-Djruby.jit.threshold=0
-Djruby.regexp.interruptible=true
-XX:+HeapDumpOnOutOfMemoryError
-Djava.security.egd=file:/dev/urandom
-Dlog4j2.isThreadContextMapInheritable=true

6. 创建 Logstash 配置文件

logstash.conf

input {
  beats {
    port => "5044"
  }
}
output {
  elasticsearch {
    hosts => ["http://elasticsearch:9200"]
    index => "test"
  }
  stdout { codec => rubydebug }
}

7. 创建 Docker Compose 编排文件

docker-compose.yaml

services:
  elasticsearch:
    image: elasticsearch:7.7.0
    container_name: elasticsearch
    restart: always
    environment:
      - "discovery.type=single-node"
      - "TZ=Asia/Shanghai"
    volumes:
      - ./data:/usr/share/elasticsearch/data
      - ./elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
      - ./es-jvm.options:/usr/share/elasticsearch/config/jvm.options
      - ./plugins:/usr/share/elasticsearch/plugins
    ports:
      - 9200:9200
      - 9300:9300
    deploy:
      resources:
        limits:
          cpus: "1"
          memory: "2G"

  kibana:
    image: kibana:7.7.0
    container_name: kibana
    restart: always
    depends_on:
      - elasticsearch
    environment:
      - i18n.locale=zh-CN
      - TZ=Asia/Shanghai
    volumes:
      - ./kibana.yml:/usr/share/kibana/config/kibana.yml
    ports:
      - 5601:5601
    deploy:
      resources:
        limits:
          cpus: "1"
          memory: "1G"

  logstash:
    image: logstash:7.7.0
    container_name: logstash
    restart: always
    volumes:
      - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
      - ./kibana-jvm.options:/usr/share/logstash/config/jvm.options
    ports:
      - 5044:5044
    environment:
      - TZ=Asia/Shanghai
    depends_on:
      - elasticsearch
    deploy:
      resources:
        limits:
          cpus: "1"
          memory: "1G"

启动服务

docker compose up -d

查看容器运行状态:

docker compose ps

验证访问

# 验证 Elasticsearch
curl http://127.0.0.1:9200

# 验证 Kibana
curl http://127.0.0.1:5601

在浏览器中打开 http://<服务器IP>:5601 即可访问 Kibana 界面。


安全配置(设置密码)

步骤一:修改 Elasticsearch 配置

elasticsearch.yml 中添加以下内容:

# 开启 X-Pack 安全认证
xpack.security.enabled: true

# 关闭 SSL 证书校验(7.7.0 版本必须配置,否则启动失败)
xpack.security.transport.ssl.enabled: false

# 允许远程访问
network.host: 0.0.0.0
discovery.type: single-node

步骤二:重启 Elasticsearch 并设置密码

# 重启 Elasticsearch 容器
docker compose restart elasticsearch

# 进入容器设置密码
docker exec -it elasticsearch /bin/bash
elasticsearch-setup-passwords interactive

按提示依次为以下用户设置密码:

用户 说明
elastic 超级管理员(必设,Kibana/Logstash 连接使用)
apm_system APM 系统用户
kibana Kibana 连接 ES 使用
logstash_system Logstash 监控用户
beats_system Beats 监控用户

建议:将所有密码统一设置为相同值,便于管理。

步骤三:配置 Kibana 密码

修改 kibana.yml,添加用户名和密码:

server.name: kibana
server.host: "0"
elasticsearch.hosts: [ "http://elasticsearch:9200" ]
xpack.monitoring.ui.container.elasticsearch.enabled: true
i18n.locale: "zh-CN"

# 配置 ES 认证
elasticsearch.username: "elastic"
elasticsearch.password: "你设置的ES密码"

# 开启 Kibana 登录认证
xpack.security.enabled: true

步骤四:配置 Logstash 密码

修改 logstash.conf,在 output 中添加认证信息:

input {
  beats {
    port => "5044"
  }
}
output {
  elasticsearch {
    hosts => ["http://elasticsearch:9200"]
    index => "log-%{+YYYY.MM.dd}"
    user => "elastic"
    password => "你设置的ES密码"
  }
  stdout { codec => rubydebug }
}

步骤五:重启所有服务

docker compose restart

Logstash 高级配置示例

以下是一个完整的 Logstash 配置示例,包含日志解析、字段处理和性能优化:

input {
  beats {
    port => 5044
  }
}

filter {
  # 解析日志行,提取时间戳和其他字段
  grok {
    match => {
      "message" => "^<(?<log_level>\d+)> %{TIMESTAMP_ISO8601:log_timestamp} \[%{LOGLEVEL:log_level_str}\] %{IP:client_ip} #%{NUMBER:connection_id} \[%{DATA:api_path}\] \[%{DATA:api_response}\] %{NUMBER:response_time}ms (?<json_data>{.*})$"
    }
    tag_on_failure => ["_grokparsefailure"]
  }

  # 将日志时间戳设置为 @timestamp
  date {
    match => ["log_timestamp", "yyyy-MM-dd HH:mm:ss"]
    target => "@timestamp"
    timezone => "Asia/Shanghai"
    locale => "zh_CN"
    tag_on_failure => ["_dateparsefailure"]
  }

  # 如果日期解析失败,使用当前时间作为备选
  if "_dateparsefailure" in [tags] {
    mutate {
      remove_tag => ["_dateparsefailure"]
      add_tag => ["timestamp_fallback"]
    }
    date {
      match => ["@timestamp", "ISO8601"]
      timezone => "Asia/Shanghai"
    }
  }

  # 添加计算字段
  mutate {
    add_field => {
      "api_performance" => "%{response_time}"
      "status" => "%{response_time}"
    }
  }

  # 清理冗余字段,减少存储开销
  mutate {
    remove_field => [
      "[beat][hostname]",
      "[beat][name]",
      "[beat][version]",
      "[message]"
    ]
  }
}

output {
  elasticsearch {
    hosts => ["127.0.0.1:9200"]
    index => "%{index}-%{+YYYY-MM-dd}"
    user => "elastic"
    password => "aaabbbccc"
  }
}

常用管理命令

操作 命令
启动所有服务 docker compose up -d
停止所有服务 docker compose stop
重启所有服务 docker compose restart
查看容器状态 docker compose ps
查看日志 docker compose logs -f --tail=100
查看 Elasticsearch 日志 docker logs elasticsearch -f --tail=50
查看 Kibana 日志 docker logs kibana -f --tail=50
查看 Logstash 日志 docker logs logstash -f --tail=50
进入 Elasticsearch 容器 docker exec -it elasticsearch /bin/bash

常见问题

Q:Elasticsearch 启动失败,提示内存不足?

检查 JVM 堆内存配置是否超过宿主机可用内存:

# 查看宿主机内存
free -h

# 修改 es-jvm.options 中的 -Xms 和 -Xmx 参数
# 建议设置为宿主机内存的 50%,且不超过 32G

Q:Kibana 无法连接到 Elasticsearch?

  1. 确认 Elasticsearch 已完全启动:
curl http://127.0.0.1:9200
  1. 检查 elasticsearch.hosts 配置是否正确:
elasticsearch.hosts: [ "http://elasticsearch:9200" ]  # 容器内部使用服务名
# 或
elasticsearch.hosts: [ "http://127.0.0.1:9200" ]     # 宿主机访问
  1. 如已开启认证,确认用户名密码配置正确。

Q:Logstash 无法向 Elasticsearch 写入数据?

  1. 检查 Elasticsearch 是否正常运行
  2. 确认认证信息(user/password)是否正确
  3. 查看 Logstash 日志排查错误:
docker logs logstash --tail=100

Q:如何升级 ELK 版本?

  1. 修改 docker-compose.yaml 中的镜像版本号(三个组件版本需保持一致)
  2. 备份 Elasticsearch 数据目录 ./data
  3. 执行 docker compose down 停止服务
  4. 执行 docker compose up -d 启动新版本
  5. 如遇索引兼容性问题,需执行数据迁移或重建索引

Q:Beats 如何配置输出到 Logstash?

在 Filebeat/Metricbeat 的配置文件中设置:

output.logstash:
  hosts: ["<Logstash_IP>:5044"]

参考链接