Logs流水线:ELK和Loki
1)为什么和时间: 拼写目的
可观察性和RCA:加速debag,后太平间,SLO/SLA控制。
安全和审计:访问痕迹,异常,调查。
业务指标:转换、支付漏洞、PSP错误、用户行为。
合规性:存储,PII掩盖,还原策略,法律保留。
博客类型:应用,基础架构(kubelet, kube-proxy, CNI, ingress),网络,审计,支付,Web事件,Nginx/Envoy, DB。
2)高级体系结构
选项A: ELK
Producers → Logshipper (Filebeat/Fluent Bit/Vector) → Logstash/Beats input → Elasticsearch → Kibana/Алертинг
选项B: Loki
Producers → Promtail/Fluent Bit → Loki distributor/ingester/querier → Grafana/Алертинг
溷合动力车
ELK用于全文搜索/面板,Loki用于廉价的可扩展存储和快速的格雷普式查询;在Grafana中使用度量/轨迹。
3)数据流和处理级别
1.收集:打字机文件,journald,syslog,stdout容器,HTTP。
2.丰富:timestamp归一化,主机/pod/namespace,env(prod/stage),版本,commit SHA,trace/span id。
3.配对:JSON →平地;grok/regex;Nginx/Envoy格式;支付方案(PSP错误代码)。
4.过滤器/修订版:剪切PII (PAN, CVV,电子邮件,地址),秘密,令牌。
5.漫游:按电话/服务/日志级别;hot/warm/cold;在S3/对象存储中。
6.存储和还原:数据类的TTL策略。
7.访问/分析/Alerta。
4) ELK: 关键解决方桉
4.1 Logstash/Beats
将Beats/Fluent Bit用作轻量级收集器,Logstash用作中央ETL (grok, dissect, mutate, geoip, translate)。
Logstash池:ingest-ETL, security-ETL, payments-ETL-用于隔离负载。
4.2 Elasticsearch
摇摇欲坠:专注于每摇摇欲坠的~ 20-50 GB;避免"沙丁鱼爆炸"。
索引策略:'log-<tenant>-<service>-YYYY。MM.DD'或数据流;rollover的大小/时间。
ILM (hot/warm/cold/frozen):
hot:SSD,1-7天;warm: HDD, 7-30天;冷:体积大;冷冻:最低成本,访问速度较慢。
Mappings:硬类型字段,限制"fielddata"并创建动态字段。
缓存和查询:按键字段的过滤器,整齐的聚合;用于高频搜索的点对点。
4.3 Kibana
多影子空间。
Saved searches,Lens/TSVB,threshold/度量。
按索引模式划分的RBAC("logs-tenant-")。
5) Loki: 关键解决方桉
5.1个标签型号
标签是Loki的"索引"。使用低基数:'cluster'、'namespace'、'app'、'level'、'env'、'tenant'。
高基数字段(uid,request_id)在行中;通过LogQL "|="、"| json"、"| regexp"查询时检索。
5.2个组件
Promtail: сбор stdout, files, journald;解析器(JSON, regex, cri)。
Distributor/Ingester/Querier/Query-frontend:按角色缩放;请求缓存。
Object Storage (S3/GCS/MinIO)用于长期存储字符日志。
5.3 LogQL技术
快速grep: '{app='payments',level='error'} |= 'declined'
Парсинг JSON: `{app="api"} | json | code="5xx" | unwrap duration | avg()`
与指标的相关性: 'rate ({app='nginx"} |= '200' [5m])'
6)ELK vs Loki比较(简述)
搜索/聚合:对于复杂的全文和多面查询,ELK更强大;Loki像油脂一样,快速便宜。
成本:Loki通常在较大体积上便宜(对象存储+较小的索引)。
操作难度:ELK 需要索引/ILM,Javu-hips的纪律;Loki是标签上的学科。
与度量/轨迹的相关性:Loki自然与Grafana/OTel堆栈集成;ELK也知道,但更常见的是通过集成。
7)安全和合规性
边缘的PII修订版(shipper):伪装PAN、电子邮件、电话、地址、令牌。
传输中的TLS,代理与总线之间的mTLS。
RBAC:按指数索引/标签;Nijspace/空间隔离。
Secrets hygiene:无秘密环境变量,个别秘密经理。
法律保持:分段/索引冻结机制;有争议时期的write-once。
删除/重建:按数据类别(prod/stateful/付款/审计)分列的TTL策略。
登录访问审核预告片。
8)可靠性和吞吐量
缓冲和备份:代理的本地文件/驱动器;带有指数回放的回放。
Idempotency: "ingest_id"/"log_id"字段,用于避免重播时的重复。
HA: Loki的ES 大师/ingesters最少3个读物;antiaffinity по AZ.
Tenant/Service的配额和等级限制;防御逻辑的"风暴"。
Log Level Scheme:"ERROR"是有限的,"DEBUG"只是暂时通过动态标志。
9)性能和调音
ELK:
JVM heap 50% RAM(但每头≤ ~ 30-32 GB), page cache很重要。
智能过山车(每个20-50 GB/shard),"refresh_interval" ↑用于ingest索引。
在Logstash中避免"沉重"的树皮;如果可能,在源上进行JSON生成。
Loki:
正确的标签设置是速度的关键。
大袜子→便宜的存储,但更昂贵的是内存;平衡一下。
Query-frontend+缓存(模因/Redis)用于重复查询。
10) FinOps for Logs(成本)
字段/标签基数降低。
Sampling DEBUG和动态"log-swichi"。
轮换:短热,长冷成对象。
重复数据消除和合并消息(batch)。
将很少使用的日志存档到廉价的存储类。
Dashbord价值:体积/数据流/标签/索引/tenant。
11)与指标和轨道的相关性(Observability 3-in-1)
每个日志中的Trace-ID/Span-ID(网关API和服务上的middleware)。
OpenTelemetry:一个上下文;Tempo/Jaeger的出口商,Prometheus/Mimir的指标,logi-Loki/ELK。
快速场景: "通过度量标准→跳入适当的日志→跳入赛道。"
12)多重性与隔离
基于Namespace的隔离(K8s标签),单独的索引模式/标签"tenant"。
沿着Tenant划分Alert/Dashbords/Rhetenchn。
按消费计费:ingest卷,storage,查询。
13)管道本身的监控和SLO
SLO ingest: «99.9%的日志交付于<X秒"。
搜索的SLO: "p95查询<Y sec"。
技术指标:queue depth、dropped logs、reprocess rate、error rate parser, ingester/ES nod故障。
14)示例部署模式
Managed: Elasticsearch Service/Opensearch, Grafana Cloud Loki.
自主K8s:用于ES/Loki的StatefulSets,AZ上的反亲和力,PersistentVolumes,对象存储。
Edge Agent(区域应用程序):本地缓冲区+TLS通道到中央入口。
15)配置示例
15.1 Promtail (K8s, CRI JSON)
yaml scrape_configs:
- job_name: kubernetes-pods kubernetes_sd_configs:
- role: pod pipeline_stages:
- cri: {}
- json:
expressions:
level: level msg: message trace: trace_id
- labels:
level:
app:
namespace:
- match:
selector: '{namespace="prod"}'
stages:
- regex:
expression: '(?P<pan>\b[0-9]{12,19}\b)'
- replace:
expression: '(?P<pan>\b[0-9]{12,19}\b)'
replace: '[REDACTED_PAN]'
relabel_configs:
- action: replace source_labels: [__meta_kubernetes_pod_label_app]
target_label: app
- action: replace source_labels: [__meta_kubernetes_namespace]
target_label: namespace
- action: replace source_labels: [__meta_kubernetes_pod_node_name]
target_label: node
15.2 Logstash (ingest和蒙版)
ruby input {
beats { port => 5044 }
}
filter {
json { source => "message" skip_on_invalid_json => true }
mutate { add_field => { "env" => "%{[kubernetes][labels][env]}" } }
PII mutate {
gsub => [
"message", "\b[0-9]{12,19}\b", "[REDACTED_PAN]",
"message", "(?i)(authorization: Bearer)([A-Za-z0-9\.\-_]+)", "\1[REDACTED_TOKEN]"
]
}
}
output {
elasticsearch {
hosts => ["https://es-hot-1:9200","https://es-hot-2:9200"]
index => "logs-%{[fields][tenant]}-%{[app]}-%{+YYYY. MM. dd}"
ilm_enabled => true ssl => true cacert => "/etc/ssl/certs/ca. crt"
user => "${ES_USER}"
password => "${ES_PASS}"
}
}
16)Alerting和dashbords(模式)
Ошибки API: `rate({app="api",level="error"}[5m]) > threshold` → PagerDuty/Telegram.
Nginx/Envoy中的5xx爆发;代理商的rop ingest;后期搜索增长。
Dashbords:- 按服务/tenant排列的日志量。
- 顶级错误模式(代码/例外/endpoint)。
- 续集/存储类成本。
17)质量检查(log-QA)
拼写合同:JSON格式,必填字段("ts","level","service","env","trace_id","msg")。
CI中的Linter Loger:未经同意禁止使用高基数的新字段。
金丝雀服务:为早期回归检测生成参考日志。
18)频繁的错误和反模式
高基数的Loki标签("user_id","request_id")→内存爆炸。
ES中没有映射的动态字段→"索引爆炸"。
DEBUG"永远"出售。通过旗帜和TTL打开。
没有PII修订版。
一个通用的"整体"流水线适合一切-最好是跨域细分。
19)实施计划(迭代)
1.MVP: Agent+1 pipline(应用程序),Basic dashbords, PII修订版。
2.扩展:网络/infra-logs,SLO alerts,带有轨道。
3.FinOps:重构矩阵,价值报告,标签/指数优化。
4.多特南特:空间,RBAC,按消费计费。
5.可靠性:HA, disaster-drills, Legal Hold。
20)入口的启动支票清单
- 所有服务中的JSON格式和必填字段。
- 在代理/ingest上伪装PII。
- 还原政策/ILM或bucket-lifecycle。
- RBAC/空间/tenants。
- SLO ingest/Search和Alertes。
- 金丝雀日志和测试运行负载。
- 价值码和服务所有者报告。
- Runbooks:"如果ingest下跌/搜索缓慢/鲨鱼是红色,该怎么办。"
21) Mini-FAQ
选择什么-ELK或Loki?