# Helm 安装 Loki 以及使用 Promtail 进行日志采集(弹性集群)

安装环境:阿里云 ACK 集群 k8s 版本 1.28 Worker 节点 3 推荐单节点 4C16G 以上

# helm 更新

首先更新 Helm 源

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

# helm 安装配置 s3(使用阿里云 OSS)

阿里云 OSS 兼容 S3 的配置 需要提前创建三个 Loki 需要使用的 Bucket
分别名称为 xxx-chunks xxx-ruler xxx-admin

loki:
  commonConfig:
    replication_factor: 1
  schemaConfig:
    configs:
    - from: "2024-01-01"
      store: tsdb
      index:
        prefix: loki_index_
        period: 24h *#这里设置 oss 内日志保留的日期 24h 30d
      object_store: s3
      schema: v13
  storage:
    type: s3
    bucketNames: 
      chunks: xxx-loki-chunks
      ruler: xxx-loki-ruler
      admin: xxx-loki-admin
    s3:
      endpoint: oss-cn-beijing-internal.aliyuncs.com  #阿里云的 endpoint 地址 这里用的内网因为在 VPC 内部署的 K8s 网络
      region: cn-beijing #region 不设置也可以
      secretAccessKey: sxxxxxxxxxxxx  #SecretKey
      accessKeyId: LTAxxxxxxxxxxxxxxxx #KeyId
      s3ForcePathStyle: false 
      insecure: false
deploymentMode: SimpleScalable #部署模式选简单可伸缩
backend: #后端部署
  replicas: 3 #副本数量
  persistence: #这块是自定义挂载卷后面会解释为何这么配置
    storageClass: alibabacloud-cnfs-nas
    size: 5Gi
read: #只读 Pod
  replicas: 3
write: #写 Pod 这是个有状态副本
  replicas: 3
  persistence: 
    storageClass: alibabacloud-cnfs-nas #这块是自定义挂载卷后面会解释为何这么配置
    size: 5Gi
singleBinary:
  replicas: 0
minio: #关闭 minio 存储 这是一个本地类似 S3 结构的文件存储库 不推荐线上使用
  enabled: false
ingester:
  replicas: 0
querier:
  replicas: 0
queryFrontend:
  replicas: 0
queryScheduler:
  replicas: 0
distributor:
  replicas: 0
compactor:
  replicas: 0
indexGateway:
  replicas: 0
bloomCompactor:
  replicas: 0
bloomGateway:
  replicas: 0

首先到文档列表中获取 Object Storage Configuration
链接贴上 helm 安装弹性集群

一些详细的配置修改可以参考这个链接 helm 安装 chart—values 设置

修改完之后将文件存储为 values.yaml 但现在不能直接应用需要考虑以下两个问题

# 1. 阿里云设置卷对应的默认存储

由于无状态的 backend 及有状态的 write 需要提供卷存储

backend 需要提供 BoltDB Shipper 的磁盘空间本地缓存数据 并定期上传至 S3 中

write 则需要将 log 数据暂存在磁盘中 写入数据库后清除缓存

由于以上问题 我们需要检查阿里云 ACK 中是否存在未使用的存储类 如有直接修改 value.yml 反之请创建存储类 大小建议在 20GB 以上 修改 value.yml 指定刚创建的的存储类名称

# 2. 阿里云拉取镜像问题

自 Docker 关闭中国境内的镜像源之后 大部分镜像都需要挂代理获取

现在的方案为 docker.io 内的镜像直接使用 DaoCloud 的镜像仓库 非 docker.io 的镜像将使用代理服务器或海外服务器拉取镜像并上传至私人 Docker Registy 仓库

我的方案代理服务器拉取的镜像 push 到将是阿里云的镜像仓库产品个人版 将 value.yml 对应的例如(loki.image.registry loki.image.repository) 镜像修改成阿里云镜像仓库的地址

当然可以尝试下更换 Helm Charts 仓库

# 3. 配置免密组件 SA 豁免

关于阿里云镜像问题还需要注意一个很重要的点 第三方 helm 安装的应用如果使用自己账号内镜像仓库的镜像 如果之前配置了免密插件拉取镜像 需要设置对应 SA 或者为豁免所有 SA 的使用组件的权限

免密组件

这个组件安装的位置在 kube-system 下 相关配置查看配置文件名称

组件配置

将 yaml 中 watch-namespace 修改成 all 并重启 acr 免密组件

data:
  acr-api-version: '2018-12-01'
  acr-registry-info: |
    - instanceId: ""
  expiring-threshold: 15m
  service-account: '*'
  watch-namespace: all

# 4. 关闭验证与 X-Scope-OrgID

Grafana Loki 是一个多租户系统,不同租户之间的数据隔离,通过 X-Scope-OrgID 标识请求的租户。

Loki 默认以多租户模式运行 auth_enabled: true。promtail 和 Grafana 均需要验证才能访问

Grafana 租户查询隔离时,可以在 Grafana 设置 DataSource 中根据 HTTP 标头中的 X-Scope-OrgID 区分查询。

如果设置 auth_enabled: false Loki 将不进行验证 租户 ID 将设为 fake

# 安装 Promtail Damonset

设置 grafana helm 仓库

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

设置 Loki 后端地址

config:
  clients:
    - url: http://loki-gateway/loki/api/v1/push
      tenant_id: 1

安装 protail daemonset

helm upgrade --values values.yaml --install promtail grafana/promtail

设置 Loki 限流
使用默认的 limits_config 的配置在 Loki 后端中会出现以下的的错误

promptail-http-status-429-too-many-requests
msg="error sending batch, will retry" status=429 error="server returned HTTP status 429 Too Many Requests (429): Maximum active stream limit exceeded, reduce the number of active streams

根据限流配置调整以下配置

limits_config:
  #摄取器速率
  ingestion_rate_mb: 200
  #摄取器极限速率
  ingestion_burst_size_mb: 400
  per_stream_rate_limit: 512MB
  per_stream_rate_limit_burst: 1024MB
  max_entries_limit_per_query: 25000
  max_query_parallelism: 1024

# 安装 Grafana

没什么好说的 helm 直接安装

helm install grafana grafana/grafana --namespace monitoring

用以下指令获取 grafana 密码

kubectl get secret --namespace monitoring my-grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo

之后配置好 Loki 数据源就可以使用 Loki 查询日志了

# 架构解释

# Loki 弹性架构

Loki 弹性架构由一个复杂的读、写、存、缓存分离架构组成
弹性架构

# 1. 节点中的 Promtail 以 DaemonSet 的形式分布在各个节点 用于收集日志将日志 Push 到 Loki 中

Promtail 会使用 fsnotify 监听指定目录下的日志文件的创建和删除

对活跃的日志文件会起一个 goroutine 进行类似 tail -f 的读取,读取到的内容发送给 channel

会有一个单独的 goroutine 读取 channel 中的日志行 分批处理并进行标签处理后 发送给 Loki

promtail 工作流程

# 2.Loki 内的写流程

在弹性模式内 gateway 接收到 promtail push 的日志内容之后 会由负载均衡到 write 的多副本中任一副本

write 副本中具有 Distributor 功能 根据日志中的 TenantID、Labels 计算 Hash 根据 Hash 值分发到不同的 Ingester 上 其次功能还包括验证数据格式 标签预处理 以及速率限制等功能

write 副本中的 Ingester 会构建及刷新 Chunk 块 所有的 Chunk 块会在本地磁盘缓存(TSDB 的形式) 只有达到容量上限后 Chunk 块设为只读 并发送至 S3 存储端进行存储 并清除指定的 Chuck 信息

# 3.Index tsdb 缓存、Memcached 缓存与 Rulers

backend 副本会定期到 S3 中下载文件并进行合并、压缩 上传新的 index 到 S3 上 并在本地保存 TSDB cache

索引网关服务负责处理和提供元数据查询。主要用于 query frontend 查询 Index-Gateway 中的 chunk 引用 其中一部分主要用于指标查询

memcached 缓存两部分数据一种为 result-cache(查询结果的缓存)和 chunk-cache(由 Ingester 存储后的完整 chunk 缓存) 并在内部维护淘汰策略

backend 副本中的 Rulers 提供类似 promthus 的 AlertManager 的报警策略 另一方面 ruler 会根据评估标准配置对 query frontend 进行评估

# 4.Loki 内的查询流程

Loki 的查询一般是 Grafana 前端发出 LogQL 后经由 Gateway 指向 read 副本

其中 read 副本的 Querier 会解析 LogQL 并从 IndexGateway 中获取索引信息

优先查询 memcached 的 cache 无法查询到后将指向 S3 中的对应分片进行查询 查询出的结果将会同步结果到 result-cache 以便提高下次查询的速度

功能模式

Loki Overview

# 关于 Loki-Canary

Loki-canary 是一个相对独立的组件、主要用于 Loki 集群性能的评估
Loki-canary 作为 DamonSet 分布在各个节点上 会定期生成日志行 这些日志行会被 Promtail 采集并按照正常流程被 Loki 处理

Loki-canary 生成的 log 行一般由时间戳及填充字符串构成,之后 Loki Canary 将打开与 Loki 的 WebSocket 连接,并跟踪它创建的日志。当在 WebSocket 上收到日志时,日志消息中的时间戳将与内部数组进行比较,用以评估 Loki 的性能指标。

Loki-canary 会定期进行抽查 确保曾经上报的日志信息并没有丢失

除此之外 Loki-canary 进行指标查询 count_over_time 验证 Loki 的日志速率是否与其创建的日志速率是否相对应

Loki-canary架构

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

JoyseeKing 微信支付

微信支付

JoyseeKing 支付宝

支付宝

JoyseeKing 贝宝

贝宝