作者 | 余韬(迅飞)来源 | 阿里开发者公众号背景K8s丰富的controller为容器编排提供了极大的便利,其中针对单次任务和定时任务的需求,K8s提供了Job和Cronjob控制器来满足非常驻容器编排的需要由于这种非常驻的特征,任务容器的时长可能很短(如定时清理数据的任务),甚至有些任务因为一启动就运行失败出现秒退的情况,这给采集Job日志带来了很大的挑战本文将基于高性能轻量级可观测采集器iLogtail探讨Job日志的多种采集方案,分析这些方案在不同场景下对日志采集所能做到稳定性保证以及方案优化空间Job容器的特点为了表述方便,本文将由Job控制器控制的业务容器都称为Job容器相比于其他类型容器,Job容器具有如下特点:增删频率高:Job容器经常为周期性调度或者on-demand调度并且执行完毕即结束,因此增删频率会显著高于其他类型容器生命周期短:Job容器的预期就是执行完任务后退出,并非常驻服务,因此生命周期相对较短有些Job仅仅用于简单地删除历史数据等,生命周期仅秒级突发并发大:Job容器常在编排批处理任务或者测试场景使用,此类场景往往会瞬时触发大量Job容器实例的生成,并伴随生成大量日志Job日志采集方案选择的关键考虑点因此,对于Job日志采集以下三个考虑点至关重要容器发现速度:Job容器增删频率高,如果容器发现的速度太慢,那么可能还没有来得及发现容器,容器就已经销毁了,更妄谈数据采集开始采集延时:Job容器生命周期可能很短,K8s中Pod销毁时会连带删除其下所有容器数据,如果没有及时开始采集,那么就无法锁定文件句柄,被删除的文件数据也就无法采集了弹性支持:Job容器的突发高并发特性非常适合使用弹性资源以节省成本,因此对应地希望采集方案可以适配支持弹性扩缩容同时,容器日志采集的一些通用需求在选择方案时也需要纳入考量资源开销:更低的资源开销通常意味着更低的成本,同时也减少日志采集对业务使用资源的影响meta信息打标:元信息用来标识日志来源,丰富的元信息有助于日志的查找和使用侵入性:侵入性决定了采集日志的开发成本,同时更强的侵入性也会增加日志采集和业务的耦合,给未来方案修改升级带来潜在成本iLogtail容器采集方案比较DaemonSet采集方式DaemonSet采集方式,利用K8s的DaemonSet控制器在每一个节点上部署一个iLogtail容器用于该节点上所有容器的日志采集这种部署方式通过与节点上的docker.sock或者containerd.sock与容器运行时通信以发现节点上所有容器,从返回的容器信息中获取容器的标准输出路径和存储路径,并挂载主机路径以采集数据这种采集方式的好处非常明显,每个节点上只需要部署一个采集容器,与应用容器的数量无关十分节省资源,可以获取完整的容器meta信息,并且应用对采集容器不感知,完全没有侵入而与Job日志采集密切相关3个关键点上DaemonSet方式反而表现一般通过DaemonSet部署iLogtail时,iLogtail的发现容器的机制依赖与docker.sock或者containerd.sock通信,docker有自己的EventListener机制可以实时获取容器的创建销毁事件;而containerd则没有,只能通过轮询机制了解容器的创建销毁,在最新版本中轮询间隔为1秒,因此可以认为iLogtail发现容器的延时为1秒从发现容器到将开始数据采集还有一个3-6秒左右的延时,其中采集stdout的延时来自stdout采集插件内部的轮询间隔,而采集容器文件的延时则来自docker_file插件的轮询间隔和C++核心部分加载最新容器配置的频率限制因此,再加上一些处理耗时,DaemonSet方式预期的容器日志开始采集延时为5-8秒左右弹性方面,DaemonSet部署的iLogtail可以支持动态节点扩容方式,但无法直接支持没有物理节点的弹性容器扩容方式Sidecar采集方式Sidecar采集方式,利用K8s同一个Pod内的容器可以共享存储卷的特性,在一个业务Pod内同时部署业务和采集容器以达到业务数据的目的这种采集方式要求业务容器将需要采集的目录挂载出来与采集容器共享,采集容器则使用采集本地文件的方式采集业务容器日志这种方式本质上与主机采集没有太大区别,无需关心容器发现问题同时只要采集容器没有退出,Pod就会处于Running状态,共享存储卷上的文件也不会被删除,因此也就无需担心开始采集延时导致数据丢失的问题由于随业务容器Pod部署,Sidecar也可以灵活支持各种弹性扩缩容方案,因此在Job容器采集的关键3点上表现较好但是相比于DaemonSet,Sidecar并没有那么受欢迎,除了无法直接支持采集容器标准输出的功能因素外,还有一些缺点限制了其使用的范围首先是资源消耗较大,每个Pod都需要一个Sidecar采集容器,其资源开销与业务Pod数量成正比其次,由于采集的原理本质同主机,因此容器的meta信息无法自动采集,需要通过环境变量等方式暴露到采集容器中最后,每个业务Pod都需要为目标数据配置共享存储,并且要考虑通知采集容器退出的机制,存在一定的侵入性ECI弹性容器产品采集方式ECI是弹性容器实例的缩写(详见阿里云官方介绍),相当于一个小型虚拟机,用完即毁,没有物理节点的羁绊,对于突发高并发场景具备成本和弹性优势,而这刚好是部分Job容器使用场景的特点ECI产品采集方式的原理与DaemonSet采集方式类似,其不同点在于,在ECI中的iLogtail容器不受Kube Scheduler控制,而是由ECI进行控制的,对用户不可见iLogtail的容器发现方式,也不通过与docker.sock或containerd.sock通信,而是通过静态容器信息发现要采集的容器为了支持容器数据获取,ECI还会将ECI上的路径挂载到iLogtail容器中,与DaemonSet挂载主机路径原理相同ECI产品的采集方式自然对弹性扩缩容提供了良好的支持由于采集原理与DaemonSet类似,因此ECI采集方式也继承了部分DaemonSet采集的性质,比如完整获取meta信息的能力,比如容器发现和开始采集的延时但由于ECI产品采集方式采用静态文件发现容器的方式,启动后第一时间就能发现容器,因此实际延比DaemonSet小得多成本方面,虽然每个Pod都会启动一个ECI并附带iLogtail Pod,但由于弹性容器资源随用随还的特点,对于突发高并发的Job场景其实际成本可能比自建节点更低由于ECI仅为需要采集数据的容器创建iLogtail容器,因此需要一些手段判断业务容器的日志采集需求,目前支持采用CRD(K8s Operator)或者环境变量CRD方式是目前更为推荐的一种接入方式,对业务容器无入侵且支持更丰富的采集配置若采用环境变量方式,则存在一定的侵入性同容器采集方式同容器采集方式是指将采集进程和业务进程同容器部署,相当于将容器视为一个虚拟机的部署方式,因此采集的原理也完全同主机虽然这种方式看上去非常笨重,侵入性高,但在老业务容器化过程中却十分常见采用同容器部署,要保证Job数据不丢失,需要精心设计容器的退出机制,等待数据采集完成后才能退出由于采集进程与业务进程工作在同一容器中,因此这种采集方式不存在容器发现和开始采集的延时,也完全支持各类弹性方案在资源开销方面,每个业务容器均额外消耗采集进程开销,资源消耗较大而要采集容器的meta信息,则需要通过环境变量等方式暴露在业务容器中,不能进行自动标注独立存储采集方式独立存储方式是指容器将要采集的数据都打印到共享的pv或hostPath挂载的路径上,而采集容器只需要关心将pv或hostPath上的数据采集上来的采集方案有些Job调度器可以指定每个Job的日志路径,因此可以将日志都打在同一个共享卷上当使用共享pv上时,所有数据采集只需要由1个采集容器负责采集即可;使用hostPath时,则需要使用DaemonSet部署采集容器,使每个节点上都恰好有一个采集容器点击链接查看原文,获取更多福利
https://developer.aliyun.com/article/1070098?groupCode=alitech?utm_content=g_1000363193版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容
0 评论