【K8S 运维实战】13-日志体系Loki
日志体系:Loki+Promtail 轻量方案落地
一句话定位:ELK 太重?Loki + Promtail 给你一条"像 grep 一样查日志,像 Prometheus 一样管日志"的轻量之路。
写在前面
2024年我在一家电商公司做 K8s 集群迁移,原来的日志方案是 ELK—— 3 台 16C64G 的 Elasticsearch 节点,每月存储成本 8000+。日志量大时 ES 频繁 OOM,Kibana 查询慢得让人想砸键盘。业务方天天投诉"日志查不出来"。
后来我们切到 Loki + Promtail,同样的日志量,存储成本降到原来的 1/5,查询速度反而更快。这篇文章就是把那次迁移的完整经验写出来,从原理到部署到踩坑,一条龙。
读完你能带走什么:
- Loki 架构原理和标签设计方法论
- DaemonSet vs Sidecar 两种采集模式的选型决策
- 一套生产可用的 Loki+Promtail Helm 部署配置
- LogQL 常用查询速查手册
- 日志告警和成本控制策略
核心问题
ELK 太重,有没有轻量替代?回答这个问题之前,我们先搞清楚 ELK 到底"重"在哪:
- 全文索引开销大:ES 对每行日志建倒排索引,磁盘和内存消耗是原始日志的 2-3 倍
- 运维复杂:ES 集群分片、副本、JVM 调优,没个专职运维搞不定
- 与 K8s 生态割裂:ELK 不是云原生出身,和 Prometheus、Grafana 配合起来别扭
Loki 的思路很聪明:不索引日志内容,只索引标签(Labels)。这就像图书馆里不把每本书的全文做成索引卡片,只按分类号、作者、出版日期建卡片——找书时先按卡片定位,再翻内容。
一、原理剖析
1.1 Loki 整体架构
Loki 是一个"写多读少"的日志聚合系统,设计上大量借鉴了 Prometheus 的理念。
┌────────────────────────────────────────────────────────────────┐
│ Loki 架构 │
├────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Promtail │ │ Promtail │ │ Promtail │ (采集层) │
│ │ (Node-1) │ │ (Node-2) │ │ (Node-3) │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ └────────────────┼────────────────┘ │
│ │ (gRPC push) │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ Distributor │ (分发层) │
│ │ - 验证租户/标签 │ │
│ │ - 哈希路由 │ │
│ │ - 一致性哈希环 │ │
│ └─────────┬───────────┘ │
│ │ │
│ ┌────────────┼────────────┐ │
│ ▼ ▼ ▼ │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ Ingester │ │ Ingester │ │ Ingester │ (写入层) │
│ │ - 构建Chunk│ │ - 内存缓存│ │ - 刷写存储│ │
│ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ │
│ │ │ │ │
│ └─────────────┼─────────────┘ │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ 对象存储 (S3/GCS等) │ (持久化层) │
│ │ Chunks + Index │ │
│ └───────────┬───────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ Querier │ (查询层) │
│ │ - 接收查询请求 │ │
│ │ - 并行读取Chunks │ │
│ │ - 合并返回结果 │ │
│ └───────────────────────┘ │
│ │
└────────────────────────────────────────────────────────────────┘
各组件职责:
| 组件 | 职责 | 关键设计 |
|---|---|---|
| Distributor | 接收日志流,验证标签格式,按一致性哈希路由到 Ingester | 无状态,可水平扩展 |
| Ingester | 接收日志、构建 Chunk、定期刷写到对象存储 | 有状态,通过 WAL 保证不丢数据 |
| Querier | 执行 LogQL 查询,从 Ingester + 对象存储读取数据并合并 | 无状态,读路径 |
| Compactor | 合并小 Index 文件,执行保留策略清理过期数据 | 减少查询时需要扫描的文件数 |
| Query Frontend | 查询缓存、查询拆分、重试、限流 | 可选但生产强烈建议部署 |
| Ruler | 周期性执行 LogQL 规则,生成告警或录制指标 | 日志告警的核心组件 |
1.2 核心设计:标签为王
Loki 最核心的设计哲学来自 Prometheus:Labels are the index。
Loki 只对标签({app="nginx", env="prod"})建索引,日志内容本体(log line)不做索引,直接按时间排序存储在 Chunk 中。
这带来一个直接推论:标签的设计决定了查询性能和存储成本。
标签索引原理(ASCII 示意):
日志流:
{app="nginx", env="prod", pod="nginx-7d4f8"}
2024-01-01 10:00:01 GET /api/users 200
2024-01-01 10:00:02 POST /api/orders 201
2024-01-01 10:00:03 GET /api/products 200
查询: {app="nginx", env="prod"} |= "orders"
│
▼
┌──────────────────┐
│ 1. 标签索引查找 │ ← 直接命中,O(1)
│ app=nginx │
│ env=prod │
└──────┬───────────┘
│
▼
┌──────────────────┐
│ 2. 定位 Chunk 文件 │ ← 按时间范围过滤
│ 2024-01-01 │
└──────┬───────────┘
│
▼
┌──────────────────┐
│ 3. 顺序扫描内容 │ ← 类似 grep,但不建索引
│ 匹配 "orders" │
└──────────────────┘
标签设计的黄金法则:
高基数标签 ──▶ 禁止! 例如 pod_name, container_id, trace_id
中等基数 ──▶ 谨慎 例如 user_id, request_id(考虑用结构化日志字段代替)
低基数标签 ──▶ 推荐! 例如 app, env, namespace, cluster, team
高基数标签为什么是大忌?Loki 为每个标签组合创建一个独立的流(Stream),如果你把 pod_name 当作标签,每次 Pod 重启都会创建新流,标签索引会爆炸式增长,DynamoDB/BigTable 存储成本直线上升。
1.3 采集模式对比:DaemonSet vs Sidecar
这是面试和方案评审中必问的问题。两种模式各有优劣,没有银弹。
DaemonSet 模式 Sidecar 模式
┌──────────────────────┐ ┌──────────────────────┐
│ Node │ │ Pod │
│ ┌────────────────┐ │ │ ┌────────────────┐ │
│ │ Pod A │ │ │ │ App Container │ │
│ │ (stdout/stderr) │ │ │ │ → 写文件到 │ │
│ └────────┬───────┘ │ │ │ /var/log/ │ │
│ │ stdout │ │ └───────┬────────┘ │
│ ┌────────▼───────┐ │ │ │ tail │
│ │ Promtail │◄──┤─ 所有Pod │ ┌───────▼────────┐ │
│ │ (DaemonSet) │ │ 共享一个 │ │ Log Sidecar │ │
│ │ /var/log/pods │ │ Promtail │ │ → push Loki │ │
│ └────────┬───────┘ │ │ └────────────────┘ │
│ │ push │ └──────────────────────┘
│ ┌─────▼─────┐ │
│ │ Loki │ │ 一个Pod一个Sidecar
│ └───────────┘ │ 资源消耗随Pod线性增长
└──────────────────────┘
| 维度 | DaemonSet | Sidecar |
|---|---|---|
| 资源占用 | O(Node数量) | O(Pod数量) |
| 侵入性 | 无侵入,应用写 stdout 即可 | 需改造 Pod Spec |
| 日志格式处理 | 统一处理 | 每个 Sidecar 独立处理 |
| 适用场景 | 标准应用日志采集 | 日志需要特殊解析/脱敏 |
| 网络开销 | 每节点一个 gRPC 连接 | 每 Pod 一个连接 |
生产建议:除非有特殊需求(如必须采集非 stdout 的文件日志、需要日志脱敏),一律用 DaemonSet 模式。简单就是最大的美德。
二、实战操作
2.1 环境准备
# 确认 K8s 版本
kubectl version --short
# 确认 Helm 版本
helm version --short
# 添加 Loki 官方 Helm 仓库
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
2.2 Loki 生产部署配置
# 创建命名空间
kubectl create namespace loki
# 创建 S3 凭证 Secret(以 MinIO 为例,生产用 AWS S3/GCS/Azure Blob)
kubectl create secret generic loki-s3-credentials \
--from-literal=access_key_id="loki-admin" \
--from-literal=access_key_secret="your-secret-key" \
-n loki
loki-values.yaml —— 生产级部署配置:
# ============================================
# Loki 生产部署配置 (v2.9.x, Helm Chart 5.x)
# 适用规模:日均日志量 100GB-1TB
# ============================================
# ── Loki 核心配置 ──
loki:
# 部署模式:SingleBinary 适合入门/小规模
# 大规模场景用 microservices 模式分开部署各个组件
deploymentMode: SingleBinary
# 镜像版本
image:
repository: grafana/loki
tag: 2.9.6
# 认证:多租户模式下强制开启
auth_enabled: false # 单租户场景关闭,多租户必须开启
# ── 存储配置 ──
storage:
type: s3
bucketNames:
chunks: loki-chunks
ruler: loki-ruler
admin: loki-admin
s3:
endpoint: minio.loki.svc.cluster.local:9000
region: us-east-1
secretAccessKey: ${S3_SECRET_KEY}
accessKeyId: ${S3_ACCESS_KEY}
insecure: true # MinIO 非 TLS 场景
s3ForcePathStyle: true
# ── Ingester 配置 ──
ingester:
chunk_encoding: snappy # snappy 平衡压缩率和 CPU 消耗
chunk_target_size: 1572864 # 1.5MB,Chunk 目标大小
chunk_idle_period: 30m # 30分钟无新日志则关闭 Chunk
chunk_retain_period: 1m # Ingester 关闭后 Chunk 保留时间
max_chunk_age: 2h # Chunk 最大存活时间,到达后强制刷写
chunk_block_size: 262144 # 256KB 块大小
max_returned_stream_errors: 10
wal:
enabled: true # 生产必须开 WAL
dir: /var/loki/wal
replay_memory_ceiling: 2GB # WAL 回放内存上限
# ── 查询配置 ──
querier:
max_concurrent: 20 # 最大并发查询数
query_ingesters_within: 2h # 2小时内的数据从 Ingester 查
query_timeout: 5m # 查询超时
engine:
timeout: 3m
max_look_back_period: 720h # 30天
# ── 查询前端(生产强烈推荐) ──
queryFrontend:
max_outstanding_per_tenant: 1024
compress_responses: true
log_queries_longer_than: 10s
max_retries: 3
# ── Query Scheduler ──
queryScheduler:
max_outstanding_requests_per_tenant: 100
# ── 索引与 Chunk Schema ──
schemaConfig:
configs:
- from: "2024-01-01"
store: tsdb # TSDB 索引格式(Loki 2.8+ 推荐)
object_store: s3
schema: v13
index:
prefix: loki_index_
period: 24h
# ── 压缩器 ──
compactor:
working_directory: /var/loki/compactor
compaction_interval: 10m
retention_enabled: true
retention_delete_delay: 2h
delete_request_store: s3
# ── 保留策略(关键!控制成本) ──
limits_config:
retention_period: 744h # 保留31天日志
max_entries_limit_per_query: 5000
max_streams_per_user: 10000 # 每个租户最大流数
max_global_streams_per_user: 50000
ingestion_rate_mb: 16 # 每秒摄入速率限制(MB)
ingestion_burst_size_mb: 32 # 突发摄入大小(MB)
max_label_name_length: 1024
max_label_value_length: 2048
max_label_names_per_series: 30 # 每个流最多30个标签(鼓励标签收敛)
# ── Ruler 日志告警 ──
rulerConfig:
storage:
type: s3
s3:
bucketNames: loki-ruler
alertmanager_url: http://alertmanager.monitoring.svc:9093
enable_alertmanager_v2: true
enable_api: true
ring:
kvstore:
store: inmemory
rule_path: /var/loki/rules-temp
poll_interval: 1m
# ── 资源配额 ──
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2000m
memory: 4Gi
# 持久化
persistence:
enabled: true
size: 50Gi
storageClass: ssd-sc # WAL 和临时数据建议用 SSD
# 服务暴露
service:
type: ClusterIP
port: 3100
# ── Promtail 配置 ──
promtail:
enabled: true
image:
registry: docker.io
repository: grafana/promtail
tag: 2.9.6
config:
clients:
- url: http://loki.loki.svc.cluster.local:3100/loki/api/v1/push
batchsize: 1048576 # 1MB 批次
batchwait: 1s
backoff_config:
min_period: 500ms
max_period: 5m
max_retries: 10
# ── 管道配置(核心!日志处理在这里做) ──
snippets:
extraScrapeConfigs: |
# 额外抓取配置示例
pipelineStages:
# Stage 1: 解析 CRI 格式的容器日志
- cri: {}
# Stage 2: 提取关键字段为标签
- static_labels:
cluster: "prod-k8s-1"
datacenter: "cn-east-2"
# Stage 3: 根据 Pod 标签动态添加 Loki 标签
- labels:
app:
namespace:
pod_template_hash:
container:
# Stage 4: 水位线(避免重复采集)
- match:
selector: '{app=~".*"}'
stages:
- json:
expressions:
level: level
message: message
trace_id: trace_id
- labels:
level:
trace_id:
# Stage 5: 删除不需要的标签(控制标签基数)
- labeldrop:
- pod_template_hash
- controller_revision_hash
- pod_uid
# 资源限制
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
# 容忍所有污点
tolerations:
- operator: Exists
# ── 测试用 Grafana ──
grafana:
enabled: true
adminPassword: admin123
datasources:
datasources.yaml:
apiVersion: 1
datasources:
- name: Loki
type: loki
url: http://loki.loki.svc.cluster.local:3100
access: proxy
isDefault: true
# ── MinIO(仅测试用,生产请用外部 S3) ──
minio:
enabled: true
mode: standalone
rootUser: loki-admin
rootPassword: changeme-dev-only
buckets:
- name: loki-chunks
policy: none
purge: false
- name: loki-ruler
policy: none
purge: false
- name: loki-admin
policy: none
purge: false
persistence:
enabled: true
size: 20Gi
部署命令:
# 部署 Loki Stack (Loki + Promtail + Grafana + MinIO)
helm upgrade --install loki grafana/loki \
--namespace loki \
--values loki-values.yaml \
--timeout 10m \
--wait
# 验证所有 Pod 正常运行
kubectl get pods -n loki -w
# 预期输出:
# NAME READY STATUS RESTARTS AGE
# loki-0 1/1 Running 0 2m
# loki-grafana-xxxxx 1/1 Running 0 2m
# loki-minio-xxxxx 1/1 Running 0 2m
# loki-promtail-xxxxx 1/1 Running 0 2m (每个节点一个)
# loki-promtail-yyyyy 1/1 Running 0 2m
2.3 验证部署
# 端口转发 Loki API
kubectl port-forward -n loki svc/loki 3100:3100 &
# 验证 Loki Ready
curl http://localhost:3100/ready
# 预期输出: Ready
# 查看所有标签(确认标签采集正常)
curl http://localhost:3100/loki/api/v1/labels | jq
# 查看某个标签的值
curl 'http://localhost:3100/loki/api/v1/label/app/values' | jq
# 发送一条测试日志查询
curl -G -s "http://localhost:3100/loki/api/v1/query_range" \
--data-urlencode 'query={app=~".+"}' \
--data-urlencode 'limit=5' \
--data-urlencode 'start='$(date -d '1 hour ago' +%s)'000000000' \
--data-urlencode 'end='$(date +%s)'000000000' | jq
三、踩坑与排查
3.1 坑一:标签基数爆炸
现象:部署一周后,Loki 查询越来越慢,S3 上的 Index 文件快速增长。Promtail 日志中出现 stream limit exceeded 错误。
原因:运维同学在 Promtail 管道中把 pod_name 加入了 labels:
# 这是错误的配置!
- labels:
pod: # pod name 每次滚动更新都会变!
container:
每次 Deployment 滚动更新,Pod 名称变化就会创建全新的 stream。一个 100 副本的服务,一天滚动 3 次,就产生了 400 个 stream(100×3 + 原始100)。这还没算上 container_id、pod_uid 等更多高基数标签。
排查过程:
# 1. 查看每个租户的 stream 数量
curl http://localhost:3100/loki/api/v1/series | jq '.data | length'
# 2. 找出基数最高的标签(需要安装 logcli)
logcli series '{app=~".+"}' --since=24h | \
awk '{print $1}' | sort | uniq -c | sort -rn | head -20
# 3. 检查标签基数
logcli labels --since=1h
解决方案:
# 正确的标签策略
pipelineStages:
- cri: {}
- labels:
app: # 低基数 ✓
namespace: # 低基数 ✓
env: # 低基数 ✓ (dev/staging/prod)
- labeldrop:
- pod # 高基数 ✗ 删除
- container_id # 高基数 ✗ 删除
- pod_uid # 高基数 ✗ 删除
如果确实需要在查询中按 Pod 名称过滤,用 LogQL 的内容匹配替代标签过滤:
# 不要这样(标签基数高)
{app="nginx", pod="nginx-7d4f8-abcde"}
# 改成这样(内容匹配)
{app="nginx"} |= "nginx-7d4f8-abcde"
3.2 坑二:Ingester OOM 频发
现象:高负载时段 Loki 频繁 OOMKilled。Ingester 内存持续上升不释放。
原因:Ingester 在内存中缓存 Chunk,直到 max_chunk_age 或 Chunk 满才刷写。如果配置不合理,Ingester 会囤积大量未刷写数据。
定位:
# 查看 Ingester 内存
kubectl top pod loki-0 -n loki
# 查看 Loki 内部指标
curl http://localhost:3100/metrics | grep loki_ingester_memory_streams
# 关键指标
# loki_ingester_memory_streams ← 活跃 stream 数
# loki_ingester_chunk_age_seconds ← Chunk 平均年龄
# loki_ingester_memory_chunks ← 内存中 Chunk 数
解决方案:
loki:
ingester:
max_chunk_age: 1h # 缩短为 1 小时(原 2h)
chunk_idle_period: 15m # 15分钟无新日志就关闭
chunk_target_size: 1048576 # 降为 1MB(原 1.5MB),更频繁刷写
max_returned_stream_errors: 10
resources:
limits:
memory: 6Gi # 适当提高限制(前提是节点有资源)
3.3 坑三:查询超时
现象:查询最近 7 天的日志总是超时,返回 500。
原因:查询时间范围太大,Querier 需要扫描大量 Chunk 文件。没有部署 Query Frontend 或未配置查询拆分。
排查:
# 先用 logcli 精确排查
logcli query '{app="nginx"}' --from="2024-07-01T00:00:00Z" --to="2024-07-01T01:00:00Z" --limit=100
# 如果 1 小时可以,7 天不行 → 确认是范围问题
# 查看 Query Frontend 日志
kubectl logs -n loki deployment/loki -c loki | grep "query"
解决方案:
loki:
queryFrontend:
split_queries_by_interval: 30m # 按 30 分钟拆分大型查询
max_retries: 2
parallelise_shardable_queries: true # 并行分片查询
querier:
max_concurrent: 30 # 提高并发
query_timeout: 3m # 适当放宽
3.4 坑四:Promtail 重复采集
现象:同一行日志在 Loki 中出现多次,查询结果翻倍。
原因:Promtail 的 position 文件损坏或丢失,重启后从头读取日志文件。
定位:
# 检查 Promtail position 文件
kubectl exec -n loki daemonset/loki-promtail -- cat /var/lib/promtail/positions.yaml
# 查看是否有文件被重复打开(inode 变化)
kubectl logs -n loki daemonset/loki-promtail | grep "new file"
解决方案:
promtail:
config:
positions:
filename: /var/lib/promtail/positions.yaml
sync_period: 10s # 更频繁地同步 position
# 持久化 position 文件,Pod 重启不丢失
extraVolumes:
- name: positions
hostPath:
path: /var/lib/promtail-positions
type: DirectoryOrCreate
extraVolumeMounts:
- name: positions
mountPath: /var/lib/promtail
四、最佳实践
标签设计清单
- 标签总数控制在 10 个以内
- 使用
app(应用名)、env(环境)、namespace(K8s 空间)、cluster(集群名)、team(团队)等低基数标签 - 禁止
pod、container_id、pod_uid等会频繁变化的高基数标签 - Pod 名称信息通过日志内容匹配过滤,不通过标签
性能优化清单
- 部署 Query Frontend + Query Scheduler,开启查询拆分和结果缓存
- Ingester 开启 WAL(
wal.enabled: true),防止 OOM 丢数据 - 使用 TSDB 索引格式(
schema: v13,store: tsdb),Loki 2.8+ 默认推荐 - Chunk 编码选
snappy,压缩率 4-6x,CPU 开销小 - 合理设置
max_entries_limit_per_query(默认 5000),防止一条查询拖垮集群
成本控制清单
- 必做:设置
retention_period,删除过期日志(建议 30 天或 90 天) - 推荐:S3 配置生命周期策略,自动转换到标准-IA 或 Glacier
- 推荐:按
env标签配置不同保留期(生产 30 天、测试 7 天) - 可选:日志降采样 —— 7 天前的日志只保留
ERROR级别 - 禁止:使用
lz4编码(虽然快但压缩率差,S3 存储成本高)
日志告警清单
# loki-alerts.yaml - 放入 Ruler 配置
groups:
- name: loki-alerts
rules:
# 规则1: 错误率突增
- alert: HighErrorRate
expr: |
sum(rate({app=~".+"} |~ "(?i)error|exception|fatal" [5m])) by (app)
/ sum(rate({app=~".+"} [5m])) by (app) > 0.05
for: 5m
labels:
severity: P1
annotations:
summary: "应用 {{ $labels.app }} 错误率超过 5%"
description: "当前错误率 {{ $value | humanizePercentage }}"
# 规则2: 特定错误关键词
- alert: OutOfMemoryDetected
expr: |
count_over_time({app=~".+"} |= "OutOfMemoryError" [5m]) > 0
for: 1m
labels:
severity: P0
annotations:
summary: "检测到 OOM 错误"
# 规则3: 应用日志量突降(可能采集挂了)
- alert: LogVolumeDropped
expr: |
sum(rate({app=~".+"} [5m])) by (app) < 1
for: 10m
labels:
severity: P2
annotations:
summary: "应用 {{ $labels.app }} 日志量异常下降"
LogQL 速查
| 场景 | LogQL 查询 | 说明 |
|---|---|---|
| 应用全部日志 | {app="myapp"} |
最基础查询 |
| 时间范围+关键词 | {app="myapp"} |= "error" |
行包含 filter |
| 正则匹配 | {app="myapp"} |~ "(?i)error|exception" |
大小写不敏感 |
| 排除关键词 | {app="myapp"} != "debug" |
不包含 debug 的行 |
| JSON 字段过滤 | {app="myapp"} | json | level="error" |
解析 JSON 后过滤 |
| 计数统计 | count_over_time({app="myapp"} [5m]) |
5 分钟内日志行数 |
| 速率统计 | rate({app="myapp"} [5m]) |
每秒日志速率 |
| 按标签聚合 | sum(rate({app=~".+"} [5m])) by (app) |
每个应用的日志速率 |
| TOP N 应用 | topk(5, sum(rate({app=~".+"} [5m])) by (app)) |
日志量 Top 5 |
| 无日志检测 | absent_over_time({app="myapp"} [10m]) |
10 分钟没有日志则触发 |
| IP 解析过滤 | {app="nginx"} | pattern "<ip>" |
提取 IP 模式 |
| 字节日志 | bytes_over_time({app="myapp"} [1h]) |
1 小时内日志字节数 |
五、小结
Loki 不是要取代 ELK,而是提供了一种更适合云原生环境的日志方案。记住三句话:
- 标签是索引,内容是 grep —— 标签设计好了,Loki 就跑顺了
- DaemonSet 搞定 90% 的采集需求 —— Sidecar 只在有特殊需求时用
- Query Frontend + 合理保留策略 = 低成本高性能 —— 生产部署的基本姿势
如果你正在被 ELK 的运维成本折磨,给 Loki 两周时间试试。小规模(日均 < 100GB 日志)用 SingleBinary 模式跑单体就够了,大规模(> 1TB/天)上微服务模式 + 独立的 S3/GCS。
思考题
- 如果你的应用同时输出 JSON 格式的结构化日志和纯文本的非结构化日志,Promtail 管道应该怎么配?
- 多租户场景下,如何通过
X-Scope-OrgIDheader 实现租户隔离?如果一个租户的日志量是其他租户的 100 倍,如何限流? - Loki 的 Ingester 如果宕机,多久会丢数据?(提示:WAL + Replication Factor)
延伸阅读
- Loki 官方文档 - 标签最佳实践
- Loki 存储设计详解(Grafana 官方博客)
- Deep Dive into Loki’s TSDB Index
- 《Prometheus 监控实战》—— 标签设计理念来自 Prometheus,推荐搭配阅读
更多推荐




所有评论(0)