Helm chart允许您在Kubernetes集群中配置、安装和升级Grafana Loki。

本文使用的是Loki Helm chart的5.5.3版本,并包含以下部分:

  • 配置存储
  • Helm Chart组件
  • Helm Chart值
  • 安装Loki
  • 将日志写入到Loki
  • 配置Grafana使用Loki数据源

Loki的helm chart在github中地址是“Helm chart for Grafana Loki in simple, scalable mode”

1.配置存储

可扩展的部署模式需要一个托管的对象存储,如AWS S3或Google Cloud Storage,或者一个自托管的存储,如Minio。而单个二进制安装只能使用文件系统进行存储。

本文假设Loki将以以上一种模式安装,并且已创建了一个values.yaml文件。

这里选择使用的存储为是一个已经存在的Minio集群,修改values.yaml配置文件:

 1minio:
 2  enabled: false
 3
 4loki:
 5  storage:
 6    bucketNames:
 7      chunks: chunks
 8      ruler: ruler
 9      admin: admin
10    type: s3
11    s3:
12      endpoint: <endpoint>
13      region: <region>
14      accessKeyId: <minio access key>
15      secretAccessKey: <minio access keysecret>
16      s3ForcePathStyle: false
17      insecure: false

在上面的values.yaml中,因为使用的是一个已经存在的minio集群,所以配置了minio.enabled=false,这样在安装Chart时将不会部署一个minio集群。而在loki.storage.s3下配置的是锁使用的minio集群的相关信息。

对于loki.storage.s3.accessKeyIdloki.storage.s3.secretAccessKey需要在Minio中创建Access Key,为设置其User Policy如下:

 1{
 2 "Version": "2012-10-17",
 3 "Statement": [
 4  {
 5   "Effect": "Allow",
 6   "Action": [
 7    "s3:GetBucketLocation",
 8    "s3:ListBucket",
 9    "s3:ListBucketMultipartUploads"
10   ],
11   "Resource": [
12    "arn:aws:s3:::loki-*"
13   ]
14  },
15  {
16   "Effect": "Allow",
17   "Action": [
18    "s3:AbortMultipartUpload",
19    "s3:DeleteObject",
20    "s3:GetObject",
21    "s3:ListMultipartUploadParts",
22    "s3:PutObject"
23   ],
24   "Resource": [
25    "arn:aws:s3:::loki-*/*"
26   ]
27  }
28 ]
29}

2.Helm Chart组件

Loki Read和Write: 默认情况下,Loki将以可扩展模式安装。它包括读取和写入组件。这两个组件可以独立进行扩展。

Dashboards: 包含用于监控Loki的Dashboards。这些Dashboard需要在下面描述的monitoring.serviceMonitormonitoring.selfMonitoring部分中定义的抓取配置。Dashboards通过ConfigMap部署,可以挂载在Grafana实例上。Dashboards需要安装Grafana AgentPrometheus Operator。Agent将Dashboards一起安装。

Canary: 默认情况下,该Chart默认安装了Canary及其告警功能。这是另一个验证Loki部署是否处于正常状态的工具。可以使用monitoring.lokiCanary.enabled=false来禁用它。

Gateway(网关):默认情况下,受Grafana的Tanka设置的启发,该Chart安装了网关组件,它是一个Nginx,用于公开Loki的API并自动代理请求到正确的Loki组件(读取或写入,或单体部署模式下的文件系统存储)。如果需要Ingress,则必须启用网关,因为Ingress仅公开网关。如果启用了网关,应配置Grafana和日志传送Agent(例如Promtail)以使用网关。如果启用了NetworkPolicies,则如果启用了网关,它们会有更多的限制。

Cache(缓存): 默认情况下,该Chart配置了内存缓存。如果该缓存对于您的部署不起作用,您应该设置memcache。

为简化部署,继续定制values.yaml文件,禁用Dashboards和Canary:

 1# Monitoring section determines which monitoring features to enable
 2monitoring:
 3  dashboards:
 4    # -- If enabled, create configmap with dashboards for monitoring Loki
 5    enabled: false
 6  rules:
 7    # -- If enabled, create PrometheusRule resource with Loki recording rules
 8    enabled: false
 9  # ServiceMonitor configuration
10  serviceMonitor:
11    # -- If enabled, ServiceMonitor resources for Prometheus Operator are created
12    enabled: false
13  # Self monitoring determines whether Loki should scrape its own logs.
14  # This feature currently relies on the Grafana Agent Operator being installed,
15  # which is installed by default using the grafana-agent-operator sub-chart.
16  # It will create custom resources for GrafanaAgent, LogsInstance, and PodLogs to configure
17  # scrape configs to scrape its own logs with the labels expected by the included dashboards.
18  selfMonitoring:
19    enabled: false
20    grafanaAgent:
21      installOperator: false
22  # The Loki canary pushes logs to and queries from this loki installation to test
23  # that it's working correctly
24  lokiCanary:
25    enabled: false
26
27test:
28  enabled: false

test依赖于监控,上面的配置中也把test禁用了。

3.Helm Chart值

helm chart值配置文档的地址是“Helm Chart Values”

4.安装Loki

这个Helm Chart安装后将在Kubernetes集群中运行Grafana Loki集群。

如果配置了对象存储,该将配置Loki以在可扩展模式下运行读写target,采用高可用架构(每个target有3个副本),设计用于与AWS S3对象存储一起使用。它还将配置度量(metrics)和日志的元监控(meta-monitoring)。

注意: 无法在文件系统存储上运行可扩展部署模式。

开始之前需要准备以下内容:

  1. 安装Helm 3或更高版本。请参考Helm安装文档。
  2. 运行中的Kubernetes集群。
  3. 如需使用元监控,需要安装Prometheus Operator。
  4. 可选项:为了获得更好的性能,可以部署Memcached。请参考缓存部分以了解如何配置Memcached。

需为write和backup target的PVC配置Storage Class,这个由具体情况决定,这里简单起见(只是为了测试)先配置由local-path-provisioner提供的local-path

1write:
2  persistence:
3    storageClass: local-path
4backend:
5  persistence:
6    storageClass: local-path

接下来在value.yaml中配置loki-gateway和它的ingress,将loki-gateway暴露到K8S集群外部:

 1gateway:
 2  ingress:
 3    enabled: true
 4    ingressClassName: nginx
 5    annotations:
 6      nginx.ingress.kubernetes.io/ssl-redirect: "false"
 7      nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
 8      nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
 9    hosts:
10      - host: loki.example.com
11        paths:
12          - path: /
13            pathType: ImplementationSpecific
14
15ingress:
16  enabled: false

注意: loki的helm chart中还提供了一个ingress用于将loki的各个组件暴露到k8s集群外部。这里将其禁用ingress.enabled=false,而是统一使用loki-gateway,因为loki的helm chart通过loki-gatway提供了对基本认证和设置多租户请求头的支持,这些内容将在以后的内容中学习。

下面将使用helm chart在k8s集群中以扩展模式部署loki。

下载loki的helm chart,这里下载的版本是helm-loki-5.5.3:

1wget https://github.com/grafana/helm-charts/releases/download/helm-loki-5.5.3/loki-5.5.3.tgz
1helm install loki loki-5.5.3.tgz -n loki  --create-namespace -f values.yaml

部署完成后到查看各个组件在k8s中正常启动:

 1kubectl get deploy,sts -n loki
 2NAME                                          READY   UP-TO-DATE   AVAILABLE   AGE
 3deployment.apps/loki-gateway                  1/1     1            1           5m36s
 4deployment.apps/loki-grafana-agent-operator   1/1     1            1           5m36s
 5deployment.apps/loki-read                     3/3     3            3           5m36s
 6
 7NAME                            READY   AGE
 8statefulset.apps/loki-backend   3/3     5m35s
 9statefulset.apps/loki-write     3/3     5m35s
10
11kubectl get po -n loki
12NAME                                           READY   STATUS    RESTARTS   AGE
13loki-backend-0                                 1/1     Running   0          5m44s
14loki-backend-1                                 1/1     Running   0          5m44s
15loki-backend-2                                 1/1     Running   0          5m44s
16loki-gateway-666dbc98c9-l99bl                  1/1     Running   0          5m44s
17loki-read-65c6646f4-fw7tq                      1/1     Running   0          5m44s
18loki-read-65c6646f4-mcck2                      1/1     Running   0          5m44s
19loki-read-65c6646f4-xmpw4                      1/1     Running   0          5m44s
20loki-write-0                                   1/1     Running   0          5m44s
21loki-write-1                                   1/1     Running   0          5m16s
22loki-write-2                                   1/1     Running   0          5m16s

测试一下从k8s集群外部访问loki-gateway:

1curl https://loki.example.com/loki/api/v1/status/buildinfo
2{"version":"2.8.2","revision":"9f809eda7","branch":"HEAD","buildUser":"root@e401cfcb874f","buildDate":"2023-05-03T11:07:54Z","goVersion":""}

5.将日志写入到Loki

这里先使用最简单的形式,在本地运行Promtail,并将日志写入到Loki中。

https://github.com/grafana/loki/releases中下载Promtail二进制文件:

1wget https://github.com/grafana/loki/releases/download/v2.8.2/promtail-linux-amd64.zip
2
3unzip promtail-linux-amd64.zip
4mv promtail-linux-amd64 promtail

创建配置文件:创建一个配置文件,用于指定Promtail如何查找和发送日志。下面是一个简单的配置文件示例:

promtail.yaml:

 1# Disable the HTTP and GRPC server.
 2server:
 3  disable: true
 4
 5positions:
 6  filename: /tmp/positions.yaml
 7
 8clients:
 9  - url: https://loki.example.com/loki/api/v1/push
10    headers:
11      X-Scope-OrgID: org1
12
13scrape_configs:
14  - job_name: system
15    static_configs:
16      - targets:
17          - localhost
18        labels:
19          job: varlogs
20          __path__: /var/log/*log

关于promtail.yaml配置文件说明如下:

  • 这里使用promtail只是为了抓取本地系统/var/log/目录下以名称以log结尾的日志文件,因此在配置文件中使用server.disable=true禁用了promtail的http和grpc端口监听。
  • positions字段用于指定位置文件配置。位置文件用于跟踪Promtail在读取日志文件时的位置,以便在Promtail重启后可以继续从上次停止的位置继续读取。位置文件是一个YAML文件,其中包含了每个日志文件的位置信息。当Promtail读取完一个日志文件后,它会将文件的路径和读取位置记录在位置文件中。当Promtail重启时,它会读取位置文件,并从上次读取的位置开始继续读取日志文件,以确保不会丢失任何日志。
  • clients[0].url中配置了loki-gateway的地址,这里的promtail位于k8s集群外部的一台本地服务器上,因此url配置了loki gateway ingress暴露的域名。如果promtail在k8s集群内部,应该使用loki gateway的k8s service。
  • Loki默认在多租户模式下运行,Loki在多租户模式下运行时,所有数据,包括内存和长期存储中的数据,都可以通过租户ID进行分区,该ID来自请求中的X-Scope-OrgIDHTTP请求头。clients[0].headers中设置的X-Scope-OrgID: org1,表示这里的promtail发送的日志将在loki中以租户id org1进行分区,即是租户org1的数据。

使用以下命令运行Promtail:

1./promtail -config.file=promtail.yaml

promtail正常启动后会跟踪并收集/var/log/目录下以名称以log结尾的日志文件中的日志内容,并将日志发送到loki中。

Loki会索引日志的元数据即labels,日志数据本身会被压缩并分块(chunck)存储在对象存储中。这里的promtail发送的日志会生成两个label: jobfilename。 此时通过调用loki的API可以查看:

1curl -H "X-Scope-OrgID: org1"  https://loki.example.com/loki/api/v1/labels
2{"status":"success","data":["filename","job"]}

注意在调用API时,也要通过X-Scope-OrgID请求头指定租户id

接下来通过API查询一下jobfilename这两个label的值:

1curl -H "X-Scope-OrgID: org1"  https://loki.example.com/loki/api/v1/label/job/values
2{"status":"success","data":["varlogs"]}
3
4curl -H "X-Scope-OrgID: org1"  https://loki.example.com/loki/api/v1/label/filename/values
5{"status":"success","data":["/var/log/dnf.librepo.log","/var/log/dnf.log","/var/log/dnf.rpm.log","/var/log/hawkey.log","/var/log/kdump.log"]}

Loki的日志流由,由标签键和值的组合定义,可以通过API /loki/api/v1/series查询。

使用/loki/api/v1/query_range API查询一下最近1个小时内的日志:

1curl -H "X-Scope-OrgID: org1"  -G 'https://loki.example.com/loki/api/v1/query_range' \
2  --data-urlencode 'query={job="varlogs"}' \
3  --data-urlencode 'since=1h'
4
5# 省略输出
6{"status":"success","data":{"resultType":"streams","result":[{"stream":{"filename":"/var/log/dnf.log","job":"varlogs"}...

6.配置Grafana使用Loki数据源

最后,可以在Grafana中创建并配置Loki数据源,就可以在Grafana的Explore进行查询了。

  • 数据源配置中的URL设置为loki-gateway的地址
  • 注意在创建Loki数据源时,也需要在Custom HTTP Headers中设置X-Scope-OrgID指定租户id

grafana-explore-loki.png

参考