这篇文章应朋友的要求,让写一篇loki日志系统,咱定责无旁贷 必定要好好写 开干!node
公司的容器云运行的应用或某一个节点出现了问题,解决的思路正则表达式
问题首先被prometheus监控算法
一、metric是来讲明当前或者历史达到了某个值spring
二、alert设置metric达到某个特定的基数触发了告警docker
仅仅这些日志是不可以解决问题的 还须要看下应用的日志数据库
k8s的基本单位是podvim
pod把日志输出到stdout和stderrcentos
当某个pod的内存变得很大api
触发了咱们的alertspringboot
这个时候管理员
去页面查询确认是哪一个pod有问题
而后要确认pod内存变大的缘由
咱们还须要去查询pod的日志
若是没有日志系统
那么咱们就须要到页面或者使用命令进行查询了
若是这个时候应用挂掉了 那么就没有办法再查询到相关日志了
优点:
一、功能丰富,容许复杂的操做
劣势:
一、主流的ELK(全文检索)或者EFK比较重
二、ES复杂的搜索功能不少都用不上 规模复杂,资源占用高,操做苦难
大多数查询只关注必定时间范围和一些简单的参数(如host、service等)
三、Kibana和Grafana之间切换,影响用户体验
四、倒排索引的切分和共享的成本较高
一、最小化度量和日志的切换成本
有助于减小异常事件的响应时间和提升用户的体验
二、在查询语言的易操做性和复杂性之间能够达到一个权衡
三、更具成本效益
一、
Loki使用了和prometheus同样的标签来做为索引
经过标签既能够查询日志的内容也能够查询到监控的数据
不但减小了两种查询之间的切换成本
也极大地下降了日志索引的存储
二、
Loki将使用与prometheus相同的服务发现和标签从新标记库编写了pormtail
在k8s中promtail以daemonset方式运行在每一个节点中
经过kubernetes api等到日志的正确元数据
并将它们发送到Loki
一、
promtail收集日志并将其发送给loki
Distributor就是第一个接收日志的组件
Loki经过构建压缩数据块来实现批处理和压缩数据
二、
组件ingester是一个有状态的组件
负责构建和刷新chunck
当chunk达到必定的数量或者时间后
刷新到存储中去
三、
每一个流的日志对应一个ingester
当日志到达Distributor后
根据元数据和hash算法计算出应该到哪一个ingester上面
四、为了冗余和弹性,咱们将其复制n(默认状况下为3)次
ingester接收到日志并开始构建chunk
将日志进行压缩并附加到chunk上面
一旦chunk“填满”(数据达到必定数量或者过了必定期限)
ingester将其刷新到数据库
咱们对块和索引使用单独的数据库
由于它们存储的数据类型不一样
刷新一个chunk以后
ingester而后建立一个新的空chunk并将新条目添加到该chunk中
一、 由Querier负责给定一个时间范围和标签选择器
Querier查看索引以肯定哪些块匹配
并经过greps将结果显示出来
它还从Ingester获取还没有刷新的最新数据
二、
对于每一个查询
一个查询器将为您显示全部相关日志
实现了查询并行化
提供分布式grep
即便是大型查询也是足够的
安装loki、promtail、grafana
`vim docker-compose.yaml
version: "3"
networks:
loki:
services:
loki:
image: grafana/loki:1.5.0
ports:
command: -config.file=/etc/loki/local-config.yaml
networks:
promtail:
image: grafana/promtail:1.5.0
volumes:
command: -config.file=/etc/promtail/docker-config.yaml
networks:
grafana:
image: grafana/grafana:latest
ports:
networks:
docker-compose up -d
docker-compose ps
http://localhost:3000
默认的登录帐号admin/admin
而后添加loki数据源
url添加http://loki:3100/
点击Explore 选择Loki 选择相应的Label
也能够经过正则表达式来查询日志
上面咱说完了 liki架构、实现原理及环境搭建过程
如今就结束了吗? No 那多显得那么出类拔萃呀 哈哈
咱再结合一个具体的案例:
使用loki对接下k8s下面的pod日志
let's go !
具体过程以下:
一、nacos为注册中心
二、user和order为2个springboot项目
三、将user和order使用k8s部署
四、访问user接口 ,user访问order 打印出日志
五、该日志经过loki显示出来
1-4过程 我们以前的文章介绍过
朋友们若是本身想实际操练一遍的话能够先看下这篇文章 使用k8s把项目部署起来
部署的效果是
nacos界面
user和order服务都是k8s部署的
这里显示的ip是k8s集群下面的ip
kubectl get pod
kubectl get svc
2个都是nodePort类型的
因此直接能够访问user服务的接口
kubectl logs -f user-5776d4b64c-xsb5c
如今loki有了,k8s pod 日志也有了 下面咱看看loki和k8s如何关联起来 达到经过loki查询k8s的效果
这里只须要实现 promtail访问到k8s日志就能够了
promtail能够直接访问到k8s集群内部的日志
也能够将k8s集群内部的日志挂载到宿主机器上 而后再经过promtail访问宿主机上的日志
这里介绍4种实现方式
我们分别实现下看看
备注:这篇文章先简单介绍下4种方式的思路,下篇文章我们针对这4种方式实现相应的效果
promtail能够直接访问到k8s集群内部的日志
首先须要知道 k8s集群下面的pod生成的日志 默认目录为/var/log/containers
一、咱先看看上面的promtail的docker-compose的配置命令
`promtail:
image: grafana/promtail:1.5.0
volumes:
command: -config.file=/etc/promtail/docker-config.yaml
networks:
其中 /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
看到界面效果 发现问题了没?
一、路径不是修改为 /var/log/container/*log 这个了吗 怎么仍是 /var/log下面的日志?
二、选中一个日志文件怎么显示不出来该文件的内容
这2个问题放到下篇文章解答下吧 (先埋个坑 哈哈 我这么这么坏)
- replacement: /var/log/container/*.log
这种方式也放到下篇文章再说吧
这种方式 我试过了 也是达到指望效果的
一、
首先给springboot项目添加日志文件输出 我们这个示例中 以user项目为例说下
二、将springboot项目生成docker镜像 而后上传到阿里的镜像库 而后在k8s user 配置文件中引用这个镜像库
这些都在以前那篇文章中详细说过了 这里就再也不附述了
这里只须要不一样点
圈红的地方是添加的映射
volumeMounts 这个是将docker内部的/opt/logs目录做为挂载目录
volumes 这个是将宿主机中的
/Users/mengfanxiao/Documents/third_software/loki/log
目录做为映射目录 即docker中的/opt/logs下面的日志会映射到该目录下
须要注意:
我一开始用的目录是 /opt/logs 可是在个人mac环境中一直不能将docker中的日志目录映射到宿主机上 但 centos就能够 这个缘由也放到下篇文章说下吧
三、最后 只须要让promtail访问/Users/mengfanxiao/Documents/third_software/loki/log 这个目录下面的日志就好了
至于怎么让promtail访问 下篇再说吧
启动方式 能够参考下我以前的那篇文章 K8S原理简介及环境搭建
本文使用 mdnice 排版