「LOGGING」- 部署 Grafana Loki 服务,实现日志集中管理

问题描述

我们采用 Promtail 来采集日志,Grafana Loki 来存储日志,并对日志进行集中管理(即单个 Grafana Loki 实例来管理多个集群日志)。

该笔记将记录:采用 Grafana Loki 进行日志集中管理的方法,若干需要考虑的问题,以及相关问题的解决办法;

解决方案

在部署前,我们需要考虑的问题:

部署方式

我们直接采用 Grafana Loki 的微服务式(分布式)部署方式,原因如下:
1)官方文档也推荐该部署模式,官方文档也表示模式也最适合 Kubernetes 部署;
2)也符合我们的部署场景,我们需要在 Kubernetes Cluster 中运行日志采集;

我们采用 Helm 进行部署,原因是不用引入新的技术栈。而未采用官方推荐的 Tanka 进行部署,原因是 Tanka 暂时还没有成为像 Helm 那样广泛使用,引入新的工具需要额外的学习成本、维护成本、培训成本;

代理认证

在我们的场景中,鉴于是多集群日志管理,流量需要通过公网(部署 VPN 需要而外成本,所以流量目前是通过公网的),所以我们需要对 Grafana Loki 进行认证,防止非法访问。

但是 Grafana Loki 本身并不提供认证功能(Authentication),需要增加前端服务来提供认证,比如 Nginx Reverse Proxy 等等。

不过,这是个常见需求,所以 Grafana Loki 的 Helm Chart 包含 Basic Auth 特性,在部署的设置打开相关配置即可。

关于 Basic Auth 的位置
1) 虽然 Basic Auth 是在 Grafana Loki Helm Chart 的 ingress 中进行设置,但是实际的 Basic Auth 是添加到 Nginx 当中的;
2)所以不管 Grafana 还是 Promtail 服务,当访问 Gateway 服务时,都需要配置相关的 Basic Auth 认证;

日志标签

我们需要区分来自不同集群的日志,即 Promtail 需要增加标签,以表明该日志所来自的集群。

如果在 scrape_configs/Job 中增加,则每个都需要增加响应的标签。所以,我们使用 clients.external_labels 属性,来为所有 clients 增加标签;

日志保留

Retention | Grafana Loki documentation

Compactor 执行日志清理工作,而日志保留时长通过 limits_config 进行控制;

部署 Loki 集群

helm repo add grafana https://grafana.github.io/helm-charts
helm repo update

helm show values grafana/loki-distributed > loki.helm-values.yaml
...(1)调整 s3 相关配置:地址为 Endpoint 域名,且域名不携带 Bucket 名称;
...(2)调整 Gateway 配置:开启 Ingress 访问;开启 Basic Auth 认证;

helm --namespace=loki --create-namespace                                       \
    upgrade --install loki grafana/loki-distributed                            \
    -f loki.helm-values.yaml                                                   \
    --create-namespace

关于 Ruler 组件:
问题描述:msg=”error running loki” err=”mkdir /etc/loki/rules: read-only file system…
解决方案:需要配置 ruler.directories 参数
[loki] msg=”error running loki” err=”mkdir /rules: read-only file” · Issue #577 · grafana/helm-charts
[loki-distributed] Ruler pod won’t start. err=”mkdir /etc/loki/rules…” · Issue #537 · grafana/helm-charts
helm-charts/charts/loki-distributed at main · grafana/helm-charts

常见问题汇总

Loki Cannot connect to Loki NoSuchKey The specified key does not exist. status code: 404, request id: xxx, host id:

Amazon S3 exception: “The specified key does not exist” – Stack Overflow
解决 Amazon S3 的 404 NoSuchKey 错误

问题描述:
在 Grafana 中,添加 Datasource 保存时,出现错误:Loki Cannot connect to Loki NoSuchKey The specified key does not exist. status code: 404, request id: 629CD87A3652D93638D8FEE2, host id:

原因分析:
然后,我们查看 Querier 日志,在其中看到相关信息,似乎是 S3 相关的错误。然后我们对 S3 相关的配置进行检查,尝试配置 aws.s3forcepathstyle: false 得以解决问题;
也有可能是其他原因,06/09/2022,我们再次遇到该错误。原因是 Compactor 清理的周期过短,导致 Chunk 被请求,而无法找到日志数据;

解决方案:
配置 aws.s3forcepathstyle: false 属性;

AccessDenied: S3 API Request made to Console port

问题描述:

...
AccessDenied: S3 API Request made to Console port. S3 Requests should be sent to API port.
	status code: 403, request id: , host id:
failed to get s3 object
github.com/grafana/loki/pkg/storage/chunk/aws.(*S3ObjectClient).GetObject
	/src/loki/pkg/storage/chunk/aws/s3_storage_client.go:389
...

环境信息:MinIO 通过的 S3 存储服务;

原因分析:配置错误,应该连接 9000 端口,而不是 9001 端口(这是管理端口);

解决方案:修改配置,使用 9000 端口;

NoSuchBucket: The specified bucket does not exist

Grafana Loki/Getting started

问题描述:

...
NoSuchBucket: The specified bucket does not exist
	status code: 404, request id: 16FE7D94B41B007D, host id:
failed to get s3 object
github.com/grafana/loki/pkg/storage/ch
unk/aws.(*S3ObjectClient).GetObject
	/src/loki/pkg/storage/chunk/aws/s3_storage_client.go:389
github.com/grafana/loki/pkg/storage/stores/shipper/storage.prefixedObjectClient.GetObject
	/src/loki/pkg/storage/stores/shipper/storage/prefixed_object_client.go:25
...

环境信息:MinIO 通过的 S3 存储服务;

原因分析:需要开启 aws.s3forcepathstyle: true 属性(我们参考 Grafana Loki/Getting started 才猜测到原因);

解决方案:配置 aws.s3forcepathstyle: true 属性;

参考文献

Installation | Grafana Loki documentation
Microservices deployment with Helm | Grafana Loki documentation
Promtail/Scraping | Grafana Loki documentation
Configuration | Grafana Loki documentation