Grafana Loki用NFS存储类运行后出现index client创建失败问题
Loki使用NFS存储时出现"error creating index client"导致CrashLoopBackOff的问题排查
问题描述
在Kubernetes集群中用NFS作为StorageClass部署Grafana Loki,初始状态正常,能正常收集日志。但运行1小时以上后,出现"error creating index client"错误,Loki实例进入CrashLoopBackOff状态;改用CephFS作为StorageClass时无此问题。
错误日志
level=error ts=2023-05-19T08:56:42.910299323Z caller=index_set.go:133 table-name=index_19496 msg="failed to open existing index file /data/loki/boltdb-shipper-cache/index_19496/loki-0 level=error ts=2023-05-19T08:56:42.918924014Z caller=index_set.go:133 table-name=index_19496 msg="failed to open existing index file /data/loki/boltdb-shipper-cache/index_19496/loki-0 level=error ts=2023-05-19T08:56:42.927720949Z caller=index_set.go:133 table-name=index_19496 msg="failed to open existing index file /data/loki/boltdb-shipper-cache/index_19496/loki-0 level=info ts=2023-05-19T08:56:42.935410135Z caller=index_set.go:422 table-name=index_19496 file-name=loki-0-1684483385508800075-1684483655.gz msg="downloaded file" total_time=3.96958 level=info ts=2023-05-19T08:56:42.938327437Z caller=index_set.go:422 table-name=index_19496 file-name=loki-0-1684483385508800075-1684484100.gz msg="downloaded file" total_time=6.71881 level=info ts=2023-05-19T08:56:42.941700856Z caller=index_set.go:422 table-name=index_19496 file-name=loki-0-1684483385508800075-1684485000.gz msg="downloaded file" total_time=10.0510 level=error ts=2023-05-19T08:56:42.949063385Z caller=index_set.go:265 table-name=index_19496 msg="sync failed, retrying it" err="recovered from panic opening boltdb file: runtime erro level=info ts=2023-05-19T08:56:42.952646375Z caller=index_set.go:422 table-name=index_19496 file-name=loki-0-1684483385508800075-1684485000.gz msg="downloaded file" total_time=3.03557 level=info ts=2023-05-19T08:56:42.953549481Z caller=index_set.go:422 table-name=index_19496 file-name=loki-0-1684483385508800075-1684483655.gz msg="downloaded file" total_time=3.94770 level=info ts=2023-05-19T08:56:42.953649583Z caller=index_set.go:422 table-name=index_19496 file-name=loki-0-1684483385508800075-1684484100.gz msg="downloaded file" total_time=4.05850 level=error ts=2023-05-19T08:56:42.961398153Z caller=index_set.go:265 table-name=index_19496 msg="sync failed, retrying it" err="recovered from panic opening boltdb file: invalid free level=error ts=2023-05-19T08:56:42.961514568Z caller=index_set.go:104 table-name=index_19496 msg="failed to initialize table index_19496, cleaning it up" err="recovered from panic ope recovered from panic opening boltdb file: invalid freelist page: 0, page type is unknown<00> error creating index client github.com/grafana/loki/pkg/storage.(*store).storeForPeriod /src/loki/pkg/storage/store.go:245 github.com/grafana/loki/pkg/storage.(*store).init /src/loki/pkg/storage/store.go:162 github.com/grafana/loki/pkg/storage.NewStore /src/loki/pkg/storage/store.go:145 github.com/grafana/loki/pkg/loki.(*Loki).initStore /src/loki/pkg/loki/modules.go:522 github.com/grafana/dskit/modules.(*Manager).initModule /src/loki/vendor/github.com/grafana/dskit/modules/modules.go:120 github.com/grafana/dskit/modules.(*Manager).InitModuleServices /src/loki/vendor/github.com/grafana/dskit/modules/modules.go:92 github.com/grafana/loki/pkg/loki.(*Loki).Run /src/loki/pkg/loki/loki.go:341 main.main /src/loki/cmd/loki/main.go:105 runtime.main /usr/local/go/src/runtime/proc.go:255 runtime.goexit /usr/local/go/src/runtime/asm_amd64.s:1581 error initialising module: store github.com/grafana/dskit/modules.(*Manager).initModule /src/loki/vendor/github.com/grafana/dskit/modules/modules.go:122 github.com/grafana/dskit/modules.(*Manager).InitModuleServices /src/loki/vendor/github.com/grafana/dskit/modules/modules.go:92 github.com/grafana/loki/pkg/loki.(*Loki).Run /src/loki/pkg/loki/loki.go:341 main.main /src/loki/cmd/loki/main.go:105 runtime.main /usr/local/go/src/runtime/proc.go:255 runtime.goexit /usr/local/go/src/runtime/asm_amd64.s:1581 level=error ts=2023-05-19T08:56:42.962065413Z caller=log.go:103 msg="error running loki" err="recovered from panic opening boltdb file: invalid freelist page: 0, page type is unknown< Stream closed EOF for ecc-devops/loki-0 (loki)
环境配置
- 操作系统:3节点Ubuntu 20.04 Kubernetes集群
- NFS配置:
/mnt/nfs_share *(rw,async,no_subtree_check,all_squash)
- StorageClass:通过Helm部署的nfs-subdir-external-provisioner
- Loki:来自grafana/loki-stack Helm Chart
已尝试方案
- 手动创建PV替代StorageClass,仍报错
- 修改NFS配置参数,仍报错
- 重启所有K8s节点上的nfs-server、rpcbind,无效
原因分析
核心问题出在Loki默认使用的BoltDB索引与NFS存储的兼容性冲突:
- BoltDB的依赖特性:BoltDB是单进程文件型KV数据库,依赖底层存储提供强一致性、可靠的文件锁机制,以及写入操作的原子性保证。
- NFS的缺陷:
- 默认
async配置会导致数据写入缓存就返回确认,未持久化到磁盘前如果出现网络或服务器故障,会造成BoltDB文件损坏,出现invalid freelist page这类错误。 - NFS的文件锁实现(NLM)存在延迟或不可靠性,当Loki的boltdb-shipper组件频繁读写索引文件时,锁竞争会导致文件状态不一致,最终损坏索引。
- NFS的一致性模型无法满足BoltDB对文件元数据实时同步、页缓存一致性的严格要求,长期运行后必然出现索引文件损坏。
- 默认
解决方案
方案1:优化NFS配置适配BoltDB
- 修改NFS导出配置,将
async改为sync,确保数据持久化到磁盘后再返回写入确认:/mnt/nfs_share *(rw,sync,no_subtree_check,all_squash) - 确保NFS相关锁服务正常运行:
systemctl enable --now rpc-statd nfs-lock systemctl restart nfs-server - 清理已损坏的BoltDB索引文件后重新启动Loki:
# 进入Loki Pod kubectl exec -it loki-0 -n ecc-devops -- sh # 删除损坏的索引缓存 rm -rf /data/loki/boltdb-shipper-cache/* # 退出后重启Pod kubectl delete pod loki-0 -n ecc-devops
方案2:切换Loki索引存储类型
如果NFS优化后仍无法解决,建议改用Loki支持的更兼容的索引存储:
- 使用TSDB索引(推荐,Loki 2.4+支持):TSDB是Loki原生的索引格式,对分布式存储兼容性更好。修改Helm values.yaml:
loki: storage: type: tsdb tsdb: dir: /data/loki/tsdb schema_config: configs: - from: "2023-05-01" store: tsdb object_store: filesystem schema: v13 index: prefix: index_ period: 24h - 重新部署Loki:
helm upgrade loki grafana/loki-stack -f values.yaml -n ecc-devops
方案3:改用兼容的存储方案
- 单实例场景:使用
hostPath或local存储类,避免NFS的一致性问题。 - 多实例场景:继续使用CephFS这类原生支持强一致性和可靠文件锁的分布式存储,这也是你已验证可行的方案。
内容的提问来源于stack exchange,提问作者frogben
相关产品推荐
相关产品推荐

