准备

关于容器日志

Docker 的日志分为两类,一类是 Docker 引擎日志;另一类是容器日志。引擎日志一般都交给了系统日志,不同的操作系统会放在不同的位置。

本文主要介绍容器日志,容器日志可以理解是运行在容器内部的应用输出的日志,默认情况下,docker logs 显示当前运行的容器的日志信息,内容包含 STOUT(标准输出) 和 STDERR(标准错误输出)。日志都会以 json-file 的格式存储于 /var/lib/docker/containers/<容器id>/<容器id>-json.log,不过这种方式并不适合放到生产环境中。

  • 默认方式下容器日志并不会限制日志文件的大小,容器会一直写日志,导致磁盘爆满,影响系统应用。(docker log-driver 支持log文件的rotate)

  • Docker Daemon 收集容器的标准输出,当日志量过大时会导致 Docker Daemon 成为日志收集的瓶颈,日志的收集速度受限。

  • 日志文件量过大时,利用docker logs -f查看时会直接将 Docker Daemon 阻塞住,造成docker ps等命令也不响应。

Docker 提供了 logging drivers 配置,用户可以根据自己的需求去配置不同的log-driver,可参考官网 Configure logging drivers 。但是上述配置的日志收集也是通过Docker Daemon收集,收集日志的速度依然是瓶颈。

log-driver 日志收集速度
syslog 14.9 MB/s
json-file 37.9 MB/s

能不能找到不通过 Docker Daemon 收集日志直接将日志内容重定向到文件并自动 rotate 的工具呢?答案是肯定的采用S6基底镜像。S6-log 将 CMD 的标准输出重定向到/…/default/current,而不是发送到 Docker Daemon,这样就避免了 Docker Daemon 收集日志的性能瓶颈。本文就是采用S6基底镜像构建应用镜像形成统一日志收集方案。

关于k8s日志

k8s日志收集方案分成三个级别:

  1. 应用(Pod)级别

  2. 节点级别

  3. 集群级别

  • 应用(Pod)级别

Pod 级别的日志 , 默认是输出到标准输出和标志输入,实际上跟docker 容器的一致。使用 kubectl logs pod-name -n namespace 查看,具体参考。

https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#logs

  • 节点级别

Node 级别的日志 , 通过配置容器的log-driver来进行管理 , 这种需要配合logrotare来进行, 日志超过最大限制,自动进行rotate操作。

  • 集群级别

集群级别的日志收集,有三种节点代理方式,在node级别进行日志收集。一般使用DaemonSet部署在每个node中。这种方式优点是耗费资源少,因为只需部署在节点,且对应用无侵入。缺点是只适合容器内应用日志必须都是标准输出。

使用 sidecar container 作为容器日志代理,也就是在 pod 中跟随应用容器起一个日志处理容器,有两种形式:一种是直接将应用容器的日志收集并输出到标准输出(叫做Streaming sidecar container),但需要注意的是,这时候,宿主机上实际上会存在两份相同的日志文件:一份是应用自己写入的;另一份则是 sidecar 的 stdout 和 stderr 对应的 JSON 文件。这对磁盘是很大的浪费 , 所以说,除非万不得已或者应用容器完全不可能被修改。

另一种是每一个 pod 中都起一个日志收集 agent(比如 logstash 或 fluebtd )也就是相当于把方案一里的 logging agent放在了pod里。但是这种方案资源消耗(cpu,内存)较大,并且日志不会输出到标准输出,kubectl logs 会看不到日志内容。

应用容器中直接将日志推到存储后端,这种方式就比较简单了,直接在应用里面将日志内容发送到日志收集服务后端。

日志架构

通过上文对k8s日志收集方案的介绍,要想设计一个统一的日志收集系统,可以采用节点代理方式收集每个节点上容器的日志,日志的整体架构如图所示。

解释如下:

  1. 所有应用容器都是基于s6基底镜像的,容器应用日志都会重定向到宿主机的某个目录文件下比如/data/logs/namespace/appname/podname/log/xxxx.log

  2. log-agent 内部 包含 filebeat ,logrotate 等工具,其中filebeat是作为日志文件收集的agent

  3. 通过filebeat将收集的日志发送到kafka

  4. kafka在讲日志发送的es日志存储/kibana检索层

  5. logstash 作为中间工具主要用来在es中创建index和消费kafka 的消息

整个流程很好理解,但是需要解决的是

  1. 用户部署的新应用,如何动态更新filebeat配置,

  2. 如何保证每个日志文件都被正常的rotate,

  3. 如果需要更多的功能则需要二次开发filebeat,使filebeat 支持更多的自定义配置。

付诸实践

解决上述问题,就需要开发一个log-agent应用以daemonset形式运行在k8s集群的每个节点上,应用内部包含filebeat,logrotate,和需要开发的功能组件。

第一个问题,如何动态更新filebeat配置,可以利用http://github.com/fsnotify/fsnotify 工具包监听日志目录变化create、delete事件,利用模板渲染的方法更新filebeat配置文件

第二个问题,利用http://github.com/robfig/cron 工具包 创建cronJob,定期rotate日志文件,注意应用日志文件所属用户,如果不是root用户所属,可以在配置中设置切换用户

/var/log/xxxx/xxxxx.log {      su www-data www-data      missingok      notifempty      size 1G      copytruncate    }

第三个问题,关于二次开发filebeat,可以参考博文 https://www.jianshu.com/p/fe3ac68f4

总结

本文只是对k8s日志收集提供了一个简单的思路,关于日志收集可以根据公司的需求,因地制宜。

参考文献

  1. https://kubernetes.io/docs/concepts/cluster-administration/logging/

  2. https://support.rackspace.com/how-to/understanding-logrotate-utility/

  3. https://github.com/elastic/beats/tree/master/filebeat

  4. http://skarnet.org/software/s6/

Kubernetes 平台中的日志收集的更多相关文章

  1. 日志分析平台ELK之日志收集器logstash

    前文我们聊解了什么是elk,elk中的elasticsearch集群相关组件和集群搭建以及es集群常用接口的说明和使用,回顾请查看考https://www.cnblogs.com/qiuhom-187 ...

  2. 日志分析平台ELK之日志收集器filebeat

    前面我们了解了elk集群中的logstash的用法,使用logstash处理日志挺好的,但是有一个缺陷,就是太慢了:当然logstash慢的原因是它依赖jruby虚拟机,jruby虚拟机就是用java ...

  3. 日志分析平台ELK之日志收集器logstash常用插件配置

    前文我们了解了logstash的工作流程以及基本的收集日志相关配置,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13761906.html:今天我们来了解下l ...

  4. 如何更优雅的在kubernetes平台下记录日志

    背景 传统项目里面记录日志大多数都是将日志记录到日志文件,升级到分布式架构以后,日志开始由文件转移到elasticsearch(es)中来存储,达到集中管理.在kubernetes平台里面把日志记录到 ...

  5. kubernetes-平台日志收集(ELK)

    使用ELK Stack收集Kubernetes平台中日志与可视化 K8S系统的组件日志 K8S Cluster里面部署的应用程序日志 日志系统: ELK安装 安装jdk [root@localhost ...

  6. 关于K8s集群器日志收集的总结

    本文介绍了kubernetes官方提供的日志收集方法,并介绍了Fluentd日志收集器并与其他产品做了比较.最后介绍了好雨云帮如何对k8s进行改造并使用ZeroMQ以消息的形式将日志传输到统一的日志处 ...

  7. kubernets轻量 contain log 日志收集技巧

    首先这里要收集的日志是容器的日志,而不是集群状态的日志 要完成的三个点,收集,监控,报警,收集是基础,监控和报警可以基于收集的日志来作,这篇主要实现收集 不想看字的可以直接看代码,一共没几行,尽量用调 ...

  8. 日志收集系统系列(三)之LogAgent

    一.什么是LogAhent 类似于在linux下通过tail的方法读日志文件,将读取的内容发给kafka,这里的tailf是可以动态变化的,当配置文件发生变化时,可以通知我们程序自动增加需要增加的配置 ...

  9. Flume日志收集系统架构详解--转

     2017-09-06 朱洁 大数据和云计算技术 任何一个生产系统在运行过程中都会产生大量的日志,日志往往隐藏了很多有价值的信息.在没有分析方法之前,这些日志存储一段时间后就会被清理.随着技术的发展和 ...

  10. 日志收集系统elk

    目录 elk简介 官方帮助 rsyslog rsyslog日志采集介绍与使用 综合实验 案例一: 单机ELK部署 案例二. JAVA环境配置,部署 filebeat+Elasticsearch apa ...

随机推荐

  1. Nextcloud报 PHP zip 模块未安装

    wget https://pecl.php.net/get/zip自动下载最新包 tar xf zip-1.20.0.tgz cd zip-1.20.0/ phpize 报错system libzip ...

  2. 使用tkinter开发的一款登录和注册图形化界面

    目录 项目介绍 登录功能 登录界面展示 登录主要功能 登录部分源码 注册功能 注册界面展示 注册主要功能 注册部分源码 源码地址 项目介绍 使用tkinter开发的一款登录和注册图形化界面 使用tki ...

  3. 用 go 实现多线程下载器

    本篇文章我们用Go实现一个简单的多线程下载器. 1.多线程下载原理 通过判断下载文件链接返回头信息中的 Accept-Ranges 字段,如果为 bytes 则表示支持断点续传. 然后在请求头中设置 ...

  4. js获取字符串中含有某个字符个数

    得到字符串含有某个字符的个数 /** * 获取字符串中某字符的个数 * @param str 字符串 * @param char char为某字符 * @returns String */ const ...

  5. json类型数据取出想要的部分

    因为才疏学浅,只能用很笨的方法. 以下是我拿到的数据的json型数据. {"result":{"ingredient":{"result": ...

  6. php 反序列化字符串逃逸

    这里总结一下反序列化字符串逃逸的知识点 反序列化字符串逃逸分为 被过滤后字符增多和字符减少的情况 这里就不讲之前的基础知识了 大家看其它师傅写的博客就可以了 很多师傅的文章写的都很细 现在直接就开始进 ...

  7. [转载] MATLAB | RGB image representation

    转载自https://www.geeksforgeeks.org/matlab-rgb-image-representation/ MATLAB | RGB image representation ...

  8. 【RUNOOB】C语言学习之指针

    资料来源: (1) runoob; (2) C语言程序设计; 注1:Runoob中对于指针的讲述比较清晰简单,摘录出来(后续补充指针与结构体,指针与函数参数); 1.指针与变量的内存位置 (1) 每个 ...

  9. 一些开源软件的LOGO

    整理一些开源软件的logo或者吉祥物,主要是一些以动物形象为主的logo. 1. GNU,不是一个软件,而是一个软件组织,包括很多知名的软件例如GCC编译器. GNU的LOGO是一只牛. GCC的lo ...

  10. 解析bean封装成BeanDefinition

    默认命名空间 1:parseDefaultElement 从代码中可以了解到默认的命名空间的一节节点主要是4种,import,alias,bean,beans private void parseDe ...