前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Loki & Promtail 详解

Loki & Promtail 详解

作者头像
gopher云原生
发布2021-10-18 11:04:24
14.3K0
发布2021-10-18 11:04:24
举报
文章被收录于专栏:gopher云原生

“主流的日志收集架构一般采用 ELK/EFK/EFLK ,但是这些都比较适合在重量级、需要日志数据清理的场景下使用。 云原生环境下, Grafana + Loki + Promtail 横空出世。 “Like Prometheus, but for logs.” ”

整体介绍

Loki 是受 Prometheus 启发的水平可扩展、高可用、多租户日志聚合系统。非常适合采集 Kubernetes Pod 的日志,关键 Loki 还易于操作且更加轻量级(相比 ELK/EFK/EFLK )。

在 Loki 架构中有以下几个概念:

  • Grafana:相当于 EFK 中的 Kibana ,用于 UI 的展示。
  • Loki:相当于 EFK 中的 ElasticSearch ,用于存储日志和处理查询。
  • Promtail:相当于 EFK 中的 Filebeat/Fluentd ,用于采集日志并将其发送给 Loki 。
  • LogQL:Loki 提供的日志查询语言,类似 Prometheus 的 PromQL,而且 Loki 支持 LogQL 查询直接转换为 Prometheus 指标。

Loki整体架构

Promtail 介绍

Promtail 将本地日志内容传送到 Loki 实例。需要监控的应用程序的机器上都需要部署该组件。

它的主要工作流程可以划分为:

  • 使用 fsnotify 监听指定目录下(例如:/var/log/*.log)的文件创建与删除
  • 对每个活跃的日志文件起一个 goroutine 进行类似 tail -f 的读取,读取到的内容发送给 channel
  • 有一个单独的 goroutine 会读取 channel 中的日志行,分批并附加上标签后推送给 Loki

promtail原理

Loki 介绍

Loki 是用来接受、存储、处理、查询日志的集合体。

Loki 采用读写分离架构,关键组件有:

  • Distributor 分发器:日志数据传输的“第一站”,Distributor 分发器接收到日志数据后,根据元数据和 hash 算法,将日志分批并行地发送到多个 Ingester 接收器上
  • Ingester 接收器:接收器是一个有状态的组件,在日志进入时对其进行 gzip 压缩操作,并负责构建和刷新 chunck 块,当 chunk 块达到一定的数量或者时间后,就会刷新 chunk 块和对应的 Index 索引存储到数据库中
  • Querier 查询器:给定一个时间范围和标签选择器,Querier 查询器可以从数据库中查看 Index 索引以确定哪些 chunck 块匹配,并通过 greps 将结果显示出来,它还会直接从 Ingester 接收器获取尚未刷新的最新数据
  • Query frontend 查询前端:查询前端是一个可选的组件,运行在 Querier 查询器之前,起到缓存,均衡调度的功能,用于加速日志查询

loki组件通信

Loki 提供了两种部署方式:

  • 单体模式,ALL IN ONE:Loki 支持单一进程模式,可在一个进程中运行所有必需的组件。单进程模式非常适合测试 Loki 或以小规模运行。不过尽管每个组件都以相同的进程运行,但它们仍将通过本地网络相互连接进行组件之间的通信(grpc)。使用 Helm 部署就是采用的该模式。
  • 微服务模式:为了实现水平可伸缩性,Loki 支持组件拆分为单独的组件分开部署,从而使它们彼此独立地扩展。每个组件都产生一个用于内部请求的 gRPC 服务器和一个用于外部 API 请求的 HTTP 服务,所有组件都带有 HTTP 服务器,但是大多数只暴露就绪接口、运行状况和指标端点。

Loki组件架构

使用 Helm 部署

以 Helm 部署 Loki (StatefulSet 方式) 和 Promtail(DaemonSet 方式)采集 k8s pod 应用的日志为例

代码语言:javascript
复制
# 添加 grafana 源
helm repo add grafana https://grafana.github.io/helm-charts

# 创建命名空间
kubectl create ns grafana
kubectl create ns loki

# 部署 grafana,并开启 NodePort 访问
# 用户名 admin
# 密码 kubectl get secret --namespace grafana grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo
helm install grafana grafana/grafana --set "service.type=NodePort" -n grafana

# 部署 loki
helm install loki grafana/loki -f loki-config.yaml -n loki

# 部署 promtail
helm install promtail grafana/promtail -f promtail-config.yaml -n loki

loki-config.yaml 配置:

代码语言:javascript
复制
# loki 配置
config:
  limits_config:
   # Distributor 分发器的日志接收速率限制
    ingestion_rate_mb: 8
# 实例数
replicas: 1
# 限制使用资源
resources:
  limits:
    cpu: 2000m
    memory: 2048Mi
# 挂载宿主机时间
extraVolumeMounts:
  - name: host-time
    mountPath: /etc/localtime
extraVolumes:
  - name: host-time
    hostPath:
      path: /etc/localtime

promtail-config.yaml 配置:

代码语言:javascript
复制
extraArgs:
  # 添加全局静态标签 cluster:dev
  - -client.external-labels=cluster=dev
# 限制使用资源
resources:
  limits:
    cpu: 512m
    memory: 512Mi
# 挂载宿主机时间
extraVolumeMounts:
  - name: host-time
    mountPath: /etc/localtime
extraVolumes:
  - name: host-time
    hostPath:
      path: /etc/localtime
# promtail 配置
config:
  lokiAddress: http://loki-ip:3100/loki/api/v1/push
  snippets:
    # 清除默认配置
    scrapeConfigs: ""
    # 自定义配置
    extraScrapeConfigs: |
      # 通过 kubernetes_sd_configs:pod 配置 pod 日志,参考 https://grafana.com/docs/loki/latest/clients/promtail/configuration/#kubernetes_sd_config
      - job_name: kubernetes-pods-app
        # 流水线
        pipeline_stages:
          {{- toYaml .Values.config.snippets.podPipelineStages | nindent 4 }}
        kubernetes_sd_configs:
          - role: pod
        relabel_configs:
          # 把 pod 所有的标签暴露出来
          - action: labelmap
            regex: __meta_kubernetes_pod_label_(.+)
            replacement: $1
            target_label: $1
          - action: drop
            regex: .+
            source_labels:
              - __meta_kubernetes_pod_label_app_kubernetes_io_name
          - action: replace
            source_labels:
              - __meta_kubernetes_pod_ip
            target_label: pod_ip
          - action: replace
            source_labels:
              - __meta_kubernetes_pod_label_app
            target_label: app
          - action: drop
            regex: ''
            source_labels:
              - app
          - action: replace
            source_labels:
              - __meta_kubernetes_pod_label_component
            target_label: component
          {{- if .Values.config.snippets.addScrapeJobLabel }}
          - action: replace
            replacement: kubernetes-pods-app
            target_label: scrape_job
          {{- end }}
          {{- toYaml .Values.config.snippets.common | nindent 4 }}
    podPipelineStages:
      - docker: {}

Grafana 添加 Loki 数据源:

Grafana 中按照标签查询日志:

nginx 日志示例:

日志告警

Loki 支持三种模式创建日志告警:

  • 在 Promtail 中的 pipeline 管道的 metrics 的阶段,根据需求增加一个监控指标,然后使用 Prometheus 结合 Alertmanager 完成监控报警。
  • 通过 Loki 自带的报警功能( Ruler 组件)可以持续查询一个 rules 规则,并将超过阈值的事件推送给 AlertManager 或者其他 Webhook 服务。
  • 将 LogQL 查询转换为 Prometheus 指标。可以通过 Grafana 自带的 Alert rules & notifications,定义有关 LogQL 指标的报警,推送到 Notification channels( Prometheus Alertmanager , Webhook 等)。

以下主要介绍 LogQL 转化为 Prometheus 指标的方式实现告警。

首先,在 Grafana 添加 Prometheus 数据源,URL 只需要填入 http://loki-ip:3100/loki 即可将 LogQL 查询转换为 Prometheus 指标。

在告警规则配置中配置 Notification channels

新建一个 Dashboard ,配置一个面板,例如:当 nginx 出现 404 状态码,触发告警:

代码语言:javascript
复制
count_over_time({app="nginx-pod"} |= "404" [1m])

手动访问 nginx 404 页面,可以看到日志已经产生告警:

关于更多 Loki 和 Promtail 配置,以及日志的告警,推荐直接看官方文档,已经很详细了。这里不过多介绍。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-07-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 gopher云原生 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 整体介绍
  • Promtail 介绍
  • Loki 介绍
  • 使用 Helm 部署
  • 日志告警
相关产品与服务
Grafana 服务
Grafana 服务(TencentCloud Managed Service for Grafana,TCMG)是腾讯云基于社区广受欢迎的开源可视化项目 Grafana ,并与 Grafana Lab 合作开发的托管服务。TCMG 为您提供安全、免运维 Grafana 的能力,内建腾讯云多种数据源插件,如 Prometheus 监控服务、容器服务、日志服务 、Graphite 和 InfluxDB 等,最终实现数据的统一可视化。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档