乐趣区

关于docker:轻量级日志系统Loki原理简介和使用

前言

这篇文章应敌人的要求,让写一篇 loki 日志零碎,咱定责无旁贷 肯定要好好写 开干!

事实中的需要

公司的容器云运行的利用或某一个节点呈现了问题,解决的思路

问题首先被 prometheus 监控

1、metric 是来阐明以后或者历史达到了某个值

2、alert 设置 metric 达到某个特定的基数触发了告警

仅仅这些日志是不可能解决问题的 还须要看下利用的日志

k8s 的根本单位是 pod

pod 把日志输入到 stdout 和 stderr

当某个 pod 的内存变得很大

触发了咱们的 alert

这个时候管理员

去页面查问确认是哪个 pod 有问题

而后要确认 pod 内存变大的起因

咱们还须要去查问 pod 的日志

如果没有日志零碎

那么咱们就须要到页面或者应用命令进行查问了

如果这个时候利用挂掉了 那么就没有方法再查问到相干日志了

解决该需要可供选择的计划

ELK

劣势:

1、功能丰富,容许简单的操作

劣势:

1、支流的 ELK(全文检索)或者 EFK 比拟重

2、ES 简单的搜寻性能很多都用不上 规模简单,资源占用高,操作苦难

大多数查问只关注肯定工夫范畴和一些简略的参数(如 host、service 等)

3、Kibana 和 Grafana 之间切换,影响用户体验

4、倒排索引的切分和共享的老本较高

Loki

1、最小化度量和日志的切换老本

有助于缩小异样事件的响应工夫和进步用户的体验

2、在查询语言的易操作性和复杂性之间能够达到一个衡量

3、更具老本效益

loki 组件介绍

Promtail

  • 用来将容器日志发送到 Loki 或者 Grafana 服务上的日志收集工具
  • 该工具次要包含发现采集指标以及给日志流增加上 Label 标签 而后发送给 Loki
  • Promtail 的服务发现是基于 Prometheus 的服务发现机制实现的

Loki

  • 受 Prometheus 启发的能够程度扩大、高可用以及反对多租户的日志聚合零碎
  • 应用了和 Prometheus 雷同的服务发现机制,将标签增加到日志流中而不是构建全文索引
  • 从 Promtail 接管到的日志和利用的 metrics 指标就具备雷同的标签集
  • 不仅提供了更好的日志和指标之间的上下文切换,还防止了对日志进行全文索引

Grafana

  • 一个用于监控和可视化观测的开源平台
  • 反对十分丰盛的数据源
  • 在 Loki 技术栈中它专门用来展现来自 Prometheus 和 Loki 等数据源的工夫序列数据
  • 可进行查问、可视化、报警等操作
  • 能够用于创立、摸索和共享数据 Dashboard
  • 激励数据驱动

Loki 架构

1、

Loki 应用了和 prometheus 一样的标签来作为索引

通过标签既能够查问日志的内容也能够查问到监控的数据

岂但缩小了两种查问之间的切换老本

也极大地升高了日志索引的存储

2、

Loki 将应用与 prometheus 雷同的服务发现和标签从新标记库编写了 pormtail

在 k8s 中 promtail 以 daemonset 形式运行在每个节点中

通过 kubernetes api 等到日志的正确元数据

并将它们发送到 Loki

日志的存储架构

Distributor

1、

promtail 收集日志并将其发送给 loki

Distributor 就是第一个接管日志的组件

Loki 通过构建压缩数据块来实现批处理和压缩数据

2、

组件 ingester 是一个有状态的组件

负责构建和刷新 chunck

当 chunk 达到肯定的数量或者工夫后

刷新到存储中去

3、

每个流的日志对应一个 ingester

当日志达到 Distributor 后

依据元数据和 hash 算法计算出应该到哪个 ingester 下面

4、为了冗余和弹性,咱们将其复制 n(默认状况下为 3)次

Ingester

ingester 接管到日志并开始构建 chunk

将日志进行压缩并附加到 chunk 下面

一旦 chunk“填满”(数据达到肯定数量或者过了肯定期限)

ingester 将其刷新到数据库

咱们对块和索引应用独自的数据库

因为它们存储的数据类型不同

刷新一个 chunk 之后

ingester 而后创立一个新的空 chunk 并将新条目增加到该 chunk 中

Querier

1、由 Querier 负责给定一个工夫范畴和标签选择器

Querier 查看索引以确定哪些块匹配

并通过 greps 将结果显示进去

它还从 Ingester 获取尚未刷新的最新数据

2、

对于每个查问

一个查询器将为您显示所有相干日志

实现了查问并行化

提供分布式 grep

即便是大型查问也是足够的

拓展性

  • Loki 的索引存储能够是 cassandra/bigtable/dynamodb
  • chuncks 能够是各种对象存储
  • Querier 和 Distributor 都是无状态的组件
  • 对于 ingester 他尽管是有状态的 但当新的节点退出或者缩小整节点间的 chunk 会重新分配,以适应新的散列环

环境搭建 (应用 docker 编排来实现)

装置 loki、promtail、grafana

  • 编写 docker 编排配置文件

`vim docker-compose.yaml
version: “3”
networks:
loki:
services:
loki:
image: grafana/loki:1.5.0
ports:

  • “3100:3100”

command: -config.file=/etc/loki/local-config.yaml
networks:

  • loki

promtail:
image: grafana/promtail:1.5.0
volumes:

  • /var/log:/var/log

command: -config.file=/etc/promtail/docker-config.yaml
networks:

  • loki

grafana:
image: grafana/grafana:latest
ports:

  • “3000:3000”

networks:

    • loki`
    • 启动装置

    docker-compose up -d

    docker-compose ps

    • 拜访 grafana 界面

    http://localhost:3000

    默认的登陆账号 admin/admin

    而后增加 loki 数据源

    url 增加 http://loki:3100/

    点击 Explore 抉择 Loki 抉择相应的 Label

    也能够通过正则表达式来查问日志


    下面咱说完了 liki 架构、实现原理及环境搭建过程

    当初就完结了吗? No 那多显得那么超群绝伦呀 哈哈

    咱再联合一个具体的案例:

    应用 loki 对接下 k8s 上面的 pod 日志

    let’s go !

    具体过程如下:

    1、nacos 为注册核心

    2、user 和 order 为 2 个 springboot 我的项目

    3、将 user 和 order 应用 k8s 部署

    4、拜访 user 接口,user 拜访 order 打印出日志

    5、该日志通过 loki 显示进去

    1- 4 过程 咱们之前的文章介绍过

    【实战】K8S 部署 Nacos 微服务

    敌人们如果本人想理论操练一遍的话能够先看下这篇文章 应用 k8s 把我的项目部署起来

    部署的成果是

    nacos 界面

    user 和 order 服务都是 k8s 部署的

    这里显示的 ip 是 k8s 集群上面的 ip

    • 查看 pod

    kubectl get pod

    • 查看 service 服务

    kubectl get svc

    2 个都是 nodePort 类型的

    所以间接能够拜访 user 服务的接口

    • 查看 user 这个 pod 的日志

    kubectl logs -f user-5776d4b64c-xsb5c

    当初 loki 有了,k8s pod 日志也有了 上面咱看看 loki 和 k8s 如何关联起来 达到通过 loki 查问 k8s 的成果

    这里只须要实现 promtail 拜访到 k8s 日志就能够了

    promtail 能够间接拜访到 k8s 集群外部的日志

    也能够将 k8s 集群外部的日志挂载到宿主机器上 而后再通过 promtail 拜访宿主机上的日志

    这里介绍 4 种实现形式

    咱们别离实现下看看

    备注:这篇文章先简略介绍下 4 种形式的思路,下篇文章咱们针对这 4 种形式实现相应的成果

    形式 1: 将默认门路 var/logs/*log 批改成 /var/log/container

    promtail 能够间接拜访到 k8s 集群外部的日志

    首先须要晓得 k8s 集群上面的 pod 生成的日志 默认目录为 /var/log/containers

    1、咱先看看下面的 promtail 的 docker-compose 的配置命令

    `promtail:
    image: grafana/promtail:1.5.0
    volumes:

    • /var/log/container:/var/log/container

    command: -config.file=/etc/promtail/docker-config.yaml
    networks:

    • loki`

    其中 /etc/promtail/docker-config.yaml

    是拜访的 docker 外部的配置文件

    咱进去 docker 外部看下

    a、查看容器 id

    docker ps |grep promtail

    b、进入容器

    docker exec -it 71cb21c2d0a3 sh

    看到了

    job=varlogs

    对应的日志文件门路是 /var/log/*log

    是不是有似曾相识的感觉

    job 对应 varlogs

    filenames 是对应的日志门路 /var/log/*log 上面的日志文件

    当然只是在 promtail 容器外部的

    在这里只须要将 /var/log/*log 门路批改成 /var/log/container/*log 这个门路就能够了

    那如何批改呢

    咱们晓得 这个配置文件是在容器外部的

    要想批改这个配置文件 须要在宿主机也弄一份 而后批改宿主机上的这份文件 而后替换掉 docker 种的这个配置即可

    重启部署下 docker-compose

    看到界面成果 发现问题了没?

    1、门路不是批改成 /var/log/container/*log 这个了吗 怎么还是 /var/log 上面的日志?

    2、选中一个日志文件怎么显示不进去该文件的内容

    这 2 个问题放到下篇文章解答下吧(先埋个坑 哈哈 我这么这么坏)

    形式 2

    - replacement: /var/log/container/*.log

    这种形式也放到下篇文章再说吧

    形式 3:将 k8s 集群外部的日志挂载到宿主机器上 而后再通过 promtail 拜访宿主机上的日志

    这种形式 我试过了 也是达到冀望成果的

    1、

    首先给 springboot 我的项目增加日志文件输入 咱们这个示例中 以 user 我的项目为例说下

    • 减少日志文件

    • 日志文件的输入目录是 /opt/logs

    2、将 springboot 我的项目生成 docker 镜像 而后上传到阿里的镜像库 而后在 k8s user 配置文件中援用这个镜像库

    这些都在之前那篇文章中具体说过了 这里就不再附述了

    这里只须要不同点

    圈红的中央是增加的映射

    volumeMounts 这个是将 docker 外部的 /opt/logs 目录作为挂载目录

    volumes 这个是将宿主机中的

    /Users/mengfanxiao/Documents/third_software/loki/log

    目录作为映射目录 即 docker 中的 /opt/logs 上面的日志会映射到该目录下

    须要留神:

    我一开始用的目录是 /opt/logs 然而在我的 mac 环境中始终不能将 docker 中的日志目录映射到宿主机上 但 centos 就能够 这个起因也放到下篇文章说下吧

    3、最初 只须要让 promtail 拜访 /Users/mengfanxiao/Documents/third_software/loki/log 这个目录上面的日志就行了

    至于怎么让 promtail 拜访 下篇再说吧

    形式 4:promtail 不是从 /var/log 目录下读取的日志嘛 那么我将 user 日志输入到 /var/log 上面不就行了

    可能遇到的问题

    • 如果 k8s 状态是 start fail 状态 则 service 裸露 NodePort 的端口也拜访不了的状况下 须要重新启动下 k8s

    启动形式 能够参考下我之前的那篇文章 K8S 原理简介及环境搭建

    本文应用 mdnice 排版

    退出移动版