日志架构

针对容器化应用,最简单且最广泛采用的日志记录方式就是写入标准输出标准错误流

开发容器应用时,不用考虑将日志写入到日志文件,直接使用标准输出?

由容器引擎或者运行时提供的原生功能不足以构成完整的日志记录方案,比如容器发生崩溃、Pod被驱逐或节点宕机等情况,你可以想访问日志,但是此时日志已经查询不到了。因此在集群中,日志应该有独立的存储和生命周期,与节点、Pod或者容器的生命周期相独立,这个叫做集群日志

K8S 并没有提供原生的日志存储方案,需要集成第三方的日志方案。

节点日志记录

image.png
步骤:

  • 容器化应用写入 stdout 和 stderr
  • 容器引擎捕获并重定向到某个位置如 log-file.log
  • 容器引擎重定向到日志驱动(见 Docker 日志驱动)

注意事项:

  1. 容器重启,kubelet 会保留被终止的容器日志。
  2. 容器被驱逐,容器日志也会被驱逐。

日志轮转

需要实现日志轮转,以此来保证日志不会消耗节点上全部可用空间。K8S 并不负责轮转日志,而是通过部署工具建议一个解决问题的方案,

解决方案:

  • 有些部署工具会设置容器运行时来自动的轮转应用日志,
  • kubelet 负责对日志进行轮换管理日志目录的结构,kubelet 并将此信息发送给 CRI 容器运行时,后者将容器日志写入到指定位置,kubelet 有参数用于配置如日志文件最大长度和每个容器可以生成日志文件个数上限,参考 kubelet 配置

系统日志记录

系统组件运行时也有产生日志:

  • 容器中运行的:kube-scheduler 和 kube-proxy 等

    1. 使用 **klog** 日志库,直接绕过默认的日志机制,写入到 `/var/log` 目录。<br />

    ```shell root@master1:/var/log/containers# ls … kube-proxy-dpgsc_kube-system_kube-proxy-6be17b882b5eab7e2429870c15cc4c74f3e25a9ac823ad32a2b656722a77e0c3.log kube-scheduler-master1_kube-system_kube-scheduler-7225dd07455e3f1ae42d3e17e8cfe7046739ccbefcd7e318d02ba0413f1c36fb.log

```

  • 不在容器中运行的:kubelet 和 容器运行时(docker)

    如果是 `systemd` 机制的服务器上,写入 journald 中,否则写到 `/var/log` 目录,
    

需要考虑日志轮转

集群级日志架构

k8s 没有提供集群集日志架构,需要用户使用第三方方案解决:

  • 使用每个节点运行的节点级日志记录代理
  • 在应用程序的 Pod 中,包含专门记录日志的 sidecar 容器
    • 传输数据流的 Sidecar 容器
    • 具有日志代理功能的 Sidecar 容器
  • 应用程序直接推送到日志服务器

每种方案参考:https://kubernetes.io/zh/docs/concepts/cluster-administration/logging/