Docker 部署 Loki + Promtail + Grafana 日志监控栈

Docker 部署 Loki + Promtail + Grafana 日志监控栈

通过 Docker Compose 快速搭建日志集中采集与可视化平台,适配 auditd 审计日志场景。

架构概览

复制代码
宿主机
├── /var/log/syslog          ──┐
└── /var/log/audit/audit.log ──┤
                               ▼
                          Promtail(采集)
                               │
                               ▼
                          Loki(存储)
                               │
                               ▼
                          Grafana(可视化)
服务 镜像 端口 说明
Loki grafana/loki:2.9.4 3100 日志存储与查询引擎
Promtail grafana/promtail:2.9.4 9080 日志采集 agent
Grafana grafana/grafana:10.3.3 3000 可视化看板

目录结构

复制代码
loki-docker/
├── docker-compose.yml
└── config/
    ├── loki.yml                # Loki 主配置
    ├── promtail.yml            # Promtail 采集规则
    └── grafana-datasource.yml  # Grafana 数据源自动配置

配置文件说明

1. docker-compose.yml

yaml 复制代码
networks:
  loki:
    driver: bridge

services:
  # ─── Loki:日志存储 ───
  loki:
    image: grafana/loki:2.9.4
    container_name: loki
    ports:
      - "3100:3100"
    volumes:
      - ./config/loki.yml:/etc/loki/loki.yml
      - loki-data:/loki
    command: -config.file=/etc/loki/loki.yml
    networks:
      - loki
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "wget -q --spider http://localhost:3100/ready || exit 1"]
      interval: 10s
      timeout: 5s
      retries: 5

  # ─── Promtail:日志采集 ───
  promtail:
    image: grafana/promtail:2.9.4
    container_name: promtail
    hostname: ub-jack                   # ← 改为当前机器名
    ports:
      - "9080:9080"
    volumes:
      - ./config/promtail.yml:/etc/promtail/promtail.yml
      - /var/log:/var/log:ro            # 挂载宿主机日志(只读)
    command: -config.file=/etc/promtail/promtail.yml
    networks:
      - loki
    restart: unless-stopped
    depends_on:
      loki:
        condition: service_healthy

  # ─── Grafana:可视化 ───
  grafana:
    image: grafana/grafana:10.3.3
    container_name: grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=changeme123   # 上线前务必修改
      - GF_AUTH_ANONYMOUS_ENABLED=false
    volumes:
      - grafana-data:/var/lib/grafana
      - ./config/grafana-datasource.yml:/etc/grafana/provisioning/datasources/loki.yml
    networks:
      - loki
    restart: unless-stopped
    depends_on:
      loki:
        condition: service_healthy

volumes:
  loki-data:
  grafana-data:

⚠️ 多台机器部署时 ,每台机器只需修改 hostname: 为各自的机器名,其余配置不变。


2. config/loki.yml

yaml 复制代码
auth_enabled: false

server:
  http_listen_port: 3100
  grpc_listen_port: 9096

common:
  instance_addr: 127.0.0.1
  path_prefix: /loki
  storage:
    filesystem:
      chunks_directory: /loki/chunks
      rules_directory: /loki/rules
  replication_factor: 1
  ring:
    kvstore:
      store: inmemory

query_range:
  results_cache:
    cache:
      embedded_cache:
        enabled: true
        max_size_mb: 100

schema_config:
  configs:
    - from: 2024-01-01
      store: tsdb
      object_store: filesystem
      schema: v13
      index:
        prefix: index_
        period: 24h

limits_config:
  ingestion_rate_mb: 10
  ingestion_burst_size_mb: 20
  max_query_lookback: 720h    # 最长查询 30 天
  retention_period: 720h      # 日志保留 30 天

关键参数说明:

参数 说明
auth_enabled false 单机部署无需认证,多租户场景改为 true
retention_period 720h 日志保留 30 天,按需调整
ingestion_rate_mb 10 每秒最大写入速率(MB)
max_query_lookback 720h 查询历史最长范围

3. config/promtail.yml

yaml 复制代码
server:
  http_listen_port: 9080

positions:
  filename: /tmp/positions.yaml

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

scrape_configs:
  # ─── 采集 syslog(含 auditd via rsyslog) ───
  - job_name: syslog
    static_configs:
      - targets: [localhost]
        labels:
          job: syslog
          host: ${HOSTNAME}          # 自动读取容器 hostname
          __path__: /var/log/syslog
    pipeline_stages:
      - match:
          selector: '{job="syslog"}'
          stages:
            - regex:
                expression: '(?P<audit_type>type=[A-Z_]+)?.*(?P<audit_key>key="[^"]+")?'
            - labels:
                audit_type:
                audit_key:

  # ─── 采集 audit.log 原始文件 ───
  - job_name: auditd
    static_configs:
      - targets: [localhost]
        labels:
          job: auditd
          host: ${HOSTNAME}          # 自动读取容器 hostname
          __path__: /var/log/audit/audit.log
    pipeline_stages:
      - regex:
          expression: 'type=(?P<audit_type>[A-Z_]+).*(?:key="(?P<audit_key>[^"]+)")?'
      - labels:
          audit_type:
          audit_key:

pipeline_stages 说明:

  • regex:从日志行提取 audit_type(事件类型)和 audit_key(规则 key)
  • labels:将提取的字段设为 Loki 标签,在 Grafana 中可直接过滤

4. config/grafana-datasource.yml

yaml 复制代码
apiVersion: 1

datasources:
  - name: Loki
    type: loki
    access: proxy
    url: http://loki:3100
    isDefault: true
    jsonData:
      maxLines: 1000
      timeout: 60

此文件在 Grafana 启动时自动注册 Loki 数据源,无需手动添加。


部署步骤

前置条件

  • Docker >= 20.10
  • Docker Compose >= 2.0
  • 宿主机已安装并运行 auditd

第一步:克隆配置

bash 复制代码
# 将整个 loki-docker 目录上传到目标机器
scp -r loki-docker/ user@<服务器IP>:/opt/loki-docker

第二步:修改机器名

编辑 docker-compose.yml,将 hostname 改为当前机器名:

bash 复制代码
cd /opt/loki-docker
nano docker-compose.yml
# 找到 hostname: ub-jack,改为实际机器名

第三步:启动服务

bash 复制代码
docker compose up -d

第四步:验证服务状态

bash 复制代码
# 查看所有容器状态
docker compose ps

# 验证 Loki 就绪
curl http://localhost:3100/ready

# 验证 Promtail 正在推送日志
curl -s http://localhost:9080/metrics | grep promtail_sent_entries_total

期望输出:

复制代码
promtail_sent_entries_total{host="loki:3100"} 12345   ← 数值 > 0 即正常

访问 Grafana

浏览器打开:http://<服务器IP>:3000

项目 默认值
用户名 admin
密码 changeme123

⚠️ 登录后请立即修改密码:右上角头像 → Profile → Change Password


查询 auditd 日志(LogQL)

进入 Grafana → Explore → 选择 Loki 数据源:

logql 复制代码
# 查看所有 auditd 日志
{job="auditd"}

# 过滤指定主机
{job="auditd", host="ub-jack"}

# 查看 sudo 使用记录
{job="auditd"} |= "sudo_usage"

# 查看身份文件变更(/etc/passwd 等)
{job="auditd"} |= "identity"

# 查看登录事件
{job="auditd"} |= "USER_LOGIN"

# 统计各事件类型数量(近 5 分钟)
sum by (audit_key) (count_over_time({job="auditd"}[5m]))

常用运维命令

bash 复制代码
# 查看实时日志
docker compose logs -f

# 单独查看某个服务日志
docker logs grafana -f
docker logs loki -f
docker logs promtail -f

# 重启单个服务
docker compose restart promtail

# 停止所有服务
docker compose down

# 停止并清除数据卷(慎用,会删除所有日志数据)
docker compose down -v

多台机器部署

每台机器复制完整的 loki-docker 目录,只修改 docker-compose.yml 中的一处:

yaml 复制代码
# 机器 A
hostname: web-server-01

# 机器 B
hostname: db-server-01

# 机器 C
hostname: app-server-01

Loki 和 Grafana 只需部署在一台中央服务器上,其他机器只部署 Promtail 即可。


常见问题

问题 原因 解决方法
Grafana 启动失败(exit code 1) 数据目录权限不足 docker compose down -v && docker compose up -d
Promtail 连接不上 Loki Loki 未就绪 等待 Loki healthcheck 通过后 Promtail 自动重连
日志查询为空 采集路径不存在 确认 /var/log/audit/audit.log 在宿主机存在
host 标签显示为容器 ID 未设置 hostname 在 docker-compose.yml 中设置 hostname:
相关推荐
独自归家的兔3 小时前
2026年7月2日 Docker 容器化部署 PaddleOCR-VL 实战(OpenAI 协议兼容 HTTP 调用)
运维·docker·容器
胖胖雕4 小时前
利用阿里云与docker部署Certimate
阿里云·docker·云计算
kylin-运维4 小时前
k8s可视化看板嵌入AI助手(悬浮对话球)
人工智能·容器·kubernetes·aicoding
会飞的土拨鼠呀4 小时前
Docker 容器维护手册
docker·容器·eureka
慕伏白5 小时前
【慕伏白】Docker 常用指令
docker·容器·eureka
java_logo5 小时前
Docker 部署 Trilium Notes 完整教程:自建大型知识库
docker·容器·trilium·trilium note·trilium部署·docker部署trilium·trilium部署文档
myqijin5 小时前
Cloudflare Tunnel docker-compose.yml
docker
weixin_307779135 小时前
Linux下Docker Compose里运行PostgreSQL数据库故障诊断Shell脚本
linux·运维·数据库·docker·postgresql
梦想的颜色5 小时前
【Docker 原理】Docker 数据持久化完全指南:三种挂载原理、数据卷实操、数据库落地实战
docker·云原生·数据持久化·volume·数据卷·容器挂载