在开始这篇文章以前,首先要明确一点: Kubernetes 中对容器日志的处理方式,都叫作 cluster-level-logging ,也就是说,这个日志处理系统,与容器, Pod 以及 Node 的生命周期都是彻底无关的.其实想一想也能知道,这种设计就是为了保证,不管是容器宕了, Pod 被删除甚至是节点宕机的时候,日志处理系统仍然能够被正常获取到,从而能够分析缘由所在.
而对于一个容器来讲,当应用把日志输出到 stdout 和 stderr 以后,容器项目在默认状况下,就会把这些日志输出到宿主机上的一个 JSON 文件中,这样,我就可以经过 kubectl logs 命令,来查看到这些容器的日志.
可是你要明白一点,那就是 Kubernetes 自己,其实是不会作容器日志收集工做的,因此为了可以实现上述 cluster-level-logging ,就须要在部署集群的时候,就提早对具体的日志方案进行规划.所幸, Kubernetes 项目自己提供了三种相关方案.
接下来分别讲一讲.web
第一种 |
在 Node 上部署 logging agent ,将日志文件转发到后端存储里保存起来.这个方案的架构图以下所示:
从中咱们可以看到,这里的核心在于 logging agent ,它通常都会以 DaemonSet 的方式运行在节点上,而后将宿主机上的容器日志目录挂载进去,最后由 logging-agent 把日志转发出去.那么,这样一来,我只须要在一个节点上部署一个 agent 便可,这样也不会对应用和 Pod 有任何侵入性.
可是这种方案,要求应用输出的日志,都必须是直接输出到容器的 stdout 和 stderr 中.
这也就引出了第二种解决方案.后端
第二种 |
第二种状况,主要就是对上面所述缺点的一个处理,即:当容器的日志只能输出到某些文件中时,能够经过一个 sidecar 容器将这些日志文件从新输出到 sidecar 的 stdout 和 stderr 中.
这种解决方案的架构图以下:
由于 sidecar 和主容器之间是共享 Volume 的,因此这里的 sidecar 方案的额外性能损耗并不高,只不过是多用了一点儿 CPU 和内存罢了.
可是要了解一点,这种方案下,宿主机上会存在两份相同的日志文件:一份是应用本身写入的,另一份则是 sidecar 的 stdout 和 stderr 对应的 JSON 文件.这样就会形成对磁盘的巨大浪费.
因此,若是不是万不得已,也不是应用容器彻底不可能被修改,仍是建议使用方案一,或者使用下面介绍的方案三.
固然了,土豪随意,毕竟开心才是重要的.架构
第三种 |
第三种方案,就是经过 sidecar 容器,直接将应用的日志文件发送到远程存储里面去.也就是,方案一中的 logging agent ,放在应用 Pod 中.继续上一张架构图:
在这种方案下,应用能够直接把日志输出到固定的文件中,而不是 stdout , logging-agent 还可使用 fluentd ,后端存储还能够是 ElasticSearch .
这种方案,部署简单,对宿主机也很是友好,可是这个 sidecar 容器,颇有可能会消耗比较多的资源,甚至会拖垮应用容器,此外,因为日志没有输出到 stdout 上面,因此就算你经过命令 kubectl logs 来查看,也是看不到任何日志输出到.ide
以上就是关于容器日志的收集与管理的三种方案的介绍了.
有一点须要注意的是,无论到最后选择什么方案,到最后,必定要及时将这些日志文件,从宿主机上清理掉,或者给日志目录文件专门挂载一些容量巨大的远程盘.要否则,一旦磁盘分区被打满,整个系统就可能会陷入崩溃状态,这样形成的损失就大多了.svg
以上内容来自我学习<深刻剖析Kubernetes>专栏文章以后的一些看法,有偏颇之处,还望指出.
感谢您的阅读~性能