关于容器日志
Docker的日志分为两类,一类是 Docker引擎日志;另一类是容器日志。引擎日志一般都交给了系统日志,不同的操作系统会放在不同的位置。本文主要介绍容器日志,容器日志可以理解是运行在容器内部的应用输出的日志,默认情况下,docker logs 显示当前运行的容器的日志信息,内容包含 STOUT(标准输出) 和 STDERR(标准错误输出)。日志都会以 json-file 的格式存储于/var/lib/docker/containers/<容器id>/<容器id>-json.log,不过这种方式并不适合放到生产环境中。
Docker提供了logging drivers配置,用户可以根据自己的需求去配置不同的log-driver,可参考官网 Configure logging drivers[1] 。但是上述配置的日志收集也是通过Docker Daemon收集,收集日志的速度依然是瓶颈。
log-driver 日志收集速度 syslog 14.9 MB/s json-file 37.9 MB/s
能不能找到不通过Docker Daemon收集日志直接将日志内容重定向到文件并自动 rotate的工具呢?答案是肯定的采用S6[2]基底镜像。
S6-log 将 CMD 的标准输出重定向到/…/default/current,而不是发送到 Docker Daemon,这样就避免了 Docker Daemon 收集日志的性能瓶颈。本文就是采用S6[3]基底镜像构建应用镜像形成统一日志收集方案。
k8s日志收集方案分成三个级别:
1、应用(Pod)级别 2、节点级别 3、集群级别
Pod级别的日志 , 默认是输出到标准输出和标志输入,实际上跟docker 容器的一致。使用 kubectl logs pod-name -n namespace 查看,具体参考[4]。
Node级别的日志 , 通过配置容器的log-driver[5]来进行管理 , 这种需要配合logrotare[6]来进行 , 日志超过最大限制 , 自动进行rotate操作。
集群级别的日志收集 , 有三种
一种是直接将应用容器的日志收集并输出到标准输出(叫做Streaming sidecar container),但需要注意的是,这时候,宿主机上实际上会存在两份相同的日志文件:一份是应用自己写入的;另一份则是 sidecar 的 stdout 和 stderr 对应的 JSON 文件。这对磁盘是很大的浪费 , 所以说,除非万不得已或者应用容器完全不可能被修改。
另一种是每一个pod中都起一个日志收集agent(比如logstash或fluebtd)也就是相当于把方案一里的 logging agent放在了pod里。但是这种方案资源消耗(cpu,内存)较大,并且日志不会输出到标准输出,kubectl logs 会看不到日志内容。
通过上文对k8s日志收集方案的介绍,要想设计一个统一的日志收集系统,可以采用节点代理方式收集每个节点上容器的日志,日志的整体架构如图所示。
解释如下:
整个流程很好理解,但是需要解决的是
解决上述问题,就需要开发一个log-agent应用以daemonset形式运行在k8s集群的每个节点上,应用内部包含filebeat,logrotate,和需要开发的功能组件。
第一个问题,如何动态更新filebeat配置,可以利用http://github.com/fsnotify/fsnotify[8] 工具包监听日志目录变化create、delete事件,利用模板渲染的方法更新filebeat配置文件
第二个问题,利用http://github.com/robfig/cron[9] 工具包 创建cronJob,定期rotate日志文件,注意应用日志文件所属用户,如果不是root用户所属,可以在配置中设置切换用户
/var/log/xxxx/xxxxx.log {
su www-data www-data
missingok
notifempty
size 1G
copytruncate
}
第三个问题,关于二次开发filebeat,可以参考博文 https://www.jianshu.com/p/fe3ac68f4a7a[10]
本文只是对k8s日志收集提供了一个简单的思路,关于日志收集可以根据公司的需求,因地制宜。
https://kubernetes.io/docs/concepts/cluster-administration/logging/[11] https://support.rackspace.com/how-to/understanding-logrotate-utility/[12] https://github.com/elastic/beats/tree/master/filebeat[13] http://skarnet.org/software/s6/[14]
[1] Configure logging drivers:
https://link.zhihu.com/?target=https%3A//docs.docker.com/v17.09/engine/admin/logging/overview/
[2] S6:
https://link.zhihu.com/?target=http%3A//skarnet.org/software/s6/
[3] S6:
https://link.zhihu.com/?target=http%3A//skarnet.org/software/s6/
[4] 具体参考:
https://link.zhihu.com/?target=https%3A//kubernetes.io/docs/reference/generated/kubectl/kubectl-commands%23logs
[5] log-driver:
https://link.zhihu.com/?target=https%3A//docs.docker.com/config/containers/logging/configure/
[6] logrotare:
https://link.zhihu.com/?target=https%3A//linux.die.net/man/8/logrotate
[7] filebeat:
https://link.zhihu.com/?target=https%3A//github.com/elastic/beats/tree/master/filebeat
[8] http://github.com/fsnotify/fsnotify:
https://link.zhihu.com/?target=http%3A//github.com/fsnotify/fsnotify
[9] http://github.com/robfig/cron:
https://link.zhihu.com/?target=http%3A//github.com/robfig/cron
[10] https://www.jianshu.com/p/fe3ac68f4a7a:
https://link.zhihu.com/?target=https%3A//www.jianshu.com/p/fe3ac68f4a7a
[11] https://kubernetes.io/docs/concepts/cluster-administration/logging/:
https://link.zhihu.com/?target=https%3A//kubernetes.io/docs/concepts/cluster-administration/logging/
[12] https://support.rackspace.com/how-to/understanding-logrotate-utility/:
https://link.zhihu.com/?target=https%3A//support.rackspace.com/how-to/understanding-logrotate-utility/
[13] https://github.com/elastic/beats/tree/master/filebeat:
https://link.zhihu.com/?target=https%3A//github.com/elastic/beats/tree/master/filebeat
[14] http://skarnet.org/software/s6/:
https://link.zhihu.com/?target=http%3A//skarnet.org/software/s6/