Lo.....k...i
一、简介
Grafana Labs 开源的日志收集组件,特点有:
- Loki 只对元数据建立索引,不做全文索引,将原始日志压缩存储在对象存储上,因此具有操作简单、低成本的优势;
- 通过使用与 Prometheus 相同的标签对日志进行索引和分组,这使得日志的扩展和操作效率更高;
- 专门为 Prometheus 和 Kubernetes 用户做了相关优化,更适合云原生场景。
组件功能及读写流程图:
二、安装
Loki 有多种安装模式,使用 Helm 安装时候对应多个 Chart,这里我们以:微服务模式的 Loki、使用外部 MinIO 存储进行说明。
2.1 安装 MinIO
MinIO 是开源的高性能、与 S3 兼容的对象存储系统,与云服务(如阿里云 OSS)相比更经济,与其他对象存储系统相比主要有部署运维简单、性能优秀,并且很好的支持云原生环境的特点,可以提供高性能、低成本的存储服务,非常适合小规模分布式存储需求;
基础概念:
- object:存储到 Minio 的基本对象,如文件、字节流、图片等等…
- Bucket:用来存储 object 的逻辑空间,每个 Bucket 之间的数据是相互隔离的,对于客户而言,就相当于一个存放文件的顶层文件夹;
- Drive:即存数据的磁盘,MinIO 中所有的对象数据都会存储在 Drive 里;
- Set:即一组 Drive 的集合,分布式部署根据集群规模自动划分一个或多个 Set。
MinIO 支持多种安装模式(单机模式、纠删码模式、分布式集群模式),可靠性和安装复杂程度各有侧重,我们以:在 k8s 集群中以 Helm 模式部署高可靠的分布式集群模式进行说明,安装参考文档
安装步骤:
-
k8s(1.19+)集群中创建命名空间:
kubectl create ns minio
-
配置 Helm Repo:
helm repo add minio https://charts.min.io/
-
根据需求指定安装参数执行安装(完整的配置项说明):
# 指定命名空间、设置管理员账户、分布式多节点(2 个)、指定存储类及存储大小(50Gi)、开启 console 域名访问 helm install --namespace minio \ --set persistence.enabled=true \ --set rootUser=admin \ --set rootPassword=your_password \ --set persistence.size=50Gi \ --set resources.requests.memory=1Gi \ --set persistence.storageClass=alicloud-disk-efficiency \ --set consoleIngress.enabled=true \ --set consoleIngress.hosts[0]=minio.your_domain.com \ --set mode=distributed,replicas=2 \ minio/minio --generate-name
-
解析域名到 k8s 集群 ingress 组件对应的 IP 即可通过设置的域名访问 minio-console
-
使用 s3 格式访问 MinIO 的话需要用到 endpoint,默认程序连接使用的 endpoint 默认为 MinIO 的 9000 端口,如:
http://minio-1677222035-svc.minio:9000
,如果程序限制了只能通过 http 协议的 80 或者 443 端口访问 Minio、不支持自定义端口,那么手动创建一个入口使用,Ingress 编排文件内容如下(svc.name 根据实际情况调整):apiVersion: networking.k8s.io/v1 kind: Ingress metadata: labels: app: minio name: minio-endpoint namespace: minio spec: rules: - host: minio-api.your_domain.com http: paths: - backend: service: name: minio-1677222035-svc port: number: 9000 path: / pathType: Prefix
-
【补充】:如果只是试用,可以极简安装(单节点模式、不持久存储):
helm install --set resources.requests.memory=512Mi --set replicas=1 --set persistence.enabled=false --set mode=standalone --set rootUser=rootuser,rootPassword=rootpass123 --generate-name minio/minio
MinIO 是 golang 语言开发,拥有一个高效的客户端:mc 可以进行 minio 管理等,也有 web 控制台(minio-console)进行页面化配置,按需使用。MinIO 支持身份管理和文件生命周期配置等,在使用的过程中可以根据功能划为 bucket 和用户以实现隔离。
基本使用步骤:
-
创建 Bucket
-
创建 Policies、用户(组)并进行角色绑定,以下一个指定用户读写指定 bucket 的 IAM 策略配置实例:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:DeleteObject", "s3:GetBucketLocation", "s3:GetObject", "s3:ListAllMyBuckets", "s3:ListBucket", "s3:PutObject" ], "Resource": ["arn:aws:s3:::loki-data/*"] } ] }
-
为指定用户创建 Access Keys 供程序连接使用。
2.2 安装 Loki
官方提供了多个 Chart 版本,说明如下:
-
grafana/loki
:单体 loki,性能支持线性伸缩; grafana/loki-stack
:loki 的工具栈,包括 loki、promtail、grafana 等,缺点是没有提供对接外部 MinIO 的配置;grafana/loki-distributed
:微服务模式的 loki 集群,性能上限最高,推荐生产环境使用;
-
在 MinIO 中创建专用的 Bucket 和认证信息(Service Accounts)。
-
k8s(1.19+)集群中创建命名空间:
kubectl create ns logging
-
配置 Helm Repo:
helm repo add grafana https://grafana.github.io/helm-charts
-
下载 Chart 安装包:
helm pull grafana/loki-distributed
-
解压:
tar xvf loki-distributed-0.69.6.tgz
-
修改 loki-distributed 目录下的 values.yaml 文件,自定义修改内容参考:
# 指定了用于保存数据的 minio 配置,核心的几个组件配置 2 个副本实现高可用,ingester 和 querier 配置持久化存储
loki:
structuredConfig:
ingester:
max_transfer_retries: 0
chunk_idle_period: 1h
chunk_target_size: 1536000
max_chunk_age: 1h
schema_config:
configs:
- from: 2020-09-07
# 配置 index 存在 boltdb-shipper 里,chunk 存在 minio 里
store: boltdb-shipper
object_store: minio
schema: v11
index:
prefix: loki_index_
period: 24h
storage_config:
minio:
endpoint: minio-1677222035-svc.minio.svc.cluster.local:9000
insecure: true
bucketnames: loki-data
region: cn-hangzhou-lx-1
access_key_id: your_acceddkey_id
secret_access_key: your_accesskey_secret
s3forcepathstyle: true
boltdb_shipper:
# 这里的 shared_store 是指定存储为外部 MinIO 的核心配置
shared_store: minio
active_index_directory: /var/loki/index
cache_location: /var/loki/cache
cache_ttl: 48h
distributor:
replicas: 2
ingester:
replicas: 2
persistence:
enabled: true
size: 20Gi
storageClass: alicloud-disk-efficiency
querier:
replicas: 2
persistence:
enabled: true
size: 20Gi
storageClass: alicloud-disk-efficiency
queryFrontend:
replicas: 2
gateway:
basicAuth:
enabled: true
username: loki-gateway
password: qjXkt2sdcJ6Kw6g
nginxConfig:
httpSnippet: |-
client_max_body_size 100M;
serverSnippet: |-
client_max_body_size 100M;
- 执行安装命令:
helm install -n logging loki ./loki-distributed
2.3 安装其他组件(Promtail、Grafana)
日志收集客户端的话,官方有专门为 Loki 定制的自己的 Promtail,也支持其他主流收集器,如 fluent-bit;
收集器配置参考:https://grafana.com/go/webinar/getting-started-shipping-logs-to-grafana-loki/
2.3.1 安装 Grafana:
- 下载 Chart 安装包:
helm pull grafana/grafana --version 6.50.8 --untar
- 修改 grafana 目录下的 values.yaml 文件,自定义修改内容参考:
ingress:
enabled: true
pathType: Prefix
hosts:
- monitor.your_domain.com
persistence:
type: pvc
enabled: true
storageClassName: alicloud-disk-efficiency
accessModes:
- ReadWriteOnce
size: 20Gi
finalizers:
- kubernetes.io/pvc-protection
adminUser: admin
adminPassword: your_admin_password
- 执行安装命令:
helm install -n logging grafana ./grafana
2.3.2 安装 Promtail
-
下载 Chart 安装包:
helm pull grafana/promtail --version 6.9.0 --untar
-
修改 fluent-bit 目录下的 values.yaml 文件,自定义修改内容参考:
默认是 daemonset 的安装模式,如果不做额外处理,只能采集 std 日志,不能采集自定义路径输出到文件的日志,如果要采集,需要另外的配置,如:使用 HostPath 给业务 pods 和 promtail 挂载专门的日志目录,业务 pods 写入,promtail 配置静态发现 static_configs 去读取并写入 Loki。
config:
# 配置 Promtail 连接到 Loki 的地址
clients:
- url: http://loki-loki-distributed-gateway/loki/api/v1/push
# 只采集指定命名空间 pod 的 std 日志
snippets:
scrapeConfigs: |
- job_name: kubernetes-pods
kubernetes_sd_configs:
- role: pod
namespaces:
names:
- mars-sat
- mars-pre
- 执行安装命令:
helm install -n logging promtail ./promtail
2.3.3 Promtail 配置说明
Promtail 默认通过一个 config.yaml 文件进行配置,使用 Helm 安装的时候,默认将创建一个 secret(可以通过把 configmap.enabled 设置为 true 指定为 configmap 类型)存储这个配置文件,配置说明文档
核心配置说明如下:
server
属性配置 Promtail 作为 HTTP 服务器的行为;clients
属性是日志投递配置,包含 Loki 的连接、认证(微服务模式部署的话是 distributor 负责承接,也可以直接投递给 gateway,由 gateway 转交)信息、日志发送行为控制等。scrape_configs
属性配置 Promtail 日志采集处理和标签管理;labels
配置:自定义识别该日志时使用的标签;relabel_configs
配置:实现在日志被抓取之前动态重写其标签集;
-
pipeline_stages
配置:解析和处理日志、自定义标签等,在发现操作结束后执行。 -
一个 pipeline 管道是由一组 stages 阶段组成的,在 Promtail 配置中一共有 4 种类型的 stages:
参考:https://mp.weixin.qq.com/s/LCSHlpvi9dBwCTqObU4a-g
Parsing stages
(解析阶段) 用于解析当前的日志行并从中提取数据,提取的数据可供其他阶段使用,主要包括:- docker:使用 docker 日志格式解析并提取日志,固定格式:
docker: {}
、不提供配置选项; - cri:使用标准 CRI 格式解析并提取日志,固定格式:
cri: {}
、不提供配置选项; - regex:使用 Google RE2 正则表达式提取数据;
- json:将日志行解析为 JSON 来提取数据,也可以接受 JMESPath 表达式来提取数据。
- docker:使用 docker 日志格式解析并提取日志,固定格式:
-
Transform stages
(转换阶段) 用于对之前阶段提取的数据进行转换,主要包括:- multiline:多行合并;
- template:在将数据设置为标签之前对其他阶段的数据进行操作,如连字符替换、大小写转换等。
Action stages
(处理阶段) 用于从以前阶段中提取数据并对其进行处理,包括:- timestamp:更改日志行的时间戳;
- labels:添加或修改现有日志行标签;
- output:修改输出的日志行内容;
- metrics:在提取的数据基础上创建一个 metrics 指标;
- tenant:设置租户 ID(分租户)。
Filtering stages
(过滤阶段) 可选择应用一个阶段的子集,或根据一些条件删除日志数据,主要包括:- match:根据配置的 LogQL 流选择器和过滤表达式相匹配,有条件地应用一组 stage 或删除日志数据;
- drop:根据配置来删除日志。