
— 特色专栏 —
大家好,我是民工哥!
说到日志系统,大家首先想到的就是 ELK(Elasticsearch + Logstash + Kibana)日志平台,其存储和计算成本较高,尤其是Elasticsearch的索引占用空间较大。

综合来说,ELK 更适合需要深度日志内容分析、复杂查询及传统应用场景,而 Loki 适用于云原生环境下基于标签的高效日志过滤与低成本存储。
所以,今天我们一起来聊一聊 Loki 学习的那些事儿!
Loki 是 Grafana Labs 推出的轻量级日志聚合系统,专为解决大规模日志存储、查询和可视化问题而设计。相比 ELK(Elasticsearch + Logstash + Kibana),Loki 更轻量、更高效,尤其适合 Kubernetes 环境。

高效存储与查询:Loki不直接存储日志的完整内容,而是将日志内容存储在对象存储(如AWS S3、Azure Blob Storage、本地文件系统等)中,仅在Loki中存储日志的索引信息。这种设计使得Loki能够高效地处理大规模的日志数据,同时保持较低的存储成本和查询延迟。
标签索引机制:Loki使用类似Prometheus的标签索引机制来存储和查询日志数据,这使得它能够快速地进行分布式查询和聚合,而不需要将所有数据都从存储中加载到内存中。
与Prometheus和Grafana集成:Loki与Prometheus的监控生态系统紧密集成,尤其适合与Grafana一起使用,用于实时监控和分析日志数据。用户可以通过Grafana的界面直接查询和可视化Loki中的日志数据,方便进行监控和故障排查。
轻量级与可扩展性:Loki是一个轻量级的日志聚合系统,具有较低的硬件要求,可以在较小的硬件上运行。同时,它支持水平扩展,可以通过添加更多的Loki实例来处理大量的日志数据。
多种日志采集方式:Loki通常与Promtail(Loki的日志采集代理)一起使用,Promtail负责从本地文件、容器日志等来源采集日志,并将其推送到Loki。除了Promtail,Loki还支持其他日志采集工具,如Fluentd和Logstash。
Loki的系统架构主要由以下几个核心组件构成,各组件协同工作以实现日志的高效收集、存储和查询。

Promtail 作为Loki的日志采集代理,Promtail负责从本地文件、容器日志等来源采集日志数据。它使用配置文件定义日志的采集路径和标签,通过HTTP API将日志数据发送到Loki。
Promtail支持多种日志采集方式,包括File Target、Journal Target、Syslog Target和Stdin Target,能够灵活适应不同的日志采集需求。
Distributor 作为日志数据写入路径的第一个组件,Distributor负责接收Promtail等客户端发送的日志流。它会对接收到的日志流进行正确性校验,并根据日志的元数据(如TenantID、Labels)和哈希算法计算出日志应该分发到哪个Ingester实例上。
Distributor 以并行的方式将日志分发给多个Ingester,以提高写入性能。
Ingester 是一个有状态的组件,负责接收Distributor分发过来的日志流,并将日志数据写入长期存储后端。在写入过程中,Ingester会对日志数据进行gzip或snappy压缩操作,并构建和刷新日志块(chunk)。当内存中的日志块达到一定的数量或者时间后,Ingester会将日志块和对应的索引信息刷新到存储系统中。
Ingester还负责处理日志数据的查询请求,从内存中或存储系统中检索日志数据并返回给Querier。
Querier负责处理日志数据的查询请求。它接收一个时间范围和标签选择器作为查询条件,根据索引信息确定哪些日志块匹配查询条件,并从Ingester和长期存储中检索日志数据。
Querier实现了查询并行化,能够分布式地处理查询请求,提高查询性能。在查询过程中,Querier还会对检索到的日志数据进行去重操作,以确保查询结果的准确性。
Query Frontend 是一个可选的组件,具有查询拆分和缓存的作用。它可以将一个复杂的查询拆解成多个小查询,并行地在多个Querier组件上进行查询,并将查询结果合并后返回给前端展示。Query Frontend内部有一个内存队列,还可以将其移出作为一个Query Scheduler查询调度器的单独进程运行,以进一步提高查询性能。
Ruler 负责日志告警功能。它可以持续查询一个规则(rule),并将超过阈值的事件推送给AlertManager或者其他告警Webhook服务。
Ruler使得Loki能够实时地监控日志数据,并在发现异常时及时发出告警。
Compactor 负责定时对索引进行压缩合并,同时负责日志的删除功能。它可以减少索引的存储空间占用,提高查询性能。
Compactor会定期扫描存储系统中的索引文件,将多个小的索引文件合并成一个大的索引文件,并删除过期的日志数据。
Memcaches属于外部第三方组件,支持的缓存类型有in-memory、redis和memcached。
它可以在Ingester、Query Frontend、Querier和Ruler上配置Results查询结果缓存、Index索引缓存或Chunks块缓存,以提高系统的响应速度和吞吐量。
推荐使用Loki的场景
不推荐使用Loki的场景
维度 | Loki | 传统方案(如ELK) |
|---|---|---|
存储成本 | 对象存储+标签索引,成本降低50%+ | 全文索引,存储成本高 |
查询性能 | 标签过滤+并行查询,毫秒级响应 | 全文搜索,复杂查询可能秒级以上 |
资源占用 | 低内存、低CPU | 高内存、高CPU |
扩展性 | 存储与计算分离,支持水平扩展 | 需同时扩展索引和存储节点 |
生态集成 | 与Prometheus/Grafana无缝集成 | 需额外集成第三方工具 |
# docker-compose.yml
version: '3'
services:
loki:
image: grafana/loki:2.9.3
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
promtail:
image: grafana/promtail:2.9.3
volumes:
- /var/log:/var/log
- ./promtail-config.yml:/etc/promtail/config.yml
command: -config.file=/etc/promtail/config.yml
grafana:
image: grafana/grafana:10.3.2
ports:
- "3000:3000"
environment:
- GF_AUTH_ANONYMOUS_ENABLED=true
# promtail-config.yml
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: system
static_configs:
- targets:
- localhost
labels:
job: varlogs
__path__: /var/log/*.log
docker-compose up -d
我们首先了解一些它的基本语法结构与一些高级功能的基本语法。
基本语法:
{app="nginx"}{app="nginx"} |= "error"{app="nginx"} |= "error" |= "500" |= "@timestamp >= \"2023-01-01T00:00:00Z\""高级功能:
count_over_time({app="nginx"} |= "error"[1m]){app="nginx"} | json | label_format app="{{.app}}-{{.env}}"基本查询
{job="varlogs"} |= "error"
查询 job=varlogs 标签下包含 error 的日志。
时间范围过滤
{job="varlogs"} |= "error" |= "timeout" |~ `\d{3}ms` | json | line_format "{{.msg}}"
查询同时包含 error 和 timeout 的日志,匹配耗时(如 123ms),解析 JSON 字段,并格式化输出。


http://loki:3100,保存。

Loki 按标签索引日志,标签设计直接影响查询效率。
示例标签:
labels: job: "nginx" instance: "web-01" level: "error"
查询优化:
{job="nginx", instance="web-01", level="error"}
Loki 是 Kubernetes 环境下日志聚合的理想选择,其轻量级架构、低成本存储和与 Prometheus 生态的无缝集成,使其成为 ELK 的高效替代方案。
Loki 在 Kubernetes 中的部署通常包含以下组件:
组件 | 作用 | 部署方式 |
|---|---|---|
Loki Server | 日志存储与查询服务,接收 Promtail 推送的日志并存储到对象存储(如 S3/MinIO)。 | 通过 Helm Chart 或 Operator 部署。 |
Promtail | 日志采集 Agent,运行在每个 Node 或 Pod 中,采集日志并推送到 Loki。 | 以 DaemonSet 或 Sidecar 形式部署。 |
Grafana | 日志可视化工具,通过 LogQL 查询 Loki 中的日志。 | 独立部署或集成到现有 Grafana 实例。 |
对象存储 | 长期存储日志数据(如 S3、MinIO、GCS)。 | 需提前配置,Loki 通过 storage_config 接入。 |
使用官方 Helm Chart 一键部署:
# 添加 Grafana Helm 仓库
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update
# 部署 Loki Stack(包含 Loki、Promtail、Grafana)
helm install loki grafana/loki-stack \
--set grafana.enabled=true \
--set promtail.enabled=true \
--set loki.persistence.enabled=true \
--set loki.persistence.size=10Gi \
--set loki.persistence.storageClassName=standard \
--namespace logging --create-namespace
参数说明
persistence.enabled=true #启用持久化存储(默认使用本地存储,生产环境建议替换为对象存储)。
storageClassName #根据集群配置调整。
通过 ConfigMap 自定义 Promtail 的采集规则:
# promtail-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: promtail-config
namespace: logging
data:
promtail.yaml: |
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: kubernetes-pods-name
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app]
action: keep
regex: my-app # 只采集标签为 app=my-app 的 Pod 日志
- source_labels: [__meta_kubernetes_namespace]
target_label: namespace
- source_labels: [__meta_kubernetes_pod_name]
target_label: pod_name
应用配置
kubectl apply -f promtail-config.yaml
更新 Promtail Deployment
修改 loki-stack 中的 Promtail 配置,挂载自定义的 ConfigMap。
使用对象存储:修改 Loki 的 values.yaml,配置 S3/MinIO:
loki:
config:
storage_config:
aws:
s3: s3://your-bucket/loki
s3forcepathstyle: true
region: us-east-1
boltdb_shipper:
active_index_directory: /var/loki/index
cache_location: /var/loki/index_cache
shared_store: aws
持久化存储:若使用本地存储,需配置 storageClassName 和 size,避免数据丢失。
调整日志块大小
loki:
config:
chunk_store_config:
max_look_back_period: 30d # 限制日志查询范围
schema_config:
configs:
- from: 2023-01-01
store: boltdb-shipper
object_store: aws
schema: v12
index:
prefix: index_
period: 24h
限制日志保留时间
loki:
config:
table_manager:
retention_deletes_enabled: true
retention_period: 7d # 保留 7 天日志
启用租户 ID
loki:
config:
auth_enabled: true
ingester:
lifecycler:
ring:
kvstore:
store: memberlist
在 Promtail 中配置租户 ID
clients:
- url: http://loki:3100/loki/api/v1/push
tenant_id: "my-tenant" # 指定租户 ID
检查 Promtail 日志
kubectl logs -n logging <promtail-pod-name> -c promtail
验证标签匹配:确保 Promtail 的 relabel_configs 正确匹配目标 Pod 的标签。
{job="*"})。ingester 和 querier 的副本数。启用压缩
loki:
config:
compactor:
working_directory: /var/loki/compactor
shared_store: aws
缩短日志保留时间:调整 retention_period。
通过以上步骤,你可以在 Kubernetes 中高效部署 Loki,实现低成本、高性能的日志聚合与分析!
学习Loki需要从理论到实践逐步深入,结合官方文档、实践教程和社区资源,快速掌握其核心概念和操作方法。
再通过搭建本地环境、部署Kubernetes集群和构建日志仪表盘,逐步提升实战能力。同时,关注性能优化和故障排查,确保Loki在生产环境中的稳定运行。
#日志系统 #日志收集 #日志平台 #ELK #Loki #Kubernetes #Grafana #实用教程 #IT #运维 #科技 #Linux运维 #系统运维
👍 如果你喜欢这篇文章,请点赞并分享给你的朋友!