云原生可观测性理解
0 可观测性
复杂度以及数据处理量不断增长,为了了解系统的负载状态,我们需要系统有更好的可观测性。出现故障的时候必须要更快的找到问题根本原因并且解决,以满足更严格的服务水平要求。
越来越多的新应用基于云原生的方式而构建,提高了韧性、性能和安全性,但是同时失去了对于运行这些软件基础设施的控制的风险成本。作为系统owner必须要同时理解应用程序以及基础设施的运行状态。对于系统自身来说,其它均是外部实体,而系统在开发的时候就应该考虑给外部实体的可观测提供便利。这往往意味着编写更多的代码、自动化基础设施的操作并且监控关键的指标。
一旦系统的可观测能力能够达到一个令人满意的水平,这带来的益处是显而易见的。做到知其然,知其所以然,一切的信息都在掌控之中。这些观测能力的建设,依赖工作理念的改变、工具、目标、工作方法的变化。
对于可观测系统,其设计和开发中需要依赖遥感数据并且从这些数据中提取加工出有意义的信息。当前遥感数据主要包括:metrics,logs,traces,events,profiles和crash dumps,我们也把这些内容叫做观测信号。每种数据都有它自己的意义和最佳处理方式,如果处理不当就会产生各种新的问题,比如监控的频繁误报、故障扩容等。
控制论中的Controllability和Observability表示的是可控性,控制量对状态变量的控制能力,可观测性,输出量对状态变量的反应能力。可观测性是衡量一个系统仅凭其外部输出来判断其内部运行状态的精确度的指标,给外部实体往往是人,用来观察理解系统状态并且做出反应的功能。
可观测性是可以用在系统生命周期内的所有阶段,测试新功能、监测环境的韧性,了解你的用户,以及后续产品的路线图。对于观测信号都有不同的收集和测量方法,花费不同的资源来获取、存储和分析,同时提供不同的方法来观测相同的系统,以提供不同的视角来观察同一个技术,它们之间是互补的。
Metrics以实时、可靠、廉价的监控为中心,是支持快速、可靠告警的基础。Logs是为了更加深入了解系统运行细节,以便获取更多上下文的内容。更多时候的细节来自于请求书,也就是distributed tracing,支持了跨进程的context传播效应和串联效应。同时,也可能通过profiles来检查哪些代码效率低下并且使用了超出预期的资源。
Metrics
metrics是数据的数值表现,主要分为已经是数值的数据和被转化为数值的数据。前者比较典型的就是温度、高度等。后者转化为数值的数据,在转化的时候旧丢失了细节,比如计数,其统计的是某个周期的,对于特定的增量发生时间是丢失的。领域专家需要明确选择提取什么,如何提取,这对于数据的如何保留、转化、传输、存储和处理数据的负担大大减少,人们可以借由该metrics指标了解当前的状况。
metrics最常见的是构建概览和各项细节指标的图表集,每个指标都是一个逻辑计量单元,体现了一段时间之内相关指标的状态。
进而发出告警或自动化通知到人员或者其他自动化系统。另外也可用于长期的趋势分析和长期计划,同时也能够在时候提供解决和监控潜在问题的建议。
metrics更多的时候告诉我们“发生了什么”,衡量了关于系统的整体行为和健康状态。但是metrics往往不能告诉我们“为什么”,而是提供了相关问题定位的思路信息,并作为深入排查问题产生原因的出发点。
Logs
logs是在操作系统、应用程序中执行的过程、活动和操作的一系列文本类的对象流,是离散事件,具备结构化,人类可读的细节数据。
- 应用logs,可以帮助开发者理解和衡量应用程序在开发中及后续发布后的行为方式;
- 系统logs,可以记录操作系统本身的事件,可用于相关系统资源类的状态查看;
- 安全logs,是为了响应系统上发生的安全事件而创建的。对于系统中关键的内容均可以把其记录进入到安全logs中,往往系统管理员可以配置安全logs中包含哪些类型的事件;
- 审计logs,本质上是事件和变化的记录,代表着过程中的谁在什么事件进行了哪些动作,并且响应结果的记录。通常系统管理员会根据业务的需要而决定审计logs搜集什么。
- 基础设施logs,在本地或者云上,涉及管理影响组织IT基础的物理设备和逻辑设备,并且可以通过API、系统logs或者其他使用基于主机之上的代理收集的方式。比如往往很多主机上会安装有agent,做大量的数据搜集并且分析。
logs里的数据也可以转化成其他的可观测信号,包括metrics和traces,同时也可以使用logs分析技术来进行可视化和分析。logs级别是用来表示每条logs数据的重要性,一般常见的ERROR, WARNING, INFO和DEBUG。
ERROR往往报告的是故障的发生及其原因细节;WARNING是一个需要注意的消息,虽然可能这并不是一个故障;INFO适用于帮助理解系统是怎么运行的;DEBUG是用于每个操作非常详细信息的,其数据量较大,往往仅在故障排查时使用,避免影响存储空间和性能;
Trace
Traces通常是一组“tracing数据点”或者是一组可以用甘特来表示被称作为span。spans间是高度上下文相关的,并且包含 了初始化它的span信息。这使得分布式系统中不同的参与者(服务、队列、数据库)之间能够建立因果关系。各个参与者之间往往会定义一套标准的trace context进行信息的透传,W3C trace context定义了包含标准HTTP Header和值的格式来传播context信息,context信息唯一标识了分布式系统内的各个请求,还定义了通过添加和传播provider-specific的context信息。
组件埋点在分布式追踪系统中扮演中扮演重要的角色,负责创建数据点本身以及将context在服务间进行传递。没有context的传播,就无法将传入的HTTP请求与它下游HTTP请求或消息的生产者及消费者关联起来。
Profiles
随着云原生应用程序的不断优化,对于细粒度上理解性能指标也愈发重要,一些工具通常会帮我们发现存在的性能问题,而持续收集profiles使我们可以更深入理解某个特定系统遇到某个问题的原因,这些profiles聚焦在理解资源是如何在系统中被分配的,包括CPU Profilers,Heap Profilers,IO Profilers等。Profiling由于消耗太大,之前被认为是不适合在生产系统中添加。随着采样profiling技术的普及,在云环境中变得越来越普遍,而仅仅只是消耗很少的性能。
tracing是应用于理解应用程序的哪个部分导致延迟问题发生,profiling可以更加深入挖掘并理解那些导致延迟问题存在的原因,另外还可以知道哪些代码使用了最多的服务器资源。运行期生成的profiling数据通常包括精确到行号的统计,是回答从“是什么”到“为什么”的重要数据。
Dumps
软件开发中,当应用进程异常挂掉后会产生dump文件用于排除程序故障。通常,操作系统会根据一些配置,把进程崩溃时的内存镜像写入dump文件,以便后续分析。Linux内核2.6后,dump文件的收集工作不是操作系统完成,而是 崩溃的进程输出推送到负责写入文件的应用程序的标准输入流中,这个应用程序就是核心dump处理程序,在ubuntu下可以在systemd支持下完成。
云原生环境下,应用和基础设施的所有者角色不是那么明确,有特权的去访问系统全局配置的权限较低。另外一方面需要给崩溃的应用在pod重启之前就收集核心dump文件并写入持久卷时提供帮助。
往往系统中的一个事件会产生多个信号,产生metrics增量、出发logs日志记录和开启一个新的span追踪。这意味着与当前特定事件有关的元数据和context在整个系统中都是重复的。对于多信号,我们希望理想的结果是一个整体的互补的可观测系统,希望使用来自另外一个信号的额外信息来补充,而不仅仅是增加了整个系统的数据量和数据的处理难度。
1 构建可观测系统
前提条件是:一致的目标元数据被附加到所有的信号内。
不一致的元数据对于可观测系统是灾难的,即使label之间最微小的差别也会造成很大的麻烦。重新标记或默认是用pull模式会对这有所帮助。
建立可观测的目的是确保系统的高可用。对于高可用的衡量一般使用如下几个概念:
SLI 服务水平指标:服务水平精确的量化定义的指标;
SLO 服务水平目标:能够承受的系统故障频率目标,由SLI服务数据平指标的目标值或者目标区间组成;
SLA 服务水平协议:规定由SLO不达标造成的后果的商业协议。