page contents

k8s 日志收集的那些套路

本文只是对k8s日志收集提供了一个简单的思路,关于日志收集可以根据公司的需求,因地制宜。

attachments-2021-03-oKlBIcev6049c54f670f7.png

kubernetes日志收集方案有几种方案,都适用于什么场景?本文对[k8s]常用日志采集方案做了详细介绍。


关于容器日志

Docker的日志分为两类,一类是 [Docker]引擎日志;另一类是容器日志。

引擎日志一般都交给了系统日志,不同的操作系统会放在不同的位置。本文主要介绍容器日志,容器日志可以理解是运行在容器内部的应用输出的日志,默认情况下,docker logs 显示当前运行的容器的日志信息,内容包含 STOUT(标准输出) 和 STDERR(标准错误输出)。日志都会以 json-file 的格式存储于 /var/lib/docker/containers/<容器id>/<容器id>-json.log ,不过这种方式并不适合放到生产环境中。

  • 默认方式下容器日志并不会限制日志文件的大小,容器会一直写日志,导致磁盘爆满,影响系统应用。(docker log-driver 支持log文件的rotate)
  • Docker Daemon 收集容器的标准输出,当日志量过大时会导致Docker Daemon 成为日志收集的瓶颈,日志的收集速度受限。
  • 日志文件量过大时,利用docker logs -f 查看时会直接将Docker Daemon阻塞住,造成docker ps等命令也不响应。

Docker提供了logging drivers配置,用户可以根据自己的需求去配置不同的log-driver,可参考官网 Configure logging drivers 。但是上述配置的日志收集也是通过Docker Daemon收集,收集日志的速度依然是瓶颈。

log-driver 日志收集速度
syslog 14.9 MB/s
json-file 37.9 MB/s

能不能找到不通过Docker Daemon收集日志直接将日志内容重定向到文件并自动 rotate的工具呢?答案是肯定的采用基底镜像。

S6-log 将 CMD 的标准输出重定向到/.../default/current,而不是发送到 Docker Daemon,这样就避免了 Docker Daemon 收集日志的性能瓶颈。本文就是采用基底镜像构建应用镜像形成统一日志收集方案。


关于k8s日志

[k8s]日志收集方案分成三个级别:

  • 应用(Pod)级别
  • 节点级别
  • 集群级别

应用(Pod)级别

Pod级别的日志 , 默认是输出到标准输出和标志输入,实际上跟docker 容器的一致。使用

kubectl logs pod-name -n namespace

查看。

节点级别

Node级别的日志 , 通过配置容器的log-driver来进行管理 , 这种需要配合logrotare来进行 , 日志超过最大限制 , 自动进行rotate操作。

attachments-2021-03-g6TCLvFm6049ca73c2553.jpg

集群级别

集群级别的日志收集 , 有三种

节点代理方式,在node级别进行日志收集。一般使用DaemonSet部署在每个node中。这种方式优点是耗费资源少,因为只需部署在节点,且对应用无侵入。缺点是只适合容器内应用日志必须都是标准输出。

attachments-2021-03-jLB2vYOw6049ca6c7a386.jpg

使用sidecar container作为容器日志代理,也就是在pod中跟随应用容器起一个日志处理容器,有两种形式:

  • 一种是直接将应用容器的日志收集并输出到标准输出(叫做Streaming sidecar container),但需要注意的是,这时候,宿主机上实际上会存在两份相同的日志文件:一份是应用自己写入的;另一份则是 sidecar 的 stdout 和 stderr 对应的 JSON 文件。这对磁盘是很大的浪费 , 所以说,除非万不得已或者应用容器完全不可能被修改。

attachments-2021-03-vJg6P39x6049ca643d87e.jpg

另一种是每一个pod中都起一个日志收集agent(比如logstash或fluebtd)也就是相当于把方案一里的 logging agent放在了pod里。但是这种方案资源消耗(cpu,内存)较大,并且日志不会输出到标准输出,kubectl logs 会看不到日志内容。

attachments-2021-03-WDzsYK4E6049ca5d3dfb2.jpg

  • 应用容器中直接将日志推到存储后端,这种方式就比较简单了,直接在应用里面将日志内容发送到日志收集服务后端。

attachments-2021-03-rpE5Erpd6049ca55c822e.jpg


日志架构

通过上文对[k8s日志]收集方案的介绍,要想设计一个统一的日志收集系统,可以采用节点代理方式收集每个节点上容器的日志,日志的整体架构如图所示。

attachments-2021-03-0tM71QTq6049ca4e01842.jpg

解释如下:

  • 所有应用容器都是基于s6基底镜像的,容器应用日志都会重定向到宿主机的某个目录文件下比如/data/logs/namespace/appname/podname/log/xxxx.log
  • log-agent 内部 包含 filebeat ,logrotate 等工具,其中filebeat是作为日志文件收集的agent
  • 通过filebeat将收集的日志发送到kafka
  • kafka日志发送的es日志存储/kibana检索层
  • logstash 作为中间工具主要用来在es中创建index和消费kafka 的消息

整个流程很好理解,但是需要解决的是

  • 用户部署的新应用,如何动态更新filebeat配置,
  • 如何保证每个日志文件都被正常的rotate,
  • 如果需要更多的功能则需要二次开发filebeat,使filebeat 支持更多的自定义配置。


付诸实践

解决上述问题,就需要开发一个log-agent应用以daemonset形式运行在k8s集群的每个节点上,应用内部包含filebeat,logrotate,和需要开发的功能组件。

第一个问题,如何动态更新filebeat配置,可以利用http://github.com/fsnotify/fs... 工具包监听日志目录变化create、delete事件,利用模板渲染的方法更新filebeat配置文件

第二个问题,利用http://github.com/robfig/cron 工具包 创建cronJob,定期rotate日志文件,注意应用日志文件所属用户,如果不是root用户所属,可以在配置中设置切换用户

/var/log/xxxx/xxxxx.log {
      su www-data www-data
      missingok
      notifempty
      size 1G
      copytruncate
    }


总结

本文只是对k8s日志收集提供了一个简单的思路,关于日志收集可以根据公司的需求,因地制宜。

想高效系统的学习Python编程语言,推荐大家关注一个微信公众号:Python编程学习圈。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Python入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2022-06-8G7qhWKd62a1bbfc5f09a.jpeg

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
轩辕小不懂
轩辕小不懂

2403 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1482 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章