CNCF在云原生的定义[1]中,将可观测性(Observability)明确为一项必备要素。因此,使用云原生应用架构,享受其带来的效率提升时,不得不面对的是如何构建匹配的可观测性能力。发展到今日,可观测性在开源和商业上已经有了大量的解决方案拼图,CNCF Cloud Native Landscape[2]中相关内容更是多达上百个。本文总结了可观测性能力的成熟度模型,希望能为组织选择适合自身的可观测性方案提供指导。
1.0 | 支柱:基础的可观测性
时间回到2017年,Peter Bourgon一篇博文总结了可观测性的三大支柱:指标(Metrics)、追踪(Tracing)、日志(Logging)[3]。此后几年间这个观点受到了业内的广泛认可,发展为对可观测性能力的基本要求,并且每一个方面都有了众多成熟的解决方案。例如,开源组件中就有聚焦于Metrics的Prometheus、Telegraf、InfluxDB、Grafana等,聚焦于Tracing的Skywalking、Jaeger、OpenTracing等,聚焦于Logging的Logstash、Elasticsearch、Loki等。
构建三大支柱是可观测性能力建设的初级阶段,基于开源组件很容易为每个业务系统搭建一套开箱即用的可观测性设施。这个阶段面临的主要问题有两个:
1)数据孤岛:当团队面临一个业务故障时,可能需要频繁跳转于Metrics、Tracing、Logging系统之间,由于这些系统上的数据并没有很好的关联打通,整个问题排查流程高度依赖人工的信息衔接,有些时候可能还需要协调负责不同系统的不同人员参与问题排查。
2)建设冗余:由于观测数据的采集依赖StatsD插桩、Tracing SDK插桩、Logging SDK插桩,处于这个阶段的可观测性能力一般以业务开发团队为核心驱动构建,业务部门只会构建服务于自身的观测设施,导致在不同业务部门之间重复构建。另一方面,开箱即用的方案往往存在扩展性问题,难以成长为面向所有业务提供的基础服务。
2.0 | 服务:统一的可观测性
当观测数据的打通和观测系统的优化在日常运维工作中越来越频繁时,意味着我们需要准备提升可观测性能力到下一个等级了。这个等级的可观测性以服务为核心,由基础设施团队和业务开发团队协作。基础设施团队需要打造一个面向所有业务的统一可观测性平台,提供Metrics、Tracing、Logging数据的采集、存储、检索基础设施,并支持将不同类型的数据进行关联以消除孤岛。业务开发团队作为消费方,利用统一SDK在此平台上注入观测数据。
首先我们面临的问题是采集时如何关联不同类型的数据,OpenTelemetry[4]通过标准化数据的采集和传输期望解决此问题。遵循OpenTelemetry规范,我们可以看到Metrics可通过Exemplars关联至Trace,Trace通过TraceID、SpanID关联至Log,Log通过Instance Name、Service Name关联至Metrics。OpenTelemetry社区已经完成了Tracing规范的1.0版本,并计划在2021年完成Metrics规范、2022年完成Logging规范。这是一个高速发展中的项目,但得到了业界大量的关注和认可,也能看出可观测苦数据孤岛久矣!
其次,我们还面临着不同类型数据的存储问题,遗憾的是这方面OpenTelemetry并未涉及。Metrics和Trace/Log数据有着较大的区别,通常采用TSDB(如InfluxDB)存储Metrics数据,Search Engine(如Elasticsearch)存储Trace/Log数据。为了提供一项统一的可观测平台服务,系统需要具备水平扩展能力,但TSDB由于高基问题通常难以用于存储精细至每个微服务、API的指标数据,而Search Engine由于全文索引问题通常会带来高昂的资源开销。解决这两个问题一般考虑选择基于稀疏索引的实时数仓,例如ClickHouse等,并通过对象存储机制实现冷热数据分离。
除此之外,观测系统成为统一服务的更大挑战还在于,它需要比业务系统有更强的水平扩展能力。例如,在混合云、边缘云等复杂环境中,观测系统应该能扩展至多个Region/AZ以及边缘机房,使得可全链路监控复杂业务。
解决了数据的采集和存储问题后,基础设施团队可将观测系统作为一项统一服务向业务开发团队开放,但这个阶段的可观测性依然有两个问题未能解决:
1)团队耦合:观测能力作为一项服务(Service),必须由业务开发团队主动调用(Call),但业务保障的KPI由运维团队承担,并不直接落在开发团队上。在云原生架构应用的高速迭代背景下,是否每一次业务上线都能做到对观测服务的100%调用?即使开发团队能严守规则,整个事情的主动权也并没有落在运维团队手上。另外站在开发团队的视角,业务代码中不得不插入各式各样的由运维团队强制要求的SDK调用。
2)观测盲点:应用架构中涉及到的所有软件服务并不是每一行代码都由开发团队编写,因此侵入式的代码打桩手段势必会遇到观测盲点。例如两个微服务通信路径上的API网关、iptables/ipvs、宿主机vSwitch、SLB、Redis缓存服务、MQ消息队列服务等,都无法通过插码的方式植入式获取观测收据。
3.0 | 原力:内生的可观测性
当开发与运维的团队的耦合问题开始制约组织发展,当基础服务的观测盲点问题开始制约业务SLO进一步提升时,意味着我们需要再一次提升可观测性能力等级了。
既然每一个云原生应用都需要可观测性能力,那么我们能否让基础设施内生地提供这样的能力,它就像原力(The Force)一样,无处不在。因此,方向明朗了:如果业务代码中不插入任何一行观测代码,我们能获得多少可观测能力?这个阶段的主要挑战来自于数据的采集和存储。
如何实现基础设施内生的应用观测数据采集能力?一种Green Field的思路是通过服务网格实现。我们可以看到,无论是纯正的服务网格如Istio,还是更激进的应用运行时如Dapr,都从设计之初就考虑了可观测性能力。假如微服务之间的访问路径都经过服务网格,那么可以从基础设施层面解决观测数据的采集问题。这里的主要挑战来自于对应用架构的改变——应用需全部迁移到服务网格架构。但即使依靠服务网格,也依然会存在中间件、数据库、缓存、消息队列等系统上的观测盲点。或许等到服务网格像TCP一样——变成网络协议栈的一层时[5],我们能通过这种方法实现内生的可观测性。
另一种Brown Field的解决思路是借助BPF零侵入、无处不在的观测能力。BPF是一项内生于Linux Kernel中的观测技术,经典BPF(cBPF)主要聚焦于网络流量的过滤获取,但在Kernel 4.X版本中已经得到了巨大的增强(eBPF)。利用eBPF,无需修改业务代码、无需重启业务进程,可端到端地观测每一个TCP/UDP(kprobe)、HTTP2/HTTPS(uprobe)函数调用;利用cBPF,从网络流量中提取每一次服务访问的Metrics、Tracing、Logging观测数据,可全链路地观测服务间通信在流经虚拟机网卡、宿主机网卡、SLB等中间设备时的性能数据。随着Linux Kernel 4.X越来越广泛的应用,我们看到云监控泰斗Datadog最近刚刚发布了基于eBPF的Universal Service Monitoring(USM)零侵入监控能力[6],国内阿里云ARMS团队也在最近发布了基于eBPF的零侵入监控产品Kubernetes监控[7],开源社区方面Skywalking v9也开始关注eBPF[8]。但请注意仅仅依靠eBPF会存在依赖4.X Linux内核的问题,导致有可能退化为一种Green Field方案。原力需要无处不在,网络流量早已无处不在!
数据存储的挑战实际上和全链路监控相关。从应用代码出发的可观测性往往仅考虑业务和应用层面的问题,网络、基础设施成为盲点。在中间路径上(API网关、iptables/ipvs、宿主机vSwitch、SLB、Redis缓存服务、MQ消息队列服务)采集到的观测数据如何能与应用和业务层面的观测数据打通,需要我们构建一个面向微服务的知识图谱。通过与云平台API、K8s apiserver以及服务注册中心同步资源和服务信息,为每个微服务构建区域/可用区、VPC/子网、云服务器/宿主机、容器集群/节点/工作负载、服务名/方法名等多维度知识图谱信息,作为数据标签附加于观测数据之上,从而打通全链路上各个层面的Metrics、Tracing、Logging数据。
当你到达第3级时,可观测性已经成为了云基础设施上内生的能力,像原力一样,它蕴含在已运行的每个应用系统、以及未来会新增的每个应用系统中,是一项与生俱来的基本能力,这项能力无需依赖于在业务代码中的“调用”来触发,它就在那里。
DeepFlow在可观测性3.0等你。May the force be with you!