3

Loki生产环境集群方案

 3 years ago
source link: http://dockone.io/article/2434427
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Loki生产环境集群方案


很多新入坑Loki的小伙伴当看到distributor、ingester、querier以及各种依赖的三方存储时,往往都比较懵逼,不知道从哪儿入手。此外再加上官方的文档里面对于集群部署的粗浅描述,更是让新手们大呼部署太难。其实,除了官方的helm外,藏在Loki仓库的production目录里面有一篇生产环境的集群部署模式。

原文里面,社区采用的是docker-compose的方式来快速拉起一套Loki集群。虽然我们正式在生产环境中实施时,不会傻到用docker-compose部署在一个node上(显然这里我们强行不考虑docker-swarm)。不过里面关于Loki的架构和配置文件却值得我们学习。

那么,与纯分布式的Loki集群相比,这套方案有什么特别的呢?首先我们先来看看下面这张图:

可以看到,最明显的有三大不同点:
  1. Loki核心服务distributor、ingester、querier没有分离,而是启动在一个实例当中;
  2. 抛弃了Consul和etcd外部的KV存储,而是直接用memberlist在内存中维护集群状态;
  3. 使用boltdb-shipper替代其他日志索引方案
这样看起来,Loki集群的整体架构就比较清晰,且更少的依赖外部系统。简单总结了下,除了用于存储chunks和index而绕不开的S3存储外,还需要一个缓存服务用于加速日志查询和写入。

Loki2.0版本之后,对于使用boltdb存储索引部分做了较大的重构,采用新的boltdb-shipper模式,可以让Loki的索引存储在S3上,而彻底摆脱Cassandra或者谷歌的BigTable。此后服务的横向扩展将变得更加容易。关于bolt-shipper的更多细节,可以参考:https://grafana.com/docs/loki/ ... pper/

说得这么玄乎,那我们来看看这套方案的配置有哪些不一样呢?

memberlist

memberlist:  
join_members: ["loki-1", "loki-2", "loki-3"]  
dead_node_reclaim_time: 30s  
gossip_to_dead_nodes_time: 15s  
left_ingesters_timeout: 30s  
bind_addr: ['0.0.0.0']  
bind_port: 7946  

Loki的memberlist使用的是gossip协议来让集群内的所有节点达到最终一致性的。此部分的配置几乎都是协议频率和超时的控制,保持默认的就好

ingester

ingester:  
lifecycler:  
join_after: 60s  
observe_period: 5s  
ring:  
  replication_factor: 2  
  kvstore:  
    store: memberlist  
final_sleep: 0s 

ingester的状态通过gossip协议同步到集群的所有member当中,同时让ingester的复制因子为2。即一个日志流同时写入到两个ingster服务当中以保证数据的冗余。
社区的集群模式配置原生部分仍然显得不太够意思,除了memberlist的配置稍显诚意外,其它部分仍然不够我们对生产环境的要求。这里小白简单改造了一下,分享给大家。

storage

将index和chunks的存储统一让S3对象存储纳管,让Loki彻底摆脱三方依赖。
schema_config:  
configs:  
- from: 2021-04-25  
store: boltdb-shipper  
object_store: aws  
schema: v11  
index:  
  prefix: index_  
  period: 24h  

storage_config:  
boltdb_shipper:  
shared_store: aws  
active_index_directory: /loki/index  
cache_location: /loki/boltdb-cache  
aws:  
s3: s3://<S3_ACCESS_KEY>:<S3_SECRET_KEY>@<S3_URL>/<S3__BUCKET>    
s3forcepathstyle: true  
insecure: true

这里值得说明的就是用于存储日志流索引的是bolt_shipper,它是可以通过共享存储方式写到s3当中的。那么active_index_directory就是S3上的Bucket路径,cache_location则为Loki本地bolt索引的缓存数据。

事实上ingester上传到s3的index路径为<S3__BUCKET>/index/

Redis

原生的方案里并不提供缓存,这里我们引入Redis来做查询和写入的缓存。对于很多小伙伴纠结的是一个Redis共用还是多个Redis单独使用,这个看你集群规模,不大的情况下,一个Redis实例足以满足需求。
query_range:  
results_cache:  
cache:  
  redis:  
    endpoint: redis:6379  
    expiration: 1h  
cache_results: true  

index_queries_cache_config:  
redis:  
endpoint: redis:6379  
expiration: 1h  

chunk_store_config:  
chunk_cache_config:  
redis:  
  endpoint: redis:6379  
  expiration: 1h      
write_dedupe_cache_config:  
redis:  
  endpoint: redis:6379  
  expiration: 1h  

ruler

既然Loki以及做了集群化部署,当然ruler这个服务也得跟在切分。难以接受的是,社区这部分的配置竟然是缺失的。所以我们得自己补充完整。我们知道日志的ruler可以写在S3对象存储上,同时每个ruler实例也是通过一致性哈希环来分配自己的rules。所以这部分配置,我们可以如下参考:
ruler:  
storage:  
type: s3  
s3:  
  s3: s3://<S3_ACCESS_KEY>:<S3_SECRET_KEY>@<S3_URL>/<S3_RULES_BUCKET>  
  s3forcepathstyle: true  
  insecure: true  
  http_config:  
    insecure_skip_verify: true  
enable_api: true  
enable_alertmanager_v2: true  
alertmanager_url: "http://<alertmanager>"  
ring:  
  kvstore:  
  store: memberlist

支持Kubernetes

最后,最最最重要的是要让官方的Loki集群方案支持在Kubernetes中部署,否则一切都是瞎扯。由于篇幅的限制,我将manifest提交到GitHub上,大家直接clone到本地部署。

GitHub地址:https://github.com/CloudXiaoba ... ystem

这个manifest只依赖一个S3对象存储,所以你在部署到生产环境时,请务必预先准备好对象存储的AccessKey和SecretKey。将他们配置到installation.sh当中后,直接执行脚本就可以开始安装了。

文件中的ServiceMonitor是为Loki做的Prometheus Operator的Metrics服务发现,你可以自己选择是否部署。

本文介绍了官方提供的一种Loki生产环境下的集群部署方案,并在此基础上加入了一些诸如缓存、S3对象存储的扩展配置,并将官方的docker-compose部署方式适配到Kubernetes当中。官方提供的方案有效的精简了Loki分布式部署下复杂的结构,值得我们学习。

原文链接:https://mp.weixin.qq.com/s/qnt7JUzHLUU6Qs_tv5V0Hw

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK