阿里云原生 Kubernetes 日志监控的架构设计方案
在 Logging 这块做了几年,最近1年来越来越多的同学来咨询如何为 Kubernetes 构建一个日志系统或者是来求助在这过程中遇到一系列问题如何解决,授人以鱼不如授人以渔,于是想把我们这些年积累的经验以文章的形式发出来,让看到这篇文章的同学能少走弯路。这个系列文章定位为长篇连载,内容偏向落地实操以及经验分享,且内容会随着技术的迭代而不定期更新。
前言
第一次听到Kubernetes的名字是在16年,那个时候Kubernetes还处于和Docker Swarm、Mesos方案的“三国鼎立时代”,Kubernetes由于一系列优势(可扩展、声明式接口、云友好)在这一竞争中崭露头角,最终获得统治地位。Kubernetes作为CNCF最核心的项目(没有之一),是Cloud Native(云原生)落地的底座,目前阿里已经全面基于Kubernetes在开展全站的云原生改造,在1-2年内,阿里巴巴100%的业务都将跑在公有云上。
CloudNative在CNCF的定义[1]的核心是:在公有云、私有云、混合云等环境中,通过Containers、Service Meshes、 MicroServices、Immutable Infrastructure、Declarative APIs构建和运行可弹性扩展的且具有高容错性、易于管理、可观察、松耦合的应用系统。可观察性是应用系统必不可少的一个部分,云原生的设计理念中就有一条:面向诊断性设计(Diagnosability),包括集群级别的日志、Metric和Trace。
为何我们需要日志系统
通常一个线上问题的定位流程是:通过Metric发现问题,根据Trace定位到问题模块,根据模块具体的日志定位问题原因。在日志中包括了错误、关键变量、代码运行路径等信息,这些是问题排查的核心,因此日志永远是线上问题排查的必经路径。
在阿里的十多年中,日志系统伴随着计算形态的发展在不断演进,大致分为3个主要阶段:
•在单机时代,几乎所有的应用都是单机部署,当服务压力增大时,只能切换更高规格的IBM小型机。日志作为应用系统的一部分,主要用作程序Debug,通常结合grep等Linux常见的文本命令进行分析。•随着单机系统成为制约阿里业务发展的瓶颈,为了真正的Scale out,飞天项目启动:2013年飞天5K项目正式上线。在这个阶段各个业务开始了分布式改造,服务之间的调用也从本地变为分布式,为了更好的管理、调试、分析分布式应用,我们开发了Trace(分布式链路追踪)系统、各式各样的监控系统,这些系统的统一特点是将所有的日志(包括Metric等)进行集中化的存储。•为了支持更快的开发、迭代效率,近年来我们开始了容器化改造,并开始了拥抱Kubernetes生态、业务全量上云、Serverless等工作。在这阶段,日志无论从规模、种类都呈现爆炸式的增长,对日志进行数字化、智能化分析的需求也越来越高,因此统一的日志平台应运而生。
可观察性的终极解读
在CNCF中,可观察性的主要作用是问题的诊断,上升到公司整体层面,可观察性(Observability)不仅仅包括DevOps领域,还包括业务、运营、BI、审计、安全等领域,可观察性的最终的目标是实现公司各个方面的数字化、智能化。
在阿里,几乎所有的业务角色都会涉及到各式各样的日志数据,为了支撑各类应用场景,我们开发了非常多的工具和功能:日志实时分析、链路追踪、监控、数据加工、流计算、离线计算、BI系统、审计系统等等。日志系统主要专注于数据的实时采集、清洗、智能分析与监控以及对接各类各样的流计算、离线系统。
Kubernetes日志系统建设难点
单纯日志系统的解决方案非常多,相对也比较成熟,这里就不再去赘述,我们此次只针对Kubernetes上的日志系统建设而论。Kubernetes上的日志方案相比我们之前基于物理机、虚拟机场景的日志方案有很大不同,例如:
•日志的形式变的更加复杂,不仅有物理机/虚拟机上的日志,还有容器的标准输出、容器内的文件、容器事件、Kubernetes事件等等信息需要采集。•环境的动态性变强,在Kubernetes中,机器的宕机、下线、上线、Pod销毁、扩容/缩容等都是常态,这种情况下日志的存在是瞬时的(例如如果Pod销毁后该Pod日志就不可见了),所以日志数据必须实时采集到服务端。同时还需要保证日志的采集能够适应这种动态性极强的场景。•日志的种类变多,上图是一个典型的Kubernetes架构,一个请求从客户端需要经过CDN、Ingress、Service Mesh、Pod等多个组件,涉及多种基础设施,其中的日志种类增加了很多,例如K8s各种系统组件日志、审计日志、ServiceMesh日志、Ingress等。•业务架构变化,现在越来越多的公司开始在Kubernetes上落地微服务架构,在微服务体系中,服务的开发更加复杂,服务之间的依赖以及服务底层产品的依赖越来越多,这时的问题排查将更加复杂,如果关联各个维度的日志将是一个困难的问题。•日志方案集成困难,通常我们都会在Kubernetes上搭建一套CICD系统,这套CICD系统需要尽可能的自动化的完成业务的集成和部署,其中日志的采集、存储、清洗等也需要集成到这套系统中,并和K8s的声明式部署方式尽可能一致。而现有的日志系统通常都是较独立的系统,集成到CICD中代价极大。•日志规模问题,通常在系统初期的时候我们会选择自建开源的日志系统,这种方式在测试验证阶段或公司发展初期是没有什么问题的,但当业务逐渐增长,日志量增长到一定规模时,自建的开源系统很多时候都会遇到各种各样的问题,例如租户隔离、查询延迟、数据可靠性、系统可用性等。日志系统虽不是IT中最核心的路径,但一旦关键时刻出现这些问题都将是非常可怕的影响,例如大促的时候出现紧急问题,排查时多个工程师并发查询把日志系统打爆,导致故障恢复时间变长,大促收到影响。
那么如何在云原生的场景下搭建一个灵活、功能强大、可靠、可扩容的日志系统呢?
需求驱动架构设计
技术架构,是将产品需求转变为技术实现的过程。对于所有的架构师而言,能够将产品需求分析透彻是非常基本也是非常重要的一点。很多系统刚建成没多久就要被推翻,最根本的原因还是没有解决好产品真正的需求。
我所在的日志服务团队在日志这块有近10年的经验,几乎服务阿里内部所有的团队,涉及电商、支付、物流、云计算、游戏、即时通讯、IoT等领域,多年来的产品功能的优化和迭代都是基于各个团队的日志需求变化。
有幸我们最近几年在阿里云上实现了产品化,服务了数以万计的企业用户,包括国内各大直播类、短视频、新闻媒体、游戏等行业Top1互联网客户。产品功能从服务一个公司到服务上万家公司会有质的差别,上云促使我们更加深入的去思考:究竟哪些功能是日志这个平台需要去为用户去解决的,日志最核心的诉求是什么,如何去满足各行各业、各种不同业务角色的需求...
需求分解与功能设计
上一节中我们分析了公司内各个不同角色对于日志的相关需求,总结起来有以下几点:
•支持各种日志格式、数据源的采集,包括非K8s•能够快速的查找/定位问题日志•能够将各种格式的半结构化/非结构化日志格式化,并支持快速的统计分析、可视化•支持通过日志进行实时计算并获得一些业务指标,并支持基于业务指标实时的告警(其实本质就是APM)•支持对于超大规模的日志进行各种维度的关联分析,可接受一定时间的延迟•能够便捷的对接各种外部系统或支持自定义的获取数据,例如对接第三方审计系统•能够基于日志以及相关的时序信息,实现智能的告警、预测、根因分析等,并能够支持自定义的离线训练方式以获得更好的效果
为满足上述这些功能需求,日志平台上必须具备的功能功能模块有:
•全方位日志采集,支持DaemonSet、Sidecar各种采集方式以应对不同的采集需求,同时支持Web、移动端、IoT、物理机/虚拟机各种数据源的采集;•日志实时通道,这个是为了对接上下游所必备的功能,保证日志能够被多种系统所便捷的使用;•数据清洗(ETL: Extract,Transform,Load),对各种格式的日志进行清洗,支持过滤、富化、转换、补漏、分裂、聚合等;•日志展现与搜索,这是所有日志平台必须具备的功能,能够根据关键词快速的定位到日志并查看日志上下文,看似简单的功能却最难做好;•实时分析,搜索只能完成一些定位到问题,而分析统计功能可以帮助快速分析问题的根因,同时可以用于快速的计算一些业务指标;•流计算,通常我们都会使用流计算框架(Flink、Storm、Spark Stream等)来计算一些实时的指标或对数据进行一些自定义的清洗等;•离线分析,运营、安全相关的需求都需要对大量的历史日志进行各种维度的关联计算,目前只有T+1的离线分析引擎能够完成;•机器学习框架,能够便捷、快速的将历史的日志对接到机器学习框架进行离线训练,并将训练后的结果加载到线上实时的算法库中。
开源方案设计
借助于强大的开源社区,我们可以很容易基于开源软件的组合来实现这样一套日志平台,上图是一个非常典型的以ELK为核心的日志平台方案:
•利用FileBeats、Fluentd等采集Agent实现容器上的数据统一收集。•为了提供更加丰富的上下游以及缓冲能力,可以使用kafka作为数据采集的接收端。•采集到的原始数据还需要进一步的清洗,可以使用Logstash或者Flink订阅Kafka中的数据,清洗完毕后再写入kafka中。•清洗后的数据可以对接ElasticSearch来做实时的查询检索、对接Flink来计算实时的指标和告警、对接Hadoop来做离线的数据分析、对接TensorFlow来做离线模型训练。•数据的可视化可以使用grafana、kibana等常用的可视化组件。
为什么我们选择自研
采用开源软件的组合是非常高效的方案,得益于强大的开源社区以及庞大用户群体的经验积累,我们可以很快搭建出这样一套系统,并且可以满足我们绝大部分的需求。
当我们把这套系统部署好,能够把日志从容器上采集上来、elasticsearch上能够查到、Hadoop上能够成功执行SQL、Grafana上能看到图、告警短信能收到。。。完成上述流程打通后,加加班可能只需要花费几天的时间,当系统终于跑通的时候,这时候终于可以长舒一口气,躺在办公椅上放松放松。
然而理想很丰满现实很骨感,当我们预发通了,测试完了上到生产,开始接入第一个应用,逐渐更多的应用接入,越来越多的人开始使用。。。这时候很多问题都可能暴露出来:
•随着业务量的上涨,日志量也越来越大,Kakfa和ES要不断扩容,同时同步Kafka到ES的Connector也需要扩容,最烦的是采集Agent,每台机器上部署的DaemonSet Fluentd根本没办法扩容,到了单Agent瓶颈就没办法了,只能换Sidecar,换Sidecar工作量大不说,还会带来一系列其他的问题,比如怎么和CICD系统集成、资源消耗、配置规划、stdout采集不支持等等。•从刚开始上的边缘业务,慢慢更多的核心业务接入,对于日志的可靠性要求越来越高,经常有研发反应从ES上查不到数据、运营说统计出来的报表不准、安全说拿到的数据不是实时的。。。每次问题的排查都要经过采集、队列、清洗、传输等等非常多的路径,排查代价非常高。同时还要为日志系统搭建一套监控方案,能够即时发现问题,而且这套方案还不能基于日志系统,不能自依赖。•当越来越多的开发开始用日志平台调查问题时,经常会出现因为某1-2个人提交一个大的查询,导致系统整体负载上升,其他人的查询都会被Block,甚至出现Full GC等情况。这时候一些大能力的公司会对ES进行改造,来支持多租户隔离;或者为不同的业务部门搭建不同的ES集群,最后又要运维多个ES集群,工作量还是很大。•当投入了很多人力,终于能够把日志平台维持日常使用,这时候公司财务找过来了,说我们用了非常多的机器,成本太大。这时候开始要优化成本,但是思来想去就是需要这么多台机器,每天大部分的机器水位都在20%-30%,但是高峰的水位可能到70%,所以不能撤,撤了高峰顶不住,这时候只能搞搞削峰填谷,又是一堆工作量。
上述这些是一家中等规模的互联网企业在日志平台建设中经常会遇到的问题,在阿里这些问题会放大非常多倍:
•比如面对双十一的流量,市面上所有的开源软件都无法满足我们那么大流量的需求。•面对阿里内部上万个业务应用,几千名工程师同时使用,并发和多租户隔离我们必须要做到极致。•面对非常多核心的订单、交易等场景,整个链路的稳定性必须要求3个9甚至4个9的可用性。•每天如此大的数据量,对于成本的优化显得极为重要,10%的成本优化带来的收益可能就有上亿。
阿里K8s日志方案
针对上述的一些问题,我们经过多年的时间,开发并打磨出这样一套K8s日志方案:
•使用我们自研的日志采集Agent Logtail实现K8s全方位的数据采集,目前Logtail在集团内有数百万的全量部署,性能、稳定性经过多次双十一金融级考验。•化繁为简,数据队列、清洗加工、实时检索、实时分析、AI算法等原生集成,而不是基于各种开源软件搭积木的形式实,大大降低了数据链路长度,链路长度的降低也意味着出错可能性的减少。•队列、清洗加工、检索、分析、AI引擎等全部针对日志场景深度定制优化,满足大吞吐、动态扩容、亿级日志秒级可查、低成本、高可用性等需求。•对于流式计算、离线分析场景这种通用需求,无论是开源还是阿里内部都有非常成熟的产品,我们通过无缝对接的方式来支持,目前日志服务支持了数十种下游的开源、云上产品的对接。
这套系统目前支撑了整个阿里集团、蚂蚁集团、云上上万家企业的日志分析,每天写入的数据量16PB+,开发、运维这样一套系统问题和挑战非常多,这里就不再展开,有兴趣的同学可以参考我们团队的技术分享:阿里10PB/天日志系统设计和实现[2]。
总结
相信在搞K8s日志系统建设的同学看到上面的难点分析都会深有感触,本篇主要从架构层面去介绍如何搭建一套K8s的日志分析平台,包括开源方案以及我们阿里自研的一套方案。然而实际这套系统落地到生产环境并有效运行还有很多工作要做:
•K8s上以什么样的姿势来打日志?•K8s上的日志采集方案选择,DaemonSet or Sidecar?•日志方案如何与CICD去集成?•微服务下各个应用的日志存储如何划分?•如何基于K8s系统的日志去做K8s监控?•如何去监控日志平台的可靠性?•如何去对多个微服务/组件去做自动的巡检?•如何自动的监控多个站点并实现流量异常时的快速定位?
后续文章我们会一步一步来和大家分享如何把这套系统落地,敬请期待。
引用链接
[1]
CNCF的定义: https://www.cncf.io/webinars/what-is-cloud-native-and-why-does-it-exist[2]
阿里10PB/天日志系统设计和实现: https://zhuanlan.zhihu.com/p/75513049
END
关注我