2、环境搭建:ELK Stack 安装与配置、Grafana + Loki 轻量级方案

好,咱们直接进入正题。做日志分析,第一步就是把环境搭起来。我见过不少团队,方案选得天花乱坠,结果装到一半卡住了,或者跑起来发现资源吃紧。说白了,工具是拿来用的,不是拿来供着的。

这一章,我带你走两条路:一条是经典的 ELK Stack,功能全面,适合中大型团队;另一条是 Grafana + Loki 的轻量级组合,适合小团队或个人折腾。两条路我都会给出具体的安装步骤和配置要点。

核心思路: 不管选哪条路,都要保证日志能「收得进来、存得下去、查得出来」。别一开始就追求花哨的图表,先把管道打通。

2.1 ELK Stack:经典三件套

ELK 指的是 Elasticsearch、Logstash、Kibana。我最早接触这套组合是在 2016 年,当时公司要统一管理上百台服务器的应用日志。说实话,第一次搭的时候踩了不少坑,尤其是版本兼容性问题——Elasticsearch 和 Logstash 的版本必须严格匹配,否则连不上。

2.1.1 Elasticsearch 安装

Elasticsearch 是整个栈的核心,负责存储和检索。我个人习惯用 tar 包安装,这样便于控制版本和目录结构。

# 下载并解压(以 7.17.x 为例)
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.10-linux-x86_64.tar.gz
tar -xzf elasticsearch-7.17.10-linux-x86_64.tar.gz
cd elasticsearch-7.17.10/

然后修改配置文件 config/elasticsearch.yml

# 集群名称,同一集群内必须一致
cluster.name: my-logs-cluster

# 节点名称,建议用主机名
node.name: node-1

# 监听地址,生产环境建议内网 IP
network.host: 0.0.0.0

# HTTP 端口
http.port: 9200

# 发现配置,单节点用 localhost
discovery.seed_hosts: ["127.0.0.1"]
cluster.initial_master_nodes: ["node-1"]

注意: Elasticsearch 默认不能用 root 用户启动。我曾经因为这个折腾了半小时,后来才发现需要创建一个专用用户。建议用 adduser esuser 创建,然后 chown -R esuser:esuser elasticsearch-7.17.10/

启动命令很简单:

# 切换到 esuser 用户
su esuser
./bin/elasticsearch -d -p pid

验证是否启动成功:

curl http://localhost:9200
# 返回类似以下内容表示成功
{
  "name" : "node-1",
  "cluster_name" : "my-logs-cluster",
  "version" : { "number" : "7.17.10" }
}

2.1.2 Logstash 安装与配置

Logstash 负责日志的采集和解析。说白了,它就是个管道工——把各种格式的日志(JSON、文本、CSV)转成统一的结构化数据。

# 下载解压
wget https://artifacts.elastic.co/downloads/logstash/logstash-7.17.10-linux-x86_64.tar.gz
tar -xzf logstash-7.17.10-linux-x86_64.tar.gz
cd logstash-7.17.10/

创建一个配置文件 config/logstash-simple.conf

input {
  # 从文件读取日志
  file {
    path => "/var/log/myapp/*.log"
    start_position => "beginning"
    sincedb_path => "/dev/null"
  }
}

filter {
  # 解析 JSON 格式日志
  if [message] =~ /^{/ {
    json {
      source => "message"
    }
  }
  # 添加时间戳
  date {
    match => ["timestamp", "ISO8601"]
  }
}

output {
  elasticsearch {
    hosts => ["localhost:9200"]
    index => "myapp-logs-%{+YYYY.MM.dd}"
  }
  stdout { codec => rubydebug }
}

启动 Logstash:

./bin/logstash -f config/logstash-simple.conf

小技巧: 调试阶段建议加上 stdout { codec => rubydebug },这样能在控制台看到解析后的结果。我每次写新 filter 都会先这么干,确认没问题再去掉。

2.1.3 Kibana 安装

Kibana 是可视化层,负责展示数据。安装最简单:

wget https://artifacts.elastic.co/downloads/kibana/kibana-7.17.10-linux-x86_64.tar.gz
tar -xzf kibana-7.17.10-linux-x86_64.tar.gz
cd kibana-7.17.10/

修改 config/kibana.yml

server.port: 5601
server.host: "0.0.0.0"
elasticsearch.hosts: ["http://localhost:9200"]
kibana.index: ".kibana"

启动:

./bin/kibana &

访问 http://你的IP:5601,看到登录页面就说明成功了。第一次进去需要创建索引模式(Index Pattern),比如 myapp-logs-*,然后就能在 Discover 里查日志了。

2.2 Grafana + Loki:轻量级方案

ELK 虽好,但资源消耗确实不小。我记得有一次给一个创业公司搭日志系统,他们只有两台 4C8G 的服务器,ELK 跑起来直接吃掉 60% 的内存。后来我换成了 Grafana + Loki,瞬间就轻松了。

Loki 的设计理念和 Elasticsearch 完全不同。它不建立全文索引,而是只对标签(labels)做索引,日志内容直接压缩存储。你想想看,对于大多数排查场景,我们其实只需要按服务名、主机名、时间范围来查日志,很少会去搜某个关键词。Loki 正好迎合了这个需求。

2.2.1 Loki 安装

Loki 官方推荐用 Docker 部署,但二进制安装也很简单:

# 下载 Loki 和 Promtail(日志采集器)
wget https://github.com/grafana/loki/releases/download/v2.9.0/loki-linux-amd64.zip
wget https://github.com/grafana/loki/releases/download/v2.9.0/promtail-linux-amd64.zip
unzip loki-linux-amd64.zip
unzip promtail-linux-amd64.zip

创建 Loki 配置文件 loki-config.yaml

auth_enabled: false

server:
  http_listen_port: 3100

ingester:
  lifecycler:
    ring:
      kvstore:
        store: inmemory
      replication_factor: 1
  chunk_idle_period: 5m
  chunk_retain_period: 30s

schema_config:
  configs:
    - from: 2020-10-24
      store: boltdb-shipper
      object_store: filesystem
      schema: v11
      index:
        prefix: index_
        period: 24h

storage_config:
  boltdb_shipper:
    active_index_directory: /tmp/loki/index
    cache_location: /tmp/loki/cache
    shared_store: filesystem
  filesystem:
    directory: /tmp/loki/chunks

启动 Loki:

./loki-linux-amd64 -config.file=loki-config.yaml &

2.2.2 Promtail 配置

Promtail 负责采集日志并推送给 Loki。配置如下:

# promtail-config.yaml
server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /tmp/positions.yaml

clients:
  - url: http://localhost:3100/loki/api/v1/push

scrape_configs:
  - job_name: system
    static_configs:
      - targets: [localhost]
        labels:
          job: varlogs
          __path__: /var/log/*.log

启动 Promtail:

./promtail-linux-amd64 -config.file=promtail-config.yaml &

2.2.3 Grafana 接入 Loki

Grafana 的安装我就不多说了,官网下载解压就能跑。关键是配置数据源:

  1. 打开 Grafana(默认端口 3000,账号 admin/admin)
  2. 进入 Configuration → Data Sources → Add data source
  3. 选择 Loki,URL 填 http://localhost:3100
  4. 点击 Save & Test,看到绿色提示就成功了

然后你就可以在 Explore 页面用 LogQL 查询日志了。比如:

{job="varlogs"} |= "error"

这条语句的意思是:在 job 为 varlogs 的日志流中,搜索包含 "error" 的行。简洁吧?

2.3 两种方案对比

我整理了一张对比表,方便你根据实际情况选择:

维度 ELK Stack Grafana + Loki
资源消耗 高(内存大户) 低(压缩存储)
查询能力 全文检索、聚合分析 标签过滤 + 内容搜索
部署复杂度 中等(三个组件) 简单(两个组件)
适用场景 复杂分析、长期存储 实时排查、轻量运维
学习曲线 较陡(DSL 查询) 平缓(LogQL 简单)

我的建议: 如果你手头服务器资源充裕,团队有专职的运维人员,选 ELK 准没错。如果你是一个人管几十台机器,或者预算有限,Grafana + Loki 绝对够用。我现在的个人项目全用 Loki,省心。

2.4 核心架构图

下面这张图展示了两种方案的完整数据流。我特意把 Logstash 和 Promtail 放在同一层,方便对比:

日志采集架构对比 ELK Stack Grafana + Loki 应用日志文件 /var/log/*.log (JSON / 文本 / CSV) 应用日志文件 /var/log/*.log (JSON / 文本 / CSV) Logstash 解析、过滤、转换 Promtail 采集、打标签、推送 Elasticsearch 全文索引 + 聚合存储 Loki 标签索引 + 压缩存储 Kibana 可视化仪表盘 Grafana 统一监控面板 数据流方向:日志文件 → 采集器 → 存储引擎 → 可视化工具

2.5 避坑指南

环境搭完了,但有些坑我得提前跟你说。这些都是我亲身经历过的:

  • 版本匹配问题: 我曾经把 Elasticsearch 7.10 和 Logstash 7.17 搭在一起,结果 Logstash 死活连不上 ES。后来才发现大版本必须一致,小版本可以向下兼容。建议统一用同一个大版本的最新小版本。
  • 磁盘空间预警: Elasticsearch 默认的 watermark 阈值是 85%,一旦磁盘使用率超过这个值,ES 会自动把索引设为只读。我遇到过半夜报警,爬起来清理索引的惨痛经历。建议提前设置好 ILM(索引生命周期管理),自动删除过期数据。
  • Loki 的标签设计: Loki 的查询性能严重依赖标签设计。标签太多会导致索引膨胀,太少又查不准。我的经验是:保留 jobhostlevel(日志级别)三个标签就够了,其他信息放在日志内容里。
  • 时区问题: 默认情况下,Kibana 和 Grafana 都使用 UTC 时间。如果你在国内,记得在设置里把时区改成 Asia/Shanghai,否则查日志时总得在脑子里做加减法,很别扭。

最后说一句: 环境搭建只是第一步,别在上面花太多时间。我见过有人折腾了一周,就为了把 ELK 调得完美无缺,结果业务日志还没开始分析。先跑起来,再优化,这才是 SRE 的务实作风。


公众号:蓝海资料掘金营,微信deep3321