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