
Loki 是 Grafana Labs 开发的开源日志聚合系统,于 2019 年 11 月发布第一个稳定版本。与传统的 ELK(Elasticsearch, Logstash, Kibana)栈相比,Loki 采用了与众不同的设计哲学——它只索引日志的元数据(标签),而不索引日志内容本身,这使得 Loki 在资源消耗和运营成本上大幅降低。Loki 的架构灵感来源于 Prometheus,采用了类似的标签模型,使得日志查询与监控指标查询能够无缝结合。
Loki 的核心设计理念体现在三个方面:首先,通过避免索引日志内容来降低存储成本;其次,充分利用云原生生态系统,与 Kubernetes、Prometheus 和 Grafana 紧密集成;最后,保持系统简单易用,降低运维复杂度。这种设计使得 Loki 特别适合在云原生环境中作为日志收集和分析解决方案。
与 ELK 相比,Loki 具有明显的优势和劣势。优势主要体现在:资源消耗极低,尤其是存储空间相比 ELK 可减少 10 倍以上;部署和运维简单,组件较少;与 Prometheus 和 Grafana 生态无缝集成,使用相同的标签系统进行查询和聚合。
然而,Loki 也有其局限性:功能相对单一,主要专注于日志的存储和查询,不具备 ELK 栈中 Elasticsearch 强大的数据分析和处理能力;技术相对新颖,社区和生态系统不如 ELK 成熟;不适合需要复杂日志分析和处理的重型应用场景。
Loki 系统由三个主要组件构成:
这三个组件协同工作,构成了完整的日志收集、存储和查询链条。在 Ubuntu Server 上部署时,需要根据实际需求选择合适的部署模式和配置参数。
在 Ubuntu Server 上部署 Loki 之前,需要确保系统满足基本要求。对于测试或开发环境,建议至少 2GB RAM 和 20GB 存储空间;而对于生产环境,则需要根据日志量和查询负载确定资源配置。
更新系统软件包是第一步:
sudo apt update
sudo apt upgrade -y安装必要的工具:
sudo apt install -y wget curl unzip tar make gcc git对于 Ubuntu Server,还需要配置防火墙规则,开放 Loki 相关端口:
sudo ufw allow 3100/tcp # Loki
sudo ufw allow 9080/tcp # Promtail
sudo ufw allow 3000/tcp # Grafana
sudo ufw enable虽然 Loki 支持多种部署方式,但 Docker 部署最为简便。首先安装 Docker:
# 安装 Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# 将当前用户加入 docker 组
sudo usermod -aG docker $USER
# 重新登录使更改生效
newgrp docker接着安装 Docker Compose:
# 下载 Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 赋予执行权限
sudo chmod +x /usr/local/bin/docker-compose
# 验证安装
docker-compose --version为 Loki 创建合适的目录结构有助于后续管理和维护:
# 创建主目录
sudo mkdir -p /usr/local/docker/lokis
cd /usr/local/docker/lokis
# 创建各组件子目录
mkdir -p grafana/conf
mkdir -p loki/conf
mkdir -p loki/data/{index,chunks,wal}
mkdir -p promtail/conf
# 设置权限
sudo chmod -R 777 /usr/local/docker/lokis合理的目录结构使得配置文件、数据和日志的管理更加清晰,也便于后续的备份和迁移操作。
单体模式是 Loki 最简单的部署方式,所有组件运行在单个进程中,非常适合小规模系统或测试环境。在这种模式下,Loki 每天处理的日志量通常不超过 100GB。
要部署单体模式的 Loki,可以使用以下 Docker 命令:
docker run -d --name loki \
-p 3100:3100 \
-v /usr/local/docker/lokis/loki/conf:/etc/loki \
-v /usr/local/docker/lokis/loki/data:/loki \
grafana/loki:latest \
-config.file=/etc/loki/config.yaml或者通过 -target=all 参数明确指定单体模式:
docker run -d --name loki \
-p 3100:3100 \
-v /usr/local/docker/lokis/loki/conf:/etc/loki \
-v /usr/local/docker/lokis/loki/data:/loki \
grafana/loki:latest \
-target=all \
-config.file=/etc/loki/config.yaml单体模式的优势在于部署简单、资源消耗少、运维复杂度低。劣势是扩展性受限,无法通过增加实例来提升性能,且单个组件故障可能导致整个服务不可用。
简单可扩展模式是大多数生产环境的首选方案。这种模式将 Loki 组件分割到三个独立的执行路径中:
在简单可扩展模式下,每个路径可以独立扩展:
启动不同路径组件时,需要通过 -target 参数指定:
# 启动 Write Path
-target=write
# 启动 Read Path
-target=read
# 启动 Backend Path
-target=backend这种模式支持每日 TB 级别的日志存储量,具有良好的水平扩展性,是平衡复杂度和性能的理想选择。
微服务模式适用于超大规模日志场景或需要对 Loki 进行精细化控制的环境。在这种模式下,每个 Loki 组件都独立运行,包括:
微服务模式的优势在于极高的灵活性和可扩展性,每个组件都可以根据实际负载独立扩展和优化。劣势是部署和运维复杂度极高,需要深入理解各个组件的功能和相互关系。
在 2.9 版本的 Loki 中,需要运行的组件多达 11 个,包括 Cache Generation Loader、Overrides Exporter 等较为边缘的组件。这种模式通常只在日日志量达到 PB 级别的超大规模环境中使用。
在选择部署模式时,需要考虑以下因素:
对于大多数场景,从单体模式开始,随着业务增长逐步过渡到简单可扩展模式是较为合理的演进路径。
Loki 的配置文件采用 YAML 格式,包含多个配置段。以下是关键配置项的详细说明:
# Loki 主配置文件:/usr/local/docker/lokis/loki/conf/config.yaml
auth_enabled: false
server:
http_listen_port: 3100
grpc_listen_port: 9095
grpc_server_max_recv_msg_size: 1572864000
grpc_server_max_send_msg_size: 1572864000
ingester:
lifecycler:
address: 127.0.0.1
ring:
kvstore:
store: inmemory
replication_factor: 1
final_sleep: 0s
chunk_idle_period: 5m
chunk_retain_period: 30s
max_transfer_retries: 0
schema_config:
configs:
- from: "2023-10-23"
index:
period: 24h
prefix: loki_index_
object_store: filesystem
schema: v11
store: boltdb-shipper
storage_config:
boltdb_shipper:
active_index_directory: /loki/boltdb-index
cache_location: /loki/boltdb-cache
filesystem:
directory: /loki/chunks
limits_config:
retention_period: 240h
ingestion_rate_mb: 32
ingestion_burst_size_mb: 64配置说明:
server 部分定义了 Loki 服务的监听端口和 gRPC 配置。在生产环境中,可能需要调整 grpc_server_max_recv_msg_size 和 grpc_server_max_send_msg_size 以处理大型消息。ingester 部分控制日志数据的内存处理。chunk_idle_period 决定内存中的日志块多久后被刷新到存储,较短的周期可以减少内存使用但增加存储操作。schema_config 定义数据存储模式。上面的配置使用 filesystem 作为对象存储,适合测试环境。生产环境应使用 s3、gcs 或其他分布式存储。storage_config 配置存储后端。这里使用本地文件系统,生产环境应配置分布式存储。limits_config 设置系统限制,包括数据保留时间和摄入速率限制。ingestion_rate_mb 和 ingestion_burst_size_mb 控制日志摄入速率,防止系统过载。Docker Compose 可以简化多容器应用的部署。以下是完整的 docker-compose.yml 文件:
version: '3'
services:
loki:
image: grafana/loki:latest
container_name: loki
ports:
- "3100:3100"
- "9095:9095"
command: -config.file=/etc/loki/config.yaml
volumes:
- ./loki/conf:/etc/loki
- ./loki/data/loki:/loki
networks:
- loki-network
promtail:
image: grafana/promtail
container_name: promtail
restart: always
ports:
- 9080:9080
volumes:
- ./promtail/promtail-config.yaml:/opt/promtail-config.yaml
- /var/log:/var/log
- /usr/local/docker/javaapp/fxt-system/logs/fxt-sys-server_10201/:/data/server/system/logs/
- /usr/local/docker/javaapp/fxt-gateway/logs/fxt-gateway-center_10001/:/data/server/gateway/logs/
- /etc/localtime:/etc/localtime:ro
privileged: true
deploy:
resources:
limits:
memory: 2G
reservations:
memory: 200M
logging:
driver: json-file
options:
max-size: "200m"
max-file: "4"
command: ["-config.file=/opt/promtail-config.yaml"]
networks:
- loki-network
grafana:
image: grafana/grafana
container_name: grafana
restart: "always"
ports:
- "3000:3000"
volumes:
- ./grafana/data:/var/lib/grafana
- ./grafana/conf/defaults.ini:/etc/grafana/grafana.ini
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin123
networks:
- loki-network
networks:
loki-network:
driver: bridge启动服务:
cd /usr/local/docker/lokis
docker-compose up -d验证服务状态:
docker-compose ps
curl http://localhost:3100/readyPromtail 是 Loki 的日志收集代理,负责发现、提取和发送日志到 Loki。以下是典型的 Promtail 配置:
# Promtail 配置文件:/usr/local/docker/lokis/promtail/conf/promtail-config.yaml
server:
http_listen_port: 9080
grpc_listen_port: 0
grpc_server_max_recv_msg_size: 15728640
grpc_server_max_send_msg_size: 15728640
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: system-logs
static_configs:
- targets:
- localhost
labels:
job: system-logs
environment: production
host: server-01
__path__: /var/log/*.log
- job_name: application-logs
static_configs:
- targets:
- localhost
labels:
job: application-logs
environment: production
host: server-01
__path__: /data/server/**/logs/**/*.log
- job_name: docker-logs
docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 15s
relabel_configs:
- source_labels: ['__meta_docker_container_name']
regex: '/(.*)'
target_label: 'container'
- source_labels: ['__meta_docker_container_id']
regex: '/(.*)'
target_label: 'container_id'配置说明:
server 部分配置 Promtail 的 HTTP 和 gRPC 服务端口。在生产环境中,可能需要调整消息大小限制。positions 配置记录文件读取位置,确保在 Promtail 重启后能从断点继续收集日志。clients 配置 Loki 服务器的地址。当 Promtail 和 Loki 在同一 Docker 网络中时,可以使用容器名作为主机名。scrape_configs 是核心配置,定义如何发现和收集日志:job_name 标识不同的收集任务static_configs 用于静态配置日志路径docker_sd_configs 用于自动发现 Docker 容器日志__path__ 支持通配符,** 匹配多级目录日志路径配置需要注意几点:
/*.log/**/*.log标签管理是 Loki 中至关重要的概念。与 Prometheus 类似,Loki 使用标签对日志流进行索引和分组。最佳实践包括:
job、environment、host、application在多服务器环境中,需要在每台服务器上部署 Promtail,并配置统一的标签体系:
# 多服务器 Promtail 配置示例
scrape_configs:
- job_name: nginx-logs
static_configs:
- targets:
- localhost
labels:
job: nginx
environment: production
datacenter: dc-01
__path__: /var/log/nginx/*.log通过一致的 job 和 environment 标签,可以在 Grafana 中跨服务器查询和分析日志。
在 Ubuntu Server 上安装 Grafana:
# 添加 Grafana 仓库
sudo apt-get install -y software-properties-common
sudo add-apt-repository "deb https://packages.grafana.com/oss/deb stable main"
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
# 安装 Grafana
sudo apt-get update
sudo apt-get install grafana
# 启动服务
sudo systemctl enable grafana-server
sudo systemctl start grafana-server通过 Docker Compose 部署时,Grafana 已包含在编排文件中。访问 http://your-server-ip:3000,使用默认凭证(admin/admin)登录。
在 Grafana 中添加 Loki 数据源:
http://loki:3100(Docker 网络)或 http://your-server-ip:3100LogQL 是 Loki 的查询语言,类似于 Prometheus 的 PromQL。基础语法包括:
日志流选择器:
{job="nginx"}:选择 job 标签为 nginx 的所有日志流{environment=~"production|staging"}:使用正则表达式选择环境标签{job="api", level!="debug"}:多个标签条件组合日志过滤器:
|= "error":包含 "error" 的日志行!= "debug":不包含 "debug" 的日志行|~ "panic|fatal":正则表达式匹配!~ "info|debug":正则表达式排除度量查询:
rate({job="nginx"}[5m]):计算 Nginx 日志速率count_over_time({job="api"} |="error" [1h]):统计错误数量sum by (container) (rate({job="docker"} |~ "timeout" [5m])):按容器分组统计超时次数多步骤查询:
# 分析错误率随时间变化
sum(rate({job="application"} |="ERROR" [5m])) by (level)
/
sum(rate({job="application"}[5m])) by (level)日志解析和提取:
# 使用正则表达式提取结构化字段
{job="nginx"} | regexp `(?P<ip>\\d+\\.\\d+\\.\\d+\\.\\d+) .*?"(?P<method>\\w+) (?P<path>[^"]*)" (?P<status>\\d+)`
| status >= 500
| method != "GET"关联日志和指标:
在 Grafana 仪表板中,可以同时显示来自 Prometheus 的指标数据和来自 Loki 的日志数据,实现完整的可观测性。
Loki 的分布式架构依赖于一致性哈希算法来实现数据分片和负载均衡。在集群环境中,Ingester 服务将自己注册到哈希环中,每个 Ingester 拥有一个或多个 Token(虚拟节点)。
当 Distributor 接收到日志流时,它会计算日志流的哈希值(基于租户 ID 和标签),然后在哈希环上找到对应的 Ingester。这种机制确保了相同日志流总是路由到相同的 Ingester,保证了数据的一致性。
配置一致性哈希环:
# Loki 分布式配置
ingester:
lifecycler:
ring:
kvstore:
store: consul # 或 etcd、memberlist
consul:
host: consul:8500
replication_factor: 3
heartbeat_timeout: 1m
num_tokens: 128 # 虚拟节点数对于生产环境,需要外部的键值存储来维护哈希环状态。Consul 是常见选择:
安装 Consul:
# 下载 Consul
wget https://releases.hashicorp.com/consul/1.11.0/consul_1.11.0_linux_amd64.zip
unzip consul_1.11.0_linux_amd64.zip
sudo mv consul /usr/local/bin/
# 启动 Consul 服务器
consul agent -server -bootstrap-expect=1 -data-dir=/tmp/consul -bind=0.0.0.0 -client=0.0.0.0 -ui配置 Loki 使用 Consul:
# Loki 配置中使用 Consul
common:
ring:
kvstore:
store: consul
consul:
host: consul.service.consul:8500
ingester:
lifecycler:
ring:
kvstore:
store: consul
consul:
host: consul.service.consul:8500
replication_factor: 3复制因子(replication_factor)配置决定了每条日志数据被复制到多少个 Ingester 实例。较高的复制因子提供更好的故障容忍,但会增加存储和网络开销。
配置建议:
replication_factor: 1replication_factor: 2 replication_factor: 3当复制因子大于 1 时,Loki 使用仲裁一致性模型,Distributor 需要等待多数(quorum)Ingester 确认写入后才向客户端返回成功。
写路径高可用:
读路径高可用:
完整的集群配置示例:
# 集群模式 Loki 配置
target: querier # 或 ingester、distributor 等
frontend:
address: query-frontend:9095
querier:
engine:
timeout: 3m
query_parallelism: 32
ingester:
max_transfer_retries: 0
chunk_idle_period: 1h
chunk_block_size: 262144
chunk_retain_period: 30s
max_chunk_age: 1h
schema_config:
configs:
- from: 2020-10-24
store: boltdb-shipper
object_store: aws
schema: v11
index:
prefix: index_
period: 24h
storage_config:
aws:
s3: s3://region/bucket
s3forcepathstyle: true
boltdb_shipper:
active_index_directory: /loki/boltdb-index
cache_location: /loki/boltdb-cacheLoki 提供了多种限流机制,防止系统过载:
# 限流配置
limits_config:
# 全局日志摄入速率限制(MB/秒)
ingestion_rate_mb: 32
# 突发摄入大小(MB)
ingestion_burst_size_mb: 64
# 每个租户的日志流限制
max_streams_per_user: 10000
# 查询限制
max_query_length: 721h
max_query_parallelism: 32
# 保留期配置
retention_period: 240h限流策略调优:
ingestion_rate_mb 和 ingestion_burst_size_mbChunk 配置优化:
ingester:
chunk_idle_period: 30m # 块空闲时间,影响内存使用和查询性能
chunk_block_size: 262144 # 块大小
chunk_retain_period: 1m # 块保留期
max_chunk_age: 1h # 最大块年龄索引配置优化:
schema_config:
configs:
- from: 2023-01-01
index:
period: 24h # 索引周期,影响索引文件大小
prefix: loki_index_
object_store: filesystem
schema: v11
store: boltdb-shipper查询前端配置:
query_frontend:
compress_responses: true # 压缩响应减少带宽使用
# 查询拆分配置
parallelise_shardable_queries: true
max_query_capacity: 64
query_timeout: 5m
# 缓存配置
results_cache:
cache:
enable_fifocache: true
fifocache:
size: 1024
validity: 1h查询优化技巧:
关键监控指标:
rate(loki_distributor_bytes_received_total[1m])histogram_quantile(0.95, sum(rate(loki_query_frontend_query_duration_seconds_bucket[1m])) by (le))rate(loki_request_duration_seconds_count{status_code=~"5.."}[1m])loki_boltdb_shipper_upload_dir_size_bytesPrometheus 监控配置:
scrape_configs:
- job_name: 'loki'
static_configs:
- targets: ['loki:3100']
metric_relabel_configs:
- source_labels: [__name__]
regex: 'loki_.*'
action: keepGrafana 告警规则:
groups:
- name: Loki
rules:
- alert: LokiHighErrorRate
expr: rate(loki_request_duration_seconds_count{status_code=~"5.."}[5m]) > 0.1
for: 10m
labels:
severity: warning
annotations:
summary: "Loki high error rate"
description: "Loki error rate is {{ $value }} per second"认证与授权:
# 启用基础认证
auth_enabled: true
# 多租户配置
multitenancy:
enabled: true
# API 认证配置
server:
http_listen_port: 3100
grpc_listen_port: 9096
grpc_tls_cert_file: /path/to/cert
grpc_tls_key_file: /path/to/key网络安全性:
数据加密:
数据备份:
灾难恢复:
存储容量估算:
总存储需求 = 每日日志量 × 保留天数 × 压缩比 × 复制因子示例计算:
性能基准测试:
常见问题及解决方案:
调试工具和技巧:
/ready 和 /metrics 端点检查状态logcli 工具进行命令行查询和调试Loki 作为云原生时代的日志解决方案,以其简洁的架构、低廉的成本和与 Prometheus、Grafana 的无缝集成,正在成为越来越多组织的选择。特别是在 Kubernetes 环境中,Loki 能够天然地理解和应用标签体系,提供高效的日志管理和查询能力。
随着微服务和容器化技术的普及,传统的日志解决方案面临着成本高、复杂度大的挑战。Loki 通过只索引元数据而非日志内容的创新方法,在保持强大查询能力的同时,大幅降低了存储和运维成本。
Loki 项目仍在快速发展中,未来的重点方向包括:
要深入了解 Loki 并跟上最新发展,可以参考以下资源:
通过参与社区讨论和贡献,不仅可以解决遇到的问题,还能影响 Loki 的未来发展方向。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。