成功最有效的方法就是向有经验的人学习!

loki构建中心化日志平台

前戏

出于种种原因,我们已经不知不觉进入了k8s的时代,其优势不言而喻,但是对于应用的日志收集还没有开箱即用的方案。
为什么需要收集日志?
在过去我们要查看日志都会登陆到运行应用的主机上,打开日志文件查阅,这对于单体应用且跑在虚拟机中时,尚可。但是随时微服务的到来,运行在K8S的平台上,这简直就是噩梦。且不说要频繁的登陆服务器,还需要做RBAC的相关授权,非常麻烦,可以想像10几个微服务运行在10几台服务器中,脑补一下。

容器化应用日志处理
一般来说应用日志可以分为三大类:

  • 标准输出和标准错误流(std)
  • 写入本地文件
  • 写入某种存储(数据库等)

分别分析下这三种, 第一种肯定不会使用, 因为没有持久化; 第二种非常常见, 例如 nginx 服务之类的都会将日志写入本地文件, 此种方式弊端就是需要日志收集器来收集聚合多副本应用的日志; 第三种也有很多限制, 例如一般存储对于应用来说都是远程的, 此种方式需要解决性能问题(例如批写入), 后面还要自己实现数据查询问题.

容器化时代最普遍也最推荐的方式是第一种, 原因主要有这几点:

  • pod 退出时如果日志文件没有使用挂载 volume 会丢失
  • docker runtime 会帮我们收集容器标准输出到宿主机文件中
  • 日志文件 rotate 不需要我们自己做

这种方式的优点是, 日志具有了独立的存储和生命周期,与节点、pod 或容器的生命周期相独立, 可以避免 pod 重启或节点重启导致日志文件丢失.

所以对于容器化应用日志收集就可以转化为 应用日志输出到标准输出 -> 日志收集器收集 docker 保存的应用日志文件.

k8s 集群日志收集架构往往是这样的:
file

其实就是应用 pod 输出日志到标准输出, 容器运行时帮我们持久化到本地文件, 并处理 rotate, 然后我们在节点上运行一个 log agent, 将日志发送到中心化日志收集服务后台.

有人会说, 记录日志文件时我们可以将不同级别日志记录不同文件, 那么标准输出怎么做呢?

一般推荐使用两种格式: logfmt 和 json 格式, 并且要有 level 和 timestamp 字段. logfmt 格式是键值形式 level=debug ts=2020-08-02T15:12:53.456Z caller=manager.go:116 msg="no file", 这种格式在 go 语言知名项目中均有大范围应用, 例如: prometheus 和 grafana. 有了这两个字段, 日志收集器便可以轻松处理了, 就可以达到相同目的了.

ps: 我们最好能够统一我们业务应用的日志格式, 使用社区认可的广泛使用的格式, 日志 parser 基本都可以开箱即用, 省心省事.

loki 是什么

loki 官方是这么介绍自己的: Loki 是一个 可水平扩展, 高可用, 多租户 的日志聚合收集系统, 并且追求高性能和易于部署.

对比一下它和别的日志收集系统:

由于它不创建全文索引, 而且只存储压缩后的非结构化日志和元信息索引, 所以很轻量级易于部署
索引和分组与 Prometheus 使用相同的 label
非常适合收集 k8s pod 日志信息, 类似 pod labels 这些元信息都是自动收集并添加索引的
直接可以对接 Grafana 作为日志查询界面
相对于 ELK 需要的资源更少, 并且更易于部署.

loki 组件也基本分为三个:

  • promtail 日志收集 agent, 收集日志并发送给 loki
  • loki 核心服务, 存储日志和索引, 并提供查询服务
  • Grafana 日志查询界面

可以看到, 组件和 ELK 基本一样, 并且符合 k8s 的日志收集架构.

loki 如何部署

根据上面的组件架构, 可以看出 promtail 需要运行在所有运行应用容器的节点, 所以会是 DaemonSet, loki 作为核心服务, 带有持久化存储而且支持横向扩展, 所以应该是 StatefulSet, Grafana 是比较基本的独立应用, 可以复用已部署的.

最简单的方式还是使用 helm, loki 官方已经提供了生产可用的 chart.

# 增加源并更新
$ helm repo add loki https://grafana.github.io/loki/charts
$ helm repo update
# 拉取 chart
$ helm fetch loki/loki-stack --untar --untardir .
$ cd loki-stack
# 将 values.yaml 中的 grafana.enable 改成 true, 因为我们需要部署 grafana
# 生成 k8s 配置
$ helm template loki . > loki.yaml
# 部署
$ kubectl apply -f loki.yaml

ps: 我个人喜欢在本地生成出部署文件, 手动部署, 这样可以学习生成出来的配置文件, 并且手动做某些更改时会更方便.

等待 pod 启动完成后我们就可以看到进入 grafana 查看了:

# 输出 grafana 登录密码
$ kubectl get secret --namespace default loki-grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo
# port forward 让我们能够访问 grafana service
$ kubectl port-forward --namespace default service/loki-grafana 3000:80

接着打开 http://localhost:3000 进入 grafana 界面(用户名使用 admin), 点击 Explore 并且选择 label 就可以查看日志了.

file

基本实现开箱即用

下期针对java项目做一些自定义配置

赞(0) 打赏
未经允许不得转载:陈桂林博客 » loki构建中心化日志平台
分享到

相关推荐

  • 暂无文章

大佬们的评论 抢沙发

全新“一站式”建站,高质量、高售后的一条龙服务

微信 抖音 支付宝 百度 头条 快手全平台打通信息流

橙子建站.极速智能建站8折购买虚拟主机

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏

登录

找回密码

注册