前言

这篇文章应敌人的要求,让写一篇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 排版