「Kubernetes」- 日志

  CREATED BY JENKINSBOT

内容简介

本部分将介绍与Kubernetes日志有关内容,包括日志种类、收集方法等等。

关于日志

#1 多种多样的日志

应用程序具有日志,用于排查问题。集群具有日志,用于排查问题。容器环境具有日志机制,容器化应用应将日志写入标准输出与标准错误。

#2 但这些日志机制存在问题

但是由容器引擎提供的日志功能远远不够:容器崩溃,驱逐POD实例,节点崩溃,在这些情况下我们依旧希望访问日志。因此日志需要独立存储,并且生命周期与节点、容器等等无关。

该概念被称为“集群日志”。

#3 集群日志

“集群日志”需要单独存储,但是Kubernetes并没有提供日志后端存储,需要我们自己集成。本文结合官方「Logging Architecture」文档,整理与日志有关内容。

写入标准输出的日志

使用kubectl logs查看日志,添加–previous选项查看已崩溃容器的日志。

如果在POD实例中具有容器,可以指定容器名查看特定容器日志。

节点级日志类型

应用程序日志

由容器应用写入标准输出与标准错误的日志,会被容器引擎重定向。例如在Docker中,由日志驱动处理(在Kubernetes中,被配置写入JSON格式的文件中)。

注意,使用Docker日志驱动无法处理多行日志,需要在日志收集工具中进行处理。

如果容器重启,则kubelet会保存单个容器及它的日志。若驱逐POD实例,所有对应的容器将被驱逐,包括日志。

另外节点日志还要考虑轮转问题,防止日志消耗过多磁盘。但是Kubernetes当前不负责日志轮转,这个问题应该由容器应用处理。另外可以可以配置容器环境处理日志轮转,例如使用Docker的--log-opt选项。

当执行kubectl logs时,由对应节点的kubelet响应,直接读取日志文件。注意,如果外部系统执行轮转,日志截断为多个文件时,则kubectl logs只能读取组后一个文件。

系统组件日志

系统组件也有日志,但是分为两类:(1)运行在容器内的组件;(2)运行在容器外的组件;

运行在容器外的组件,例如kubelet及Docker等等:如果使用systemd管理,则日志写入journald中;如果未使用systemd管理,则日志写入/var/log中;
运行在容器内的组件,例如kube-proxy或scheduler等等:使用默认日志机制,将日志写入/var/log中;

同样,写入/var/log中的日志也需要轮转。

集群级日志的解决方案

由于Kubernetes没有提供集群日志解决方案,有以下集中途径解决:

使用节点级日志代理,运行在每个节点中

使用专用容器(Sidecar),收集应用程序日志

从应用程序中直接将日志写入后端日志存储

下面我们将简述各种解决方法

使用节点日志代理

以DeamonSet在每个节点运行POD实例,用于直接读取日志文件。但是这只适用于将日志写入标准错误与标准输出的容器。

常用解决方案有Elasticsaerch+Fluentd服务。

使用专用容器(Sidecar)

使用Sidecar容器(与应用容器处于相同POD实例的容器),有两种方式:(1)Sidecar容器将应用日志“流入”自己的标准输出;(2)Sidecar容器运行日志代理,收集应用程序日志;

# 流式Sidecar容器:
当Sidecar容器使用自身的标准错误与标准输出时,可以利用kubelet与每个节点的日志代理。Sidecar容器可以读取文件、套接字、journald,然后将日志写入自己的标准错误、标准输出中。

这种方法可以从应用程序不同部分中分离出不同的日志流,即使有些应用程序可能不支持写入标准输入、与标准输出。日志重定向每次只需要处理很小日志,因此不会出现过渡的开销。另外由于Sidecar的标准输出与标准错误与kubelet处理,因此可以通过kubectl logs查看日志。

虽然Sidecar是额外的容器,但是它可以简单到只运行tail命令。Sidecar是一种涉及模式。

另外节点级日志代理会自动处理日志,无需进一步配置。还可以配置收集代理来根据“源容器”日志类型进行解析。

尽管CPU使用降低,但是会增加磁盘使用量。如果你的应用程序需要将日志写入文件,那尽量写入到标准输出中,而不是使用Sidecar容器处理。

# 带有日志代理的Sidecar容器:
如果节点级日志代理无法满足需求,可以运行在Sidecar容器中运行日志收集代理。该代理可以经过配置,适用于特定应用程序。但是该类型的Sidecar会消耗更多资源,并且不能使用kubectl logs查看日志。

直接暴露日志

最后一种方法是将日志直接写入后端存储,这是一种日志存储方案,但是与Kubernetes集群的关系并不大,这里不再讨论。

最后总结

在 Kubernetes Cluster 中,需要处理的日志分为以下几种:

容器外日志:kubelet、Docker

容器内日志:(已写标准输入、标准错误)容器应用程序,包括集群组件(比如kube-porxy,etcd等等)

容器内日志:(未写标准输入、标准错误)容器应用应用,写入容器本地

使用 DaemonSet 运行 POD 实例,在节点中收集日志。

参考文献

1.17/Logging Architecture