阅读 113

Loki生产环境集群方案

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

1.png


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

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

2.png


可以看到,最明显的有三大不同点:

  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路径为&lt;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

3.png


这个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


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐