Loki 高可用 docker-compose 部署指南HA 单二进制模式、Minio 对象存储与多租户日志管道全解析【免费下载链接】lokiLike Prometheus, but for logs.项目地址: https://gitcode.com/GitHub_Trending/lok/loki本篇指南完整讲解 production/docker/ 目录下基于docker-compose的 Loki 一键部署方案它以HA 单二进制monolithic 独立 compactor架构运行 3 个 Loki 副本借助 Minio 提供 S3 兼容对象存储由 nginx 网关统一暴露读写路径并通过 Promtail flog 日志生成器构建端到端日志管道。读完本文你将掌握该 compose 栈中每个服务的职责、Loki 核心配置参数ring、memberlist、TSDB schema、ingester WAL 等的底层作用以及如何基于 delve 对容器内的 Loki 进行交互式断点调试。一、部署方案概览与核心特性production/docker/README.md中明确列出该 compose 栈的设计目标可用于开发环境也可用于生产环境。它围绕以下核心特性构建高可用单二进制部署Loki 以 HA monolithicloki-monolithic模式运行read/write目标各 3 个副本另有一个独立的loki-monolithic-compactor负责压缩与保留retention任务Memberlist 一致性哈希环副本之间通过 gossip 协议组成 hash ring实现数据分片与去重Minio 作为 S3 兼容存储chunks 与索引统一落盘到 Minio本地无需持久化存储nginx 反向代理网关统一暴露3100端口按路径将流量分发到读/写路径与 compactorPromtail 可选日志生成器flog生成并采集 JSON 格式日志多租户以docker作为 tenant ID所有日志带租户标识写入交互式调试支持构建带 delve 的 Loki 镜像并远程断点调试可观测闭环Prometheus 采集 Loki/Promtail 指标Grafana 预置 Loki 与 Prometheus 数据源。数据流架构README 用 mermaid 图描述了组件间的数据流动整理为如下关系Grafana 通过 nginx端口 8080实际 compose 栈为 3100查询日志Promtail 向 nginx 推送日志nginx 将读请求query路由到 query-frontend/querier将写请求路由到 distributor/ingesterquerier 与 ingester 分别读写 Minio 中的 chunks 与 indexes。Grafana / Promtail ── nginx 网关3100 ├── 读路径queryquery-frontend ── querier └── 写路径pushdistributor ── ingester │ querier / ingester ── Miniochunks indexes需要说明的是README 描述的是Simple Scalable Deployment简单可扩展模式的组件划分query-frontend/distributor/ingester/querier 等 target而当前仓库中 docker-compose.yaml 的实际实现采用HA 单二进制模式所有 target 集成在同一个二进制里通过 3 个loki-monolithic副本水平扩展另以 1 个副本的loki-monolithic-compactor独立承担 compactor 职责对应 README 中“3 replicas for read and write targets”。两种形态在概念上一一对应均可通过-target参数切换便于从开发栈平滑演进到微服务部署。二、快速启动一条命令拉起整套日志平台2.1 启动与初始化在 production/docker 目录下直接执行docker-compose up启动后需要数秒等待所有组件注册进 hash ring可在http://localhost:3100/ring观察。当所有实例状态变为ACTIVE后Loki 才开始接受读写请求。所有日志将以租户 IDdocker存储全部数据包括 Loki 本地状态与 Minio 对象存储位于.data目录。2.2 各服务端口一览服务端口用途nginx gateway3100Loki 统一入口转发读写请求Minio API / Console9000/9001S3 兼容对象存储及管理界面Prometheus9090采集 Loki 与 Promtail 指标Alertmanager9093接收并路由 Loki ruler 发出的告警Grafana3000预置 Loki/Prometheus 数据源匿名登录即为 AdminPromtail9080容器内日志采集 Agent 的自监控端点Loki gRPC9095组件间内部通信端口2.3 内置诊断端点启动后可直接访问以下端点验证集群状态/ring— 查看 hash ring 中注册的所有组件及其健康状态/config— 查看 Loki 实际生效的完整配置含所有默认值/memberlist— 查看 memberlist gossip 集群中的所有节点Loki 其余全部 API 端点见 pkg/loghttp 与 docs 中的 API 文档。三、docker-compose 服务逐项拆解docker-compose.yaml 共定义 9 个服务。其中x-loki-common是 YAML 锚点抽出了 Loki 容器的公共配置供loki-monolithic与loki-monolithic-compactor复用。3.1 Loki 副本x-loki-common 锚点x-loki-common: loki-common image: grafana/loki:3.7.7sha256:d70e4659623f3e109af669cae76fe2a5dd5be54e2298fe8aed380d982fbc2500 volumes: - ./config:/etc/loki/ - loki:/loki ports: - 3100 - 9095 - 7946 # memberlist gossip 端口 command: - -targetall - -config.file/etc/loki/loki.yaml restart: always healthcheck: test: [CMD, /usr/bin/loki, -health] start_period: 30s interval: 30s timeout: 10s retries: 3要点-targetall以单二进制模式启动全部 targetdistributor、ingester、querier、query-frontend、ruler 等。高可用性通过deploy.replicas: 3实现3 个副本共同组成 memberlist 环7946端口memberlist gossip 通信端口必须对所有副本开放否则无法组环健康检查调用/usr/bin/loki -healthstart_period: 30s预留了 ring 注册时间镜像通过sha256:...固定 digest保证可复现性。3.2 compactor 独立副本loki-monolithic-compactor: : *loki-common environment: LOKI_COMPACTOR_MODE: main deploy: mode: replicated replicas: 1compactor 只运行 1 个副本并通过环境变量LOKI_COMPACTOR_MODEmain标记其为主实例。该变量对应 loki.yaml 中的compactor.horizontal_scaling_mode: ${LOKI_COMPACTOR_MODE:-worker}——非 main 实例如 3 个普通副本中运行 compactor 的部分会以 worker 模式参与水平扩展形成 compactor 的 leader-worker 协同结构。3.3 存储层Miniominio: image: minio/minio entrypoint: - sh - -euc - | mkdir -p /data/loki-data \ mkdir -p /data/loki-ruler minio server --address 0.0.0.0:9000 --console-address 0.0.0.0:9001 /data environment: - MINIO_ROOT_USERloki - MINIO_ROOT_PASSWORDsupersecret - MINIO_PROMETHEUS_AUTH_TYPEpublic - MINIO_UPDATEoff启动时预先创建loki-datachunks/索引桶与loki-rulerruler 状态桶两个 bucket。生产环境必须修改MINIO_ROOT_USER/MINIO_ROOT_PASSWORD默认凭据并与 loki.yaml 中的storage_config.aws保持一致。3.4 日志生产与采集flog Promtaillog-generator服务标注“for testing purposes only, disable in production”使用mingrammer/flog以每 10 行/秒、100ms 间隔持续生成 JSON 格式日志并写入/var/log/generated-logs.txtlog-generator: image: mingrammer/flog platform: linux/amd64 command: - --loop - --formatjson - --number10 # 每秒生成日志行数 - --delay100ms # 行间延迟 - --output/var/log/generated-logs.txt - --overwrite - --typelog volumes: - ./logs/:/var/log/Promtail 通过共享卷./logs/读取该文件compose 文件中标注了TODO: Replace with Alloy提示后续版本将迁移到 Grafana Alloy。其配置见 promtail.yamlclients: - url: http://gateway:3100/loki/api/v1/push tenant_id: docker scrape_configs: - job_name: generated-logs static_configs: - targets: [localhost] labels: job: generated-logs __path__: /var/log/generated-logs.txt pipeline_stages: - json: expressions: http_method: method http_status: status - labels: http_method: http_status:关键点Promtail 显式指定tenant_id: docker与多租户配置匹配pipeline 中通过json解析阶段从日志提取method/status字段再经labels阶段转换为可查询的标签http_method/http_status。3.5 可观测性Prometheus 与 Alertmanagerprometheus.yaml 采用DNS 服务发现而非静态 target通过dns_sd_configs解析loki-monolithic、loki-monolithic-compactorA 记录端口 3100与promtail端口 9080副本扩容后无需修改配置即可自动纳入抓取。compose 中还启用了--enable-featureremote-write-receiver用于接收 Loki ruler 的 remote-write 告警指标。alertmanager.yml 定义了一个默认 receiver 与 30s 的 group_wait 路由配合 rules/docker/rules.yml 中的示例规则如NoGeneratedLogs告警absent_over_time({jobgenerated-logs}[1m])构成完整的告警链路——ruler 评估 LogQL 规则通过remote_write将指标推给 Prometheus再由 Prometheus 触发 Alertmanager。四、Loki 核心配置逐项精讲loki.yaml 是该部署的大脑下面结合源码与部署架构逐段解读。4.1 多租户与监听auth_enabled: true server: http_listen_address: 0.0.0.0 grpc_listen_address: 0.0.0.0 http_listen_port: 3100 grpc_listen_port: 9095 log_level: infoauth_enabled: true开启多租户认证每个请求必须携带X-Scope-OrgID头标识租户本部署为dockerGrafana 数据源通过自定义 HTTP 头注入该值见 datasources.yaml 中的httpHeaderName1: X-Scope-OrgID与httpHeaderValue1: docker。4.2 common路径、副本因子与 ringcommon: path_prefix: /loki replication_factor: 3 compactor_grpc_address: loki-monolithic-compactor:9095 ring: heartbeat_period: 1m heartbeat_timeout: 5m kvstore: store: memberlistreplication_factor: 3每个流stream在 3 个 ingester 副本上各保存一份任一副本故障不丢数据这也是 3 副本部署的底层原因kvstore.store: memberlistring 元数据通过 gossip 协议在节点间传播无需额外依赖 Consul/etcd简化部署compactor_grpc_address指向独立 compactor 的 gRPC 端点。4.3 对象存储对接storage_config: aws: endpoint: minio:9000 insecure: true bucketnames: loki-data access_key_id: loki secret_access_key: supersecret s3forcepathstyle: trueLoki 通过 AWS S3 SDK 协议访问 Minio因此复用aws配置块insecure: true表示走 HTTPMinio 容器内默认无 TLSs3forcepathstyle: true使用路径风格寻址minio:9000/loki-data这是 Minio 等自建 S3 兼容服务的必选项。4.4 memberlist 集群memberlist: join_members: - loki-monolithic - loki-monolithic-compactor bind_addr: [0.0.0.0] bind_port: 7946 cluster_label: loki-ha-monolithic cluster_label_verification_disabled: falsejoin_members通过 Docker DNS 名称加入 gossip 集群cluster_label为集群打上标识防止不同环境节点误加入同一环并开启标签校验。4.5 ingesterWAL 与 chunk 生命周期ingester: lifecycler: final_sleep: 0s chunk_idle_period: 1m wal: enabled: true dir: /loki/wal max_chunk_age: 1m chunk_retain_period: 30s chunk_encoding: snappy chunk_target_size: 1.572864e06 # ≈1.5MB chunk_block_size: 262144 # 256KB flush_op_timeout: 10sWALWrite-Ahead Logenabled: true时日志先写本地 WAL/loki/wal再进内存 chunk进程重启后通过 WAL 恢复避免丢失已确认的写入chunk_idle_period: 1m表示 1 分钟无新数据即冲刷 chunkmax_chunk_age: 1m限制 chunk 最长存活时间两者共同决定数据从内存到对象存储的延迟chunk_target_size约 1.5MB达到即封存控制对象存储中小文件数量chunk_encoding: snappy选择压缩算法可选 gzip/lz4/snappy 等见 pkg/chunkenc 的编解码实现。4.6 ruler规则评估与告警ruler: enable_api: true enable_sharding: true wal: dir: /loki/ruler-wal evaluation: mode: remote query_frontend: address: dns:///loki:9095 storage: type: local local: directory: /loki/rules rule_path: /loki/prom-rules remote_write: enabled: true clients: local: url: http://prometheus:9090/api/v1/write queue_config: capacity: 1 batch_send_deadline: 0sruler 在多个副本间分片评估规则enable_sharding采用remote模式将规则查询发送给 query-frontend规则文件存放在本地/loki/rules示例见 rules/docker/rules.yml评估产生的指标通过 remote-write 即时推送到 Prometheuscapacity: 1、batch_send_deadline: 0s表示样本生成后立即发送用于演示。4.7 schemaTSDB 索引与对象存储schema_config: configs: - from: 2024-03-29 store: tsdb object_store: s3 schema: v13 index: prefix: index_ period: 24h当前采用TSDB 索引格式 S3 对象存储 v13 schemachunks 与索引均存于 Minio索引按 24 小时一个周期分片index_前缀。schema 的from日期定义了该配置的生效起始时间升级 schema 版本时通过追加配置实现平滑迁移可参考 docs/sources/reference/ 中的 schema 演进文档。4.8 limits租户限额与查询调优limits_config: max_cache_freshness_per_query: 10m reject_old_samples: true reject_old_samples_max_age: 30m ingestion_rate_mb: 100 ingestion_burst_size_mb: 20 split_queries_by_interval: 15m volume_enabled: true retention_period: 336hreject_old_samplesreject_old_samples_max_age: 30m拒绝时间戳超过 30 分钟的旧样本防止乱序写入拖垮 ingesteringestion_rate_mb: 100/ingestion_burst_size_mb: 20每租户每秒 100MB 的摄入速率上限与 20MB 突发额度split_queries_by_interval: 15m将大跨度查询按 15 分钟切片并行执行volume_enabled: true开启日志量volume统计接口retention_period: 336h默认保留 14 天配合compactor.retention_enabled: true生效。4.9 查询链路与 compactorquery_range: align_queries_with_step: true max_retries: 5 parallelise_shardable_queries: true cache_results: true frontend: log_queries_longer_than: 5s compress_responses: true max_outstanding_per_tenant: 2048 query_scheduler: max_outstanding_requests_per_tenant: 1024 compactor: working_directory: /loki/compactor horizontal_scaling_mode: ${LOKI_COMPACTOR_MODE:-worker} apply_retention_interval: 1h compaction_interval: 5m retention_enabled: true delete_request_store: s3查询链路启用了结果缓存cache_results、查询分片并行parallelise_shardable_queries与响应压缩compress_responses是大规模查询的关键优化项。compactor 每 5 分钟执行一次压缩、每 1 小时应用一次保留策略删除请求记录存放在 S3delete_request_store: s3。五、nginx 网关读写分流与 WebSocket 支持nginx.conf 定义了三个上游与三段路由规则upstream loki { server loki-monolithic:3100; server loki-monolithic-compactor:3100; } upstream compactor { server loki-monolithic-compactor:3100; } server { listen 3100; location / { # 常规读写请求 proxy_pass http://loki; ... } location /loki/api/v1/tail { # 精确匹配 tail 接口 proxy_pass http://loki; proxy_set_header Upgrade $http_upgrade; # WebSocket 升级 proxy_set_header Connection upgrade; } location ~ ^/loki/api/v1/delete { # 删除请求定向到 compactor proxy_pass http://compactor; ... } }普通 HTTP 请求push/query/labels 等在loki-monolithic各副本间负载均衡/loki/api/v1/tail必须走 WebSocket 升级Upgrade/Connection头否则实时 tail 日志流无法工作删除请求/loki/api/v1/delete*通过正则路由强制转发到 compactor 主实例保证删除任务只由一个节点处理。六、基于 delve 的容器内交互式调试这是本仓库最具特色的开发能力README 的 Debugging 小节提供了完整流程。6.1 构建调试镜像在仓库根目录执行make loki-debug-image对应 Makefile 中的目标loki-debug-image: ## build the loki debug docker image $(OCI_BUILD) -t $(LOKI_IMAGE)-debug -f cmd/loki/Dockerfile.debug .构建产物镜像名为grafana/loki:...-debug从输出中获取完整镜像名替换 docker-compose.yaml 中x-loki-common的image字段。6.2 调试镜像内部机制cmd/loki/Dockerfile.debug 展示了其原理安装 delvego install github.com/go-delve/delve/cmd/dlvlatest并以make loki-debug构建带调试符号的loki-debug二进制基于gcr.io/distroless/base-nossl:debug运行EXPOSE 40000暴露 delve 监听端口入口直接是 delve 而非 Loki 本体ENTRYPOINT [/usr/bin/dlv, --listen:40000, --headlesstrue, --log, --continue, --accept-multiclient, --api-version2, exec, /usr/bin/loki-debug, --] CMD [-config.file/etc/loki/local-config.yaml]--headlesstrue以无界面模式等待外部调试器连接--continue表示连接后继续运行程序--accept-multiclient允许多个调试客户端--之后的所有参数原样传递给被调试的 Loki 进程。6.3 启用调试的步骤在 docker-compose.yaml 的x-loki-common中取消注释以下三处调试相关配置cap_add: - SYS_PTRACE # 允许 delve 附加进程 security_opt: - apparmorunconfined # 关闭 AppArmor 限制 # ports: # - 40000-40002:40000 # 将 3 个副本分别暴露到宿主 40000/40001/40002在 GoLand 中为某个 Loki 服务绑定宿主端口添加Go Remote调试配置并指向该端口也可在 IDE 中手动执行dlv connect或dlv attach核心步骤一致执行docker-compose up在代码中设置断点启动调试配置即可命中并逐步调试。注意cap_add: SYS_PTRACE与apparmorunconfined是 delve 附加/调试进程所必需的系统权限日常运行请保持注释状态。七、从开发栈到生产的注意事项凭据安全替换 Minio 的MINIO_ROOT_USER/MINIO_ROOT_PASSWORDdocker-compose.yaml并同步更新 loki.yaml 中storage_config.aws的密钥禁用测试组件生产环境应移除log-generator并将 Promtail 替换为正式采集方案compose 注释已提示迁移到 Alloy扩容与演进3 副本的 HA 单二进制模式可直接将-targetall拆分为read/write/backend等独立 target 平滑过渡到 Simple Scalable 或微服务架构参见 examples/ha-monolithic 的配置样例验证手段启动后通过/ring确认全部实例ACTIVE在 Grafanalocalhost:3000匿名 Admin执行{jobgenerated-logs}即可立即看到 flog 生成的 JSON 日志并用http_method标签聚合验证完整链路。这套 compose 栈既是理想的本地开发环境也是理解 Loki 高可用架构ring、memberlist、TSDB、WAL、compactor 协同的最佳入门模板所有核心配置集中在 config/loki.yaml 一个文件配合 docker-compose.yaml 可快速复现并实验每一项参数的行为。【免费下载链接】lokiLike Prometheus, but for logs.项目地址: https://gitcode.com/GitHub_Trending/lok/loki创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
