Kubernetes 日志收集方案

时间:2024-03-30 14:05:04

本文简单整理 Kubernetes 里关于容器应用日志的四种收集方式。



首先解释下容器日志原则:

  • 日志收集方案一般需要想办法把日志数据转发到后端(Loging Backend)里存储然后处理。
  • 因为Kubernetes 里面对容器日志的处理过程应该与容器、Pod 以及 Node 的生命周期都是完全无关的。这种设计是为了保证,无论是容器挂了、Pod 被删除,甚至节点宕机的时候,应用的日志依然可以被正常获取到。

下面整理几种日志收集方案:

一、直接指定方案

(app容器 - 后端)

最直接的方式,在编写应用的时候,就直接指定好日志的存储后端,如下所示:
Kubernetes 日志收集方案
在这种方案下,Kubernetes 就完全不必操心容器日志的收集了。但这仅适用于本身已经有完善的日志处理系统的公司。

二、NodeAgent 方案

(app容器 - [stdout/stderr] - NodeAgent - 后端)

这个方案,在社区里是最常用的一种。

在 Node 上部署 logging agent(一般都会以 DaemonSet 的方式运行),将日志文件转发到后端存储里保存起来。

Kubernetes 日志收集方案

过程解释:

  1. 应用 Pod 里的容器 app-container 产生日志输出到 stdout 和 stderr
  2. 对于一个容器来说,当应用把日志输出到 stdout 和 stderr 之后,容器项目在默认情况下就会把这些日志输出到宿主机上的一个 JSON 文件里。(这样通过 kubectl logs 命令就可以看到这些容器的日志了)
  3. logging agent 将日志文件转发到后端存储里
    另外, logrotate,在日志文件超过 10MB 的时候会自动对日志文件进行 rotate 操作

优点与不足:

最大的优点在于一个节点只需要部署一个 agent,并且不会对应用和 Pod 有任何侵入性。

不足之处就在于,它要求应用输出的日志,都必须是直接输出到容器的 stdout 和 stderr 里。因为 stdout 的数据会默认输出到容器之外的宿主机,但如果日志直接输出到了容器内的某个文件里,或者输出到了远程存储里,就不适用了。

三、Sidecar + NodeAgent 方案

(app容器 - Sidecar - [stdout/stderr] - NodeAgent - 后端)

这种方案针对容器应用产生的日志不输出到 stdout/stderr 上的特殊情况。但实际上存在两份相同的日志文件,浪费磁盘空间。

通过一个 sidecar 容器把日志文件重新输出到 sidecar 的 stdout 和 stderr 上,然后再利用 logging agent 将日志文件转发到后端。

Kubernetes 日志收集方案
过程解释:

  1. 应用 Pod 里的容器 app-container 产生日志输出到容器内的某个文件,因为在容器内,外面是获取不到的。
  2. 为 Pod 添加一个 sidecar 容器,因为 sidecar 跟主容器之间是共享 Volume 的,所以可以将容器内日志文件内容重新以 stdout 和 stderr 的方式输出出来。
  3. 对于输出到 stdout 和 stderr 的内容,容器项目会默认地把这些日志输出到宿主机上的一个 JSON 文件里。
  4. logging agent 将日志文件转发到后端存储里

分析:

此方案的额外性能损耗虽然并不高,也就是 sidecar 多占用一点 CPU 和内存罢了。但需要注意的是,这时候宿主机上实际上会存在两份相同的日志文件:一份是应用自己写入的;另一份则是 sidecar 的 stdout 和 stderr 对应的 JSON 文件。这对磁盘是很大的浪费。

所以,除非万不得已或者应用容器完全不可能被修改,其他不推荐使用此方案

四、SidecarAgent 方案

(app容器 - SidecarAgent - 后端)

通过一个 sidecar 容器,直接把应用的日志文件发送到后端远程存储里面去。

这种方案也可以处理容器应用产生的日志不输出到 stdout/stderr 上的特殊情况,但这个 sidecar 容器会消耗较多的资源,甚至拖垮应用容器。

Kubernetes 日志收集方案

总结

综合对比以上几种方案,建议将应用日志输出到 stdout 和 stderr,然后通过在宿主机上部署 logging-agent 的方式来集中处理日志。这种方案不仅管理简单,kubectl logs 也可以用,而且可靠性高,并且宿主机本身,很可能就自带了 rsyslogd 等非常成熟的日志收集组件来供你使用。


图片均来自于张磊老师极客时间课程《深入剖析 Kubernetes》,也是本文的主要参考资料