谈一下Docker与Kubernetes集群的日志和日志管理

本文的测试环境为CentOS 7.3,Kubernetes集群为1.11.2,安装步骤参见kubeadm安装kubernetes V1.11.1 集群

日志对于我们管理Kubernetes集群及其上的应用具有非常重要的作用,特别是在出现故障或者Bug的时候。如果你能回答下面几个问题,那么可以不用再看本文了,如果不能回答,本文可能正好适合你。

  • Docker都会产生哪些日志?
  • Docker产生的日志都放在哪里?
  • Docker的日志的分割、清理策略默认为什么?
  • 如何配置Docker日志的分割、清理策略?
  • Kubernetes都会产生哪些日志?
  • Kubernetes产生的日志都存放在那里?
  • 如何集中管理Kubernetes产生的日志?

1. Docker的日志处理方案

Docker产生的日志有两类:

  • 一类是Docker引擎日志。Docker引擎日志在不同的操作系统下管理方式不一样,在Centos中是通过journalctl来进行管理。
  • 一类是容器日志。容器中的应用产生的日志默认都输出到stdoutstderr中,可以通过docker logs来访问。Docker为容器日志提供了多种实现机制称为logging driver。通过docker info可以查看本机使用的logging driver,默认为json-file形式,这种形式下每个容器的日志默认以json格式存储在/var/lib/docker/containers/<容器id>/<容器id>-json.log下。下面两种情况使用docker logs看不到什么有用的信息:
    • 容器内的应用不是交互式应用,而是实现了自己的日志输出,例如对于Apache、Nginx等Web服务,通常会将访问日志和错误日志记录到不同的文件,而不是打到标准输出和错误输出。
    • 使用不同的logging driver将日志送到了文件、外部服务器、数据库等集中的日志后台。

Docker目前支持的logging driver类型:

  • none
  • json-file
  • syslog
  • journald
  • gelf
  • fluentd
  • awslogs
  • splunk
  • etwlogs
  • gcplogs
  • logentries

1.1 配置logging driver

运行容器时,可以通过命令行参数指定logging driver的类型。

bogon:log rousseau$ docker run -it --log-driver none alpine sh
/ # ls
#切换一个终端
bogon:log rousseau$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
8ec61e8feb61        alpine              "sh"                13 seconds ago      Up 12 seconds                           xenodochial_ptolemy
bogon:log rousseau$ docker logs 8ec61e8feb61
Error response from daemon: configured logging driver does not support reading
bogon:log rousseau$ docker inspect -f '{{.HostConfig.LogConfig.Type}}' 8ec61e8feb61
none

对于日志输出到文件的应用,可以通过软连接的方式将日志输出到标准输出和标准错误输出。例如:The official nginx image creates a symbolic link from /var/log/nginx/access.log to /dev/stdout, and creates another symbolic link from /var/log/nginx/error.log to /dev/stderr, overwriting the log files and causing logs to be sent to the relevant special device instead.

对于多行格式的日志信息,有一点需要特别关注。The Docker json logging driver treats each line as a separate message. When using the Docker logging driver, there is no direct support for multi-line messages. You need to handle multi-line messages at the logging agent level or higher.

1.3 日志分割策略配置

在CentOS中,可以通过修改/etc/docker/daemon.json来配置Docker的日志分割策略。

{
    "log-driver": "json-file",
    "log-opts": {
        "max-size": "9m", # Max size of the log files.
        "max-file": "5" # The maximum number of log files that can be present.
    }
}

总结:对于单机的Docker来说,可以将日志以json-file的形式存储到本地磁盘,同时提供了根据文件大小进行文件分割的配置,也提供了根据文件数量进行文件清理的策略。配置好这两个参数,基本上就不需要担心容器应用将磁盘写满的风险了。而Docker引擎本身的日志则是通过journald来进行管理的。

2. Kubernetes的日志处理方案

Kubernetes的日志管理方式与Docker有所不同,因为容器封装在Pod中,当遇到Pod被删除或者Node节点故障的情况下,日志会被删除,单纯依靠Docker本身的日志机制将无法在故障后查询日志,因此在管理集群时需要认真考虑日志的管理问题。

Kubernetes集群的日志包括以下几种:

  • 各种event事件,可以通过kubectl describe pod查看到详细信息
  • 容器应用产生的日志
  • Node节点上Docker Daemon产生的日志
  • Node节点上kubelet产生的日志

2.1 日志的位置

Kubernetes集群中包含众多组件,在用kubeadm方式安装的集群上,有些组件不是容器化运行的,包括Master节点的kubelet、kube-scheduler、kube-controller-manager、kube-apiserver,Node节点上运行了kubelet和kube-proxy。有些组件是容器化方式运行的,当然包括我们的应用。因此日志就分为两类:容器化组件及应用的日志,非容器化组件的日志。

2.1.1 容器化组件及应用的日志管理

对于容器化的组件和应用,其日志的管理方式都通过Docker的log-driver来进行指定,因此Kubernetes本身并不提供日志分割的功能。有两种方式来实现日志的分割:

  • 通过Docker配置log-opt参数,与上一节的方式相同。
  • 通过其他的脚本,例如kube-up.sh来分割日志文件。

如果使用外部工具对日志进行了分割,再通过docker logs目录查看日志时,仅返回最新的文件中的内容。

2.1.2 非容器化的组件日志管理。

系统组件也分为两种,一种是运行在容器中的应用,包括schedulerkube-proxy等;一种是没有运行在容器中的应用,包括kubelet和容器运行环境。这些组件的日志都是通过journald来进行管理的。

2.2 集群级别的日志管理

Kubernetes本身没有提供集群级别的日志管理功能,如想实现集群级别的日志管理有三种方案:

  • 在每个Node中运行日志采集代理,将日志收集到集中的日志管理平台。这种方案对应用没有侵入性,是优选方案。
  • 在前一种方案的基础上,在每个应用Pod中增加Sidecar容器来实现日志的分离。
  • 应用直接将日志输出到统一的日志管理平台,不在本地落地,这种方案对于应用的侵入性较大

2.3.1 日志采集代理方案

这种方案在每台Node上运行一个专用的日志采集代理,可以是容器化的应用(需要能够在容器内访问节点上的日志文件),可以采用DaemonSet来确保代理在每个Node中都运行。

2.3.2 Sidecar方案

Sidecar的本意是挎斗摩托车,这种车型在摩托车旁边加了一个边斗来提高运载量,是二战时期日军广泛使用的一种运输工具。

类似于挎斗摩托车,Sidecar方案是在应用Pod中增加一个或多个负责处理日志的容器,根据增加容器的作用,可以分为日志分离和容器内代理。

2.3.2.1 日志分离

尽管CPU和内存资源的消耗非常少,但是读取日志文件并且重写到标准输出会加倍磁盘的负载,这一点需要特别注意。

2.3.2.2 容器内代理

采用这种方案,通过容器内代理直接将应用的日志上传到统一的日志管理平台,会增加Pod的资源消耗,同时无法通过kubectl logs命令来查看日志。

2.3.3 流式处理方案

参考资料

  1. Logging Architecture
  2. Docker日志都在哪里?怎么收集?
  3. Systemd之journalctl
  4. Kubectl logs
  5. Docker Logging Overview
  6. fluentd
  7. Stackdriver
  8. TLDC
  9. Kubernetes日志收集
  10. Kubernetes容器集群中的日志系统集成实践
  11. Where are the Kubernetes kublet logs located?
  12. Kubernetes Log Analysis with Fluentd, Elasticsearch and Kibana
  13. Kubernetes Log File Locations
  14. Kubernetes Logs

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏编程

手把手教你制作漏洞复现环境

在学习的过程中, 是否看到别人搭建的练习平台心痒痒呢? 通过本篇教程的学习, 将手把手教你搭建属于自己的漏洞测试利用环境, 不管是自己学习还有分享给小伙伴都将轻...

34010
来自专栏云计算教程系列

如何在Ubuntu 16.04上使用Docker Bench对Docker主机进行安全性审核

使用Docker来容纳您的应用程序和服务可以为您提供开始即用的一些安全优势,但默认的Docker安装仍然有一些空间可用于一些与安全相关的配置改进。在互联网安全中...

1663
来自专栏糊一笑

centos中docker的安装

1933
来自专栏性能与架构

Docker容器案例:应用 Mysql

前阶段体验 Mysql 的新版本 5.7.13,由于机器里已经有 Mysql了,再安装另一个版本会有一些麻烦,为了简单,便使用 Docker 容器来安装 可能有...

3353
来自专栏阮一峰的网络日志

Docker 入门教程

2013年发布至今, Docker 一直广受瞩目,被认为可能会改变软件行业。 但是,许多人并不清楚 Docker 到底是什么,要解决什么问题,好处又在哪里?本文...

3523
来自专栏holer

外网访问内网Docker容器

局域网里的主机上安装了Docker容器,只能在内网访问,怎样从外网也能访问内网的Docker容器?

2691

Docker Hub:保存并分享你的Docker镜像

Docker Hub 是一个基于云的注册服务网站,提供容器应用或容器服务的构建功能。

2436
来自专栏从流域到海域

Docker 编配 ...它是什么意思,为什么你会需要它

原文作者:Cloudify Community

2378
来自专栏PHP在线

Docker 入门教程

2013年发布至今, Docker 一直广受瞩目,被认为可能会改变软件行业。 但是,许多人并不清楚 Docker 到底是什么,要解决什么问题,好处又在哪里?本文...

3724
来自专栏云计算教程系列

如何在Ubuntu 14.04上使用Docker和Docker Compose配置持续集成测试环境

持续集成(CI)指的是开发人员尽可能频繁地集成代码,并且在自动化构建将每个提交合并到共享存储库之前和之后都要进行测试的实践。

580

扫码关注云+社区

领取腾讯云代金券