介绍:目前云原生技术基于容器技术,通过标准的、可扩展的调度、网络、存储、容器运行时接口提供基础设施。当Kubernetes成为云原生事实上的标准时,可观察性挑战随之而来。目前,云原生技术以容器技术为基础,通过标准和可扩展的调度、网络、存储和容器运行时接口提供基础设施。同时,使用标准的、可扩展的声明式资源和控制器来提供运维能力。两层标准化推动开发和运维关注点分离,进一步提升各领域的规模化和专业化,实现成本、效率和稳定性。全面优化。在这样的技术背景下,越来越多的企业引入云原生技术来开发、运维业务应用。正因为云原生技术带来了越来越复杂的可能性,业务应用才具有微服务众多、多语言开发、多通信协议的鲜明特征。同时,云原生技术本身降低了复杂度,给可观察性带来了更多挑战:1.微服务架构混乱,多语言多网络协议混合业务架构容易出现大量服务分工劳动力、呼叫协议和关系非常复杂,导致常见问题包括:无法准确清晰地理解和控制整体系统运行架构;无法回答应用程序之间的连接是否正确;多语言、多网络调用协议带来隐性成本线性增长,重复埋点ROI低。开发通常会降低此类需求的优先级,但必须收集可观察的数据。2.下沉的基础设施能力屏蔽了实现细节,更难圈定问题。基础设施能力持续下沉,开发与运维重心不断分离。分层之后,实现细节相互屏蔽,数据之间也没有很好的关联。问题发生后无法快速圈定出问题发生在哪一层。开发同学只关心应用是否正常运行,并不关心底层基础设施的细节。出现问题后,需要运维同学配合排查问题。在故障排除过程中,运维同学需要开发同学提供足够的上下游信息,以促进故障排除。否则,他们只能得到“某个应用程序具有高延迟”的笼统说法,很难得到进一步的结果。所以开发同学和运维同学需要一种共同的语言来提高沟通效率。Kubernetes的Label和Namespace等概念非常适合构建上下文信息。3.很多监控系统导致监控界面不一致。复杂系统的一个严重副作用是有很多监控系统。数据链路不关联统一,监控界面体验不一致。很多运维同学可能都有过这样的经历:定位问题时,浏览器打开几十个窗口,在Grafana、控制台、日志等工具之间来回切换,不仅耗时庞大,而且大脑可以处理它。信息有限,问题定位效率低。如果有一个统一的可观察性接口,数据和信息得到有效组织,减少分心和页面切换,提高问题定位的效率,将宝贵的时间投入到业务逻辑的构建中。解决思路和技术方案为了解决上述问题,我们需要使用一种支持多种语言和多种通信协议的技术,并尽可能覆盖软件栈端到端的可观察性需求产品水平。通过研究,我们提出了一种基于容器接口和底层操作系统,向上链接应用性能监控的可观察性解决方案。在容器、节点运行环境、应用程序和网络的各个维度收集数据是非常具有挑战性的。云原生社区针对不同的需求提供了cAdvisor、nodeexporter、kube-state-metics等方法,但仍然不能满足所有需求。不应低估维护许多收集器的成本。提出的一个想法是,有没有一种对应用无侵入、支持动态扩展的数据采集方案?目前最好的答案是eBPF。《数据采集:eBPF的超能力》eBPF相当于在内核中构建了一个执行引擎,通过内核调用将这个程序附加到一个内核事件上,从而监听内核事件。有了事件,我们可以进一步推导协议,过滤掉感兴趣的协议,将事件进一步处理后放入ringbuffer或者eBPF自带的数据结构Map中,供用户态进程读取。用户态进程读取数据后,进一步关联Kubernetes元数据,推送到存储端。这是整体流程。eBPF的超强能力体现在能够订阅各种内核事件,比如文件读写、网络流量等,运行在Kubernetes中的容器或Pod中的所有行为都是通过内核系统调用来实现的。内核知道机器上所有进程中发生的一切,因此内核几乎是可观察性的最佳位置,这就是我们选择eBPF的原因。在内核上进行监控还有一个好处就是应用程序不需要改动,也不需要重新编译内核,真正做到了无侵入。当集群中有数十个或数百个应用程序时,非侵入式解决方案将大有帮助。但作为一项新技术,eBPF存在一些问题,例如安全性和探测性能。为了充分保证内核运行时的安全,eBPF代码有很多限制,比如目前最大栈空间为512,最大指令数为100万条。同时出于性能考虑,eBPF探针控制在1%左右。它的高性能主要体现在内核中对数据的处理,减少了内核态和用户态之间的数据拷贝。简单的说就是在内核中计算数据,然后给用户进程,比如一个Gauge值。过去是将原始数据复制到用户进程中,然后进行计算。可编程执行引擎自然适合可观察性。可观测性工程帮助用户更好地了解系统内部状态,消除知识盲点,及时消除系统性风险。eBPF在可观察性方面有什么能力?以应用异常为例,当发现应用出现异常时,发现在解决问题的过程中缺乏应用级的可观察性。这时候应用的可观察性辅以埋点、测试、上线。具体问题解决了,但往往是治标不治本。下次其他地方出现问题时,需要遵循相同的过程。另外,多语言、多协议使得埋点成本更高。更好的办法是以非侵入式的方式解决,这样需要观察的时候就没有数据了。eBPF执行引擎可以通过动态加载和执行eBPF脚本来收集可观察性数据。举个具体的例子,假设原来的Kubernetes系统不做进程相关的监控。某天在疯狂占用CPU中发现了一个恶意进程(比如挖矿程序),这时候我们就会发现应该对这种恶意进程的创建进行监控。这时候我们可以通过集成一个开源的流程事件检测库来实现,但这往往需要一个完整的打包、测试、发布的过程,可能需要一个月的时间才能完成所有的工作。相比之下,eBPF方法效率更高,速度更快。由于eBPF支持动态加载内核监听进程创建的事件,我们可以将eBPF脚本抽象成一个子模块,获取客户端每次只需要加载这个子模块即可。模块中的脚本完成数据采集,然后通过统一的数据通道将数据推送到后端。这样,我们就省去了代码修改、打包、测试、发布的繁琐过程,以非侵入的方式动态实现流程监控的需求。因此,eBPF的可编程执行引擎非常适合增强可观察性、收集丰富的内核数据以及连接业务应用程序以方便故障排除。从监控系统到可观察性随着云原生的浪潮,可观察性的概念越来越流行。但是仍然离不开日志、指标、链接这三类可观察领域的数据基石。做过运维或者SRE的同学经常会遇到这样的问题:半夜被拉进应急群,被问为什么数据库不行。没有上下文,他们无法立即抓住问题的核心。我们认为,一个好的可观察性平台应该帮助用户很好地反馈上下文,就像DatadogCEO说的:监控工具不是越实用越好,而是要思考如何在不同的团队和成员之间搭建桥梁,把信息尽可能在同一页面上(以弥合团队之间的差距并将所有内容放在同一页面上)。因此,在可观测平台的产品设计中,需要基于指标、链接、日志等方式集成阿里云的各种云服务。不同背景的工程师理解,从而加快故障排除。如果信息没有有效组织,就会产生理解成本。在信息粒度上,事件->指标->链接->日志,由粗到细整理成一页,方便下钻,不需要多个系统来回跳转。这提供了一致的体验。那么它是如何相关的呢?信息是如何组织的?主要从两个角度:1.端到端:扩展就是应用到应用,服务到服务,Kubernetes标准化和关注点分离,每个开发和维护都专注于自己的领域,所以端到-端监控往往成为“三不管”区域,当出现问题时,很难排查链路上的哪一环节出现问题。所以,从端到端的角度来看,两者之间的调用关系是关联的基础,因为系统调用是有联系的。通过eBPF技术可以非常方便地以非侵入的方式收集网络调用,然后将调用解析成众所周知的应用协议,如HTTP、GRPC、MySQL等,最后建立拓扑关系形成清晰的服务拓扑。快速定位问题,如下图,在网关->Java应用->Python应用->云服务的完整环节,如果有任何一个环节出现延迟,问题应该在服务拓扑。这是端到端的第一个管道点。2、自上而下的全栈关联:以Pod为媒介,Kubernetes层面可以关联Workload、Service等对象,基础设施层面可以关联节点、存储设备、网络等,应用layer可以关联日志、调用链接等。接下来介绍一下Kubernetes监控的核心功能。面向未来的黄金指标黄金指标是用于监控系统性能和状态的最小集合。黄金指标有两个好处:一是直接、清晰地表达了系统是否正常对外服务。其次,它可以快速评估对用户的影响或情况的严重性,这可以为SRE或研发节省大量时间。想象一下,如果我们把CPU使用率作为黄金指标,那么SRE或R&D会被耗尽,因为CPU使用率高可能影响不大。Kubernetes监控支持这些指标:请求数/QPS响应时间和分位数(P50、P90、P95、P99)错误数和慢调用数如下图:全局视角下的服务拓扑求域。当前技术架构和部署架构越来越复杂,问题发生后定位越来越难,导致MTTR越来越高,另外一个影响是对影响面的分析带来了很大的挑战,这通常会导致因此,像地图这样的大拓扑图是非常有必要的,全局拓扑图具有以下特点:系统架构感知:系统架构图是程序员理解一个新系统的重要参考。他们得到一个系统,最起码要知道流量入口在哪里,有哪些核心模块,依赖哪些内外部组件等等。在定位异常的过程中,有一张全局架构图,对定位异常的过程有很大的促进作用。依赖分析:下游依赖出现一些问题。如果这个依赖不是自己团队维护的话,会比较麻烦。当你自己的系统和下游系统没有足够的可观察性时,那就更麻烦了。在这种情况下,很难向依赖项的维护者明确问题。在我们的拓扑中,通过调用关系将黄金指标的上下游连接起来形成一个调用图。作为依赖关系的可视化,边缘可以查看与调用对应的黄金信号。有了goldensignal,可以快速分析下游依赖是否有问题。分布式跟踪有助于根本原因定位协议跟踪也是非侵入性和语言无关的。如果请求内容中有分布式链接TraceID,可以自动识别,方便进一步下钻链接跟踪。应用层协议的请求和响应信息有助于分析请求内容和返回码,从而知道是哪个接口出了问题。要查看代码级别或请求域的详细信息,请单击跟踪ID以深入到链接跟踪分析。开箱即用的告警功能开箱即用的告警模板,不同层级全覆盖,无需手动配置告警,将大规模Kubernetes运维经验融入告警模板,精心设计告警规则以及智能降噪和去重,我们可以实现一旦告警是有效告警,并且告警包含相关信息,我们可以快速定位到异常实体。告警规则全栈覆盖的好处是可以及时、主动地将高危事件报告给用户。用户可以通过故障排除、故障排除、事后回顾、面向故障的设计等一系列方法,逐步实现更好的系统稳定性。.网络性能监控网络性能问题在Kubernetes环境中非常常见。由于TCP底层机制屏蔽了网络传输的复杂性,应用层对此不敏感。这对于生产环境定位高丢包率和高重传率非常重要。问题会引起一些麻烦。Kubernetes监控支持RTT、重传&丢包、TCP连接信息来表示网络状况。下面以RTT为例,从namespace、node、container、Pod、service、workload等维度来支持网络性能。支持以下网络问题的定位:负载均衡无法访问某个Pod,而这个Pod上的流量为0,需要判断是Pod网络有问题还是负载均衡配置有问题;应用程序在某个节点上的性能似乎很低。很差。需要判断节点网络是否有问题。这可以通过检查其他节点网络来实现。丢包发生在链路上,但不确定发生在哪一层。可以按照node、pod、container的顺序检查。Kubernetes可观测性全景图有了以上产品能力,我们基于阿里巴巴在容器和Kubernetes方面丰富而深入的实践,将这些有价值的生产实践总结并转化为产品能力,帮助用户更有效、更快速、更准确地定位生产环境问题。可以通过以下方式来使用这个全景图:总体结构是基于服务和部署(应用程序),大多数开发人员只需要关注这一层。关注服务和应用是否慢,服务是否连通,副本数是否达到预期等。下一层是提供真正工作负载能力的Pod。Pod关注的是有没有错误或者慢请求,是否健康,资源是否充足,下游依赖是否健康等。底层是节点,为Pod和服务提供运行环境和资源。关注节点是否健康,是否处于可调度状态,资源是否充足等。生产环境网络问题:Kubernetes的网络架构高度复杂,节点、Pod、容器、服务、VPC相辅相成,看得眼花缭乱;排查网络问题需要一定的专业知识,而且大多对网络问题有一种天生的恐惧;分布式的8大谬误告诉我们,网络不稳定,网络拓扑结构不是一成不变的,延迟也不容忽视,导致端到端之间网络拓扑结构的不确定性。Kubernetes环境场景网络问题包括:conntrack记录满;知识产权冲突;CoreDNS解析速度慢,解析失败;节点未连接到外部网络。(是的,你听到的是对的);服务访问不可用;配置问题(LoadBalance配置、路由配置、设备配置、网卡配置);网络中断导致整个服务不可用。网络问题千千万万,但不变的是网络有其表征其正常运行的“黄金指标”:网络流量和带宽;丢包(率)和重传(率);RTT。下面的示例演示了网络问题导致的缓慢调用。从网关的角度来看,发生了慢速调用。查看拓扑,发现下游产品的RT比较高,但是产品本身的黄金指标说明产品本身的服务没有问题。进一步查看两者之间的网络状态,发现RTT和retransmission都比较高,说明网络性能变差了,导致整体网络传输变慢。TCP重传机制隐藏了这个事实,应用层无法感知,日志也无法揭示问题所在。这时,网络的黄金指标有助于问题的定界,从而加快排查问题的速度。节点问题Kubernetes做了很多工作来确保提供工作负载和服务的节点是正常的。节点控制器7x24小时检查节点的状态。发现影响节点正常运行的问题后,将节点设置为NotReady或不可用。调度,通过kubelet将业务Pod驱逐出问题节点。这是Kubernetes的第一道防线。第二道防线是云厂商针对高频异常节点场景设计的节点自愈组件,比如阿里云的节点修复器:在发现问题节点后,进行引流和换机,从而自动到保证业务的正常运行。即便如此,节点在长期使用过程中难免会出现各种奇怪的问题,定位起来费时费力。常见问题的分类和级别:针对这些比较复杂的问题,总结如下排查流程图:以CPU为例:1.节点状态OK,CPU占用率超过90%。2、查看对应CPU的三元组:Utilizationrate,TopN,timingdiagram,首先每个核心的利用率都非常高,导致整体CPU占用率偏高;接下来,我们自然要知道到底是谁在疯狂使用CPU。从TopN榜单中,有一个Pod的CPU使用率脱颖而出;最后,我们必须确认CPU激增是从什么时候开始的。服务响应慢导致服务响应多。该场景可能的原因有代码设计问题、网络问题、资源竞争问题、依赖服务慢等。在复杂的Kubernetes环境中,定位慢调用有两种选择:第一,应用本身是否慢;第二,下游或网络是否慢;最后,检查资源使用情况。如下图,Kubernetes监控横向和纵向分析服务性能:横向:主要是端到端层面,先看你服务的黄金指标有没有问题,然后逐步往下游看网络指标。注意,如果从client来看调用下游时间比较长,但是从下游本身的goldenindex来看是正常的,那么很有可能是网络问题或者是操作系统层面的问题。这时候可以通过网络性能指标(流量、丢包、重传、RTT等)来判断。Longitudinal:判断应用本身的外部延迟高,接下来就是判断具体原因,判断哪个步骤/方法慢,可以用火焰图看。如果代码没有问题,那么可能是代码执行的环境有问题。这时可以查看系统的CPU/Memory等资源是否有问题,进一步排查。下面是一个慢SQL查询的例子(如下图所示)。在此示例中,网关调用产品服务。产品服务依赖MySQL服务。一步步查看链接上的黄金指标,最终发现该产品执行了一条特别复杂的SQL,并关联了多张表,导致MySQL服务响应缓慢。MySQL协议基于TCP。我们的eBPF探针识别到MySQL协议后,将MySQL协议的内容进行组装还原,可以收集到任何语言执行的SQL语句。第二个例子是应用程序本身运行缓慢的例子。这时候自然要问是哪个步骤,哪个函数导致的慢。ARMS应用监控支持的火焰图通过周期性采样CPU时间帮助快速定位代码(如下图)。水平问题。Application/Pod状态问题Pod负责管理容器,容器是真正执行业务逻辑的载体。同时,Pod是Kubernetes调度的最小单元,因此Pod同时具有业务和基础设施的复杂性,需要结合日志、链路、系统指标、下游服务指标来看待。Pod流量问题是生产环境中的高频问题,比如数据库流量突然变大。当环境中有数万个Pod时,要排查流量主要来自哪个Pod尤其困难。接下来看一个典型的案例:下游服务在发布过程中灰度了一个Pod,由于代码原因Pod响应很慢,导致上游超时。Pod级别的可观察性之所以成为可能,是因为我们使用ebpf技术来收集Pod流量和黄金指标,所以我们可以很方便地查看Pod与Pods、Pod与服务、Pod与外部流量。通过eBPF汇总多语言多网络协议的无创采集黄金指标/网络指标/Trace,关联Kubernetes对象、应用、云服务等各种上下文,在需要进一步钻取时提供专业的监控工具(如火焰图),在Kubernetes环境下实现一站式的可观察性平台。如果您在构建云原生监控的过程中遇到以下困扰,请毫不犹豫的联系我们一起探讨:您对Kubernetes不熟悉,需要一套完整的统一监控解决方案;Prometheus、Alertmanager、Grafana等系统数据碎片化,上手难;容器环境中的应用程序和基础设施嵌入成本太高,我们正在寻找低成本或非侵入式的解决方案;原文链接为阿里云原创内容,未经许可不得转载。
