随着应用系统的复杂度越来越高,越来越难保证所有的系统都一直处于稳健状态,有可能某些部分会因问题而处于降级状态。因此我们不仅必须将应用程序构建得更可靠和更具弹性,还必须通过可观测性工具在运行时能够理解实际发生的事情。如果我们能够了解应用服务和基础设施在运行时发生了什么,我们就可以学会检测故障并在观察到某些意外情况时进行深入调试。这将有助于降低平均恢复时间,快速恢复对业务的影响。
可观测性是指通过查看系统的外部特征来理解和推理系统的内部处于什么样的状态。它基于控制理论的研究,最初由 Rudolf E. Kálmán 在 1960 年的论文“关于控制系统的一般理论”中提出。从实际应用的角度来看,我们在系统中需要重视其稳定性,需要理解什么时候系统运行良好或出现问题,从而可以更快地识别错误,并实施正确的自动化及手动控制来维护系统的可用性。
阿里云服务网格 ASM 提供了统一标准化方式,为用户提供一种收敛后的可观测数据生成与采集配置模式,以更好地支持云原生应用的可观测性。
01 概述
可观测介绍
可观测性是一个包含各种级别的系统特征,必须结合应用程序的指标采集、网络的的指标采集、以及基础设施如数据库存储等来筛选存储大量的数据,以便在发生不可预测的情况时拼凑出一个完整的视图。Service Mesh 在可观测性方面可以有效提升应用程序级别的网络指标采集。
Service Mesh 的数据平面代理位于服务之间的网络请求路径中,通过捕获代理的可观测性数据可以在运行时了解应用程序网络和网格的运行情况。
在 Service Mesh 中实现可观测性,涉及了日志、监控指标以及链路追踪这些可观测性数据的生成规则配置和采集配置,以及如何将这些可观测数据采集到云托管服务或者自建服务中。同时,还需要考虑如何支持针对网格代理与网关 Pod 分别定义采集配置,以支持不同的场景诉求。阿里云服务网格 ASM 提供了统一标准化方式,为用户提供一种收敛后的可观测数据生成与采集配置模式,以更好地支持云原生应用的可观测性。
内置最佳实践
虽然 Telemetry CRD 允许在多个命名空间内可以创建多个对象,但如果随意定义造成冲突等,可能使得实际执行的结果与预期不符合。我们在产品中总结并落实了如下几个最佳实践:
- 在根配置命名空间 istio-system 中定义多个网格范围的 Telemetry 资源对象是无效的,也就是说只能在存在一个 Telemetry 资源对象。阿里云服务网格 ASM 中已经内置了该最佳实践,在 istio-system 命名空间内只允许存在一个名称为 default 的 Telemetry 资源对象。
- 所有的命名空间下约束为只存在一个 Telemetry 资源对象允许工作负载的选择器 selector 为空,且名称为 default。
- 可以通过使用工作负载选择器 selector 在所需命名空间中应用新的 Telemetry 资源对象来实现特定于工作负载的覆盖。
- 如果存在具有相同的工作负载选择器 selector 的两个 Telemetry 资源对象,也就是说这两个 Telemetry 资源对象选择了相同的工作负载,那么在这种情况下,产生行为是不确定的, 即不确定是这两个 Telemetry 资源对象中的哪一个会被执行。
- 当根配置命名空间 istio-system 下的全局 Telemetry 资源对象中,未定位监控指标部分,默认对应的是不启用生成指标。
- 为了避免这些指标产生的存储成本较大,在阿里云服务网格 ASM 中第一次开启时的指标设置中全局范围内只开启 SERVER 侧指标,未开启 CLIENT 侧指标。请根据需要,自行进行开启,例如需要针对网关进行监控,则需要进行开启 CLIENT 侧指标。需要注意的是,如果已经开启过,重新开启之后的指标设置将保留使用上一次的设置规则。
02 日志
在 Service Mesh 中,日志的采集是实现可观测性的重要手段之一。通过将所有服务的日志聚合到一处,可以便于统一管理和检索。为了实现这个目标,需要将每个服务的日志打印到 stdout 或 stderr,并使用日志代理将它们收集到中心日志系统中。阿里云服务网格 ASM 提供了日志过滤和日志格式化功能,可以根据需要对日志进行过滤和格式化,以便更好地进行检索和分析。
日志格式规则配置
在实际应用中,需要考虑到不同服务的日志格式可能不同,因此需要设置生成规则来控制日志的生成方式。部署在数据平面(即加入网格的 Kubernetes 集群)的 Envoy Proxy 可以输出所有访问日志。ASM 支持自定义 Envoy Proxy 输出的访问日志内容。
基于 Telemetry CRD,阿里云服务网格 ASM 提供了如下图所示的图形化界面,简化用户定义日志数据格式的配置。
对应地,生成的定义内容如下:
envoyFileAccessLog: logFormat: text: '{"bytes_received":"%BYTES_RECEIVED%","bytes_sent":"%BYTES_SENT%","downstream_local_address":"%DOWNSTREAM_LOCAL_ADDRESS%","downstream_remote_address":"%DOWNSTREAM_REMOTE_ADDRESS%","duration":"%DURATION%","istio_policy_status":"%DYNAMIC_METADATA(istio.mixer:status)%","method":"%REQ(:METHOD)%","path":"%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%","protocol":"%PROTOCOL%","request_id":"%REQ(X-REQUEST-ID)%","requested_server_name":"%REQUESTED_SERVER_NAME%","response_code":"%RESPONSE_CODE%","response_flags":"%RESPONSE_FLAGS%","route_name":"%ROUTE_NAME%","start_time":"%START_TIME%","trace_id":"%REQ(X-B3-TRACEID)%","upstream_cluster":"%UPSTREAM_CLUSTER%","upstream_host":"%UPSTREAM_HOST%","upstream_local_address":"%UPSTREAM_LOCAL_ADDRESS%","upstream_service_time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","upstream_transport_failure_reason":"%UPSTREAM_TRANSPORT_FAILURE_REASON%","user_agent":"%REQ(USER-AGENT)%","x_forwarded_for":"%REQ(X-FORWARDED-FOR)%","authority_for":"%REQ(:AUTHORITY)%","upstream_response_time":"%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%","xff":"%REQ(X-FORWARDED-FOR)%","app_service_name":"%UPSTREAM_CLUSTER%"}' path: /dev/stdout
以及描述了过滤条件的配置内容:
accessLogging: - disabled: false filter: expression: response.code >= 400 providers: - name: envoy
具体使用方式可以参考:https://help.aliyun.com/document_detail/322801.html
数据面日志采集设置
此外,需要设置采集规则来控制日志的采集方式和储存有效期。
容器服务 ACK 集成了日志服务功能,可对服务网格数据平面集群的 AccessLog 进行采集。具体可以参考:https://help.aliyun.com/document_detail/162798.html
采集控制平面日志及设置告警
ASM 支持采集控制平面日志和日志告警,例如采集 ASM 控制平面向数据平面 Sidecar 推送配置的相关日志。ASM 控制面组件的主要功能之一是推送网格的规则配置到数据面的 Sidecar 代理或者网关中。如果用户配置的网格规则内容存在一些冲突导致推送失败,代理或者网关就接收不到最新的配置内容。虽然代理或网关在不重启的情况下,可以使用已经接收到的配置继续运行,但是一旦这些 Pod 重启,很有可能导致 Sidecar 代理或网关启动失败。在很多实际场景中,经常出现用户误配置引发的网关或代理不可用的问题,因此启用控制面的日志告警,及时发现并解决问题十分必要。
具体使用可以参考:https://help.aliyun.com/document_detail/341858.html
03 监控指标
监控指标是 Service Mesh 中的另一个重要可观测性维度,用于描述请求的处理情况、服务之间的通信状况等等。Istio 采用 Prometheus 进行监控指标的采集和存储,每个服务的代理(Envoy)会生成大量的监控指标。这些指标可以用于实时监控服务的运行情况和性能指标,还可以用于异常检测和自动伸缩等场景。
指标数据生成规则配置
启用服务网格数据平面监控指标可以使服务网格数据平面(网关以及 Sidecar 代理)生成与其运行状态相关的指标数据,您可以通过将指标采集到阿里云 ARMS Prometheus 来直接查看监控报表(采集指标可能产生费用),或是自建 Prometheus 并从 ASM 数据平面抓取监控指标。
基于 Telemetry CRD,阿里云服务网格 ASM 提供了如下图所示的图形化界面,简化用户自定义指标配置。
对应地,生成的定义内容如下:
metrics: - overrides: - disabled: true match: metric: ALL_METRICS mode: CLIENT - disabled: false match: metric: ALL_METRICS mode: SERVER tagOverrides: {} - disabled: true match: metric: REQUEST_COUNT mode: CLIENT - disabled: false match: metric: REQUEST_COUNT mode: SERVER tagOverrides: {} - disabled: true match: metric: REQUEST_DURATION mode: CLIENT - disabled: false match: metric: REQUEST_DURATION mode: SERVER tagOverrides: {} - disabled: true match: metric: REQUEST_SIZE mode: CLIENT - disabled: false match: metric: REQUEST_SIZE mode: SERVER tagOverrides: {} - disabled: true match: metric: RESPONSE_SIZE mode: CLIENT - disabled: false match: metric: RESPONSE_SIZE mode: SERVER tagOverrides: {} - disabled: true match: metric: GRPC_REQUEST_MESSAGES mode: CLIENT - disabled: false match: metric: GRPC_REQUEST_MESSAGES mode: SERVER tagOverrides: {} - disabled: true match: metric: GRPC_RESPONSE_MESSAGES mode: CLIENT - disabled: false match: metric: GRPC_RESPONSE_MESSAGES mode: SERVER tagOverrides: {} - disabled: true match: metric: TCP_SENT_BYTES mode: CLIENT - disabled: false match: metric: TCP_SENT_BYTES mode: SERVER tagOverrides: {} - disabled: true match: metric: TCP_RECEIVED_BYTES mode: CLIENT - disabled: false match: metric: TCP_RECEIVED_BYTES mode: SERVER tagOverrides: {} - disabled: true match: metric: TCP_OPENED_CONNECTIONS mode: CLIENT - disabled: false match: metric: TCP_OPENED_CONNECTIONS mode: SERVER tagOverrides: {} - disabled: true match: metric: TCP_CLOSED_CONNECTIONS mode: CLIENT - disabled: false match: metric: TCP_CLOSED_CONNECTIONS mode: SERVER tagOverrides: {} providers: - name: prometheus
注意的是,第一次开启时的指标设置:
为了避免这些指标产生费用较大,第一次开启时的指标设置中全局范围内只开启 SERVER 侧指标,未开启 CLIENT 侧指标。请根据需要,自行进行开启,例如需要针对网关进行监控,则需要进行开启 CLIENT 侧指标。需要注意的是,如果已经开启过,重新开启之后的指标设置将保留使用上一次的设置规则。
ASM 网格拓扑功能相关的指标设置:
ASM 网格拓扑功能依赖于 Sidecar 上报的监控指标,若您开启了网格拓扑,关闭部分监控指标会对网格拓扑功能造成影响甚至不可用。
- 如果不启用 REQUEST_COUNT 的 SERVER 侧指标,将无法生成 HTTP/gRPC 服务的拓扑图。
- 如果不启用 TCP_SENT_BYTES 的 SERVER 侧指标,将无法生成 TCP 服务的拓扑图。
- 关闭 REQUEST_SIZE 和 REQUEST_DURATION 的 SERVER 侧,REQUEST_SIZE 的 CLIENT 侧指标会导致部分拓扑图节点的监控信息无法展示。
具体可以参考:https://help.aliyun.com/document_detail/389053.html
指标采集配置
开启 Prometheus 的统计数据收集功能,将采集到的监控指标发送到 Prometheus 中,以便进行存储和分析。服务网格 ASM 集成了 ARMS Prometheus 功能,可以实现对服务网格的监控。具体可以参考:https://help.aliyun.com/document_detail/169961.html
Prometheus 采集间隔会对指标收集开销产生重大影响,间隔越长,抓取的数据点就越少,从而减少处理、存储和计算开销。当前的默认配置为 15s,对于生产场景来说可能过于频繁。请根据实际需要在 Prometheus 侧进行调整。
如果使用的是 ARMS Prometheus,请到 ARMS 控制台中的设置页中进行配置,查看文档说明:https://help.aliyun.com/document_detail/196107.html
直方图关联的指标(包括 istio_request_duration_milliseconds_bucket、istio_request_bytes_bucket、istio_response_bytes_bucket)通常比较密集,开销较大,为了避免这些自定义指标继续产生费用,您可以废弃这些自定义指标。如果使用的是 ARMS Prometheus,请到 ARMS 控制台中的指标页中进行配置,查看文档:https://help.aliyun.com/document_detail/340657.html
同时,也支持在 ASM 集成自建 Prometheus 实现网格监控。具体可以参考:https://help.aliyun.com/document_detail/184885.html
通过 Grafana 可以查看对应的仪表盘,类似如下:
合并 Istio 与应用的监控指标
已有 Prometheus 监控端点的应用服务,通过启用合并 Istio 与应用的监控指标功能,可以借助网格代理输出原有业务指标。启用合并 Istio 与应用的监控指标功能后,服务网格会将应用程序指标合并到 Istio 指标中,相对应的 prometheus.io 注解会被加入到所有数据面 Pod 上,以启用 Prometheus 的指标抓取能力。如果这些注解已经存在,就会被覆盖。网格代理将应用指标和 Istio 指标进行合并,Prometheus 可以从 :15020/stats/prometheus 端点拉取合并后的指标。具体参考:https://help.aliyun.com/document_detail/2392287.html
网格拓扑展示
网格拓扑是一个服务网格可观测性工具,提供查看相关服务与配置的可视化界面。ASM 支持内置网格拓扑,类似如下。具体可以参考:https://help.aliyun.com/document_detail/200336.html
服务等级目标 SLO
服务等级指标 SLI(Service Level Indicator)是衡量服务健康状况的指标。SLO 是指服务等级的目标值或范围值,由一个或多个服务等级指标 SLI 组成。
SLO 提供了一种形式化的方式来描述、衡量和监控微服务应用程序的性能、质量和可靠性。SLO 为应用开发和平台团队、运维团队提供了一个共享的质量基准,可作为衡量服务水平质量以及持续改进的参考。使用 SLI 组合定义的 SLO 能够帮助团队以更精确的方式描述服务健康状况。
SLO 示例如下:
- 每分钟平均 QPS > 100k/s
- 99% 访问延迟 < 500ms
- 99% 每分钟带宽 > 200 MB/s
阿里云服务网格 ASM 提供了开箱即用的基于服务等级目标 SLO(Service Level Objectives)的监控和告警能力,能够监控应用服务之间调用的延迟和错误率特征等。
ASM 支持的 SLI 类型如下:
- 服务可用性:服务成功响应的时间比例,对应的 SLI 插件类型为 availability。HTTP 响应码为 429 或以 5XX(以 5 开头的状态码)会被判断为不可用。
- 延迟时间:服务返回请求的响应所需的时间(单位为毫秒),对应的 SLI 插件类型为 lantency。您可自定义延迟上限,高于上限的响应会被判断为不合格。
阿里云服务网格 ASM 提供了定义 SLO 配置的 UI 界面,如下所示:
使用 ASM 定义应用服务级 SLO,可以自动生成 Prometheus 规则。将生成的规则导入 Prometheus 中之后可以执行 SLO。在 Prometheus 框架中,由 AlertManager 组件负责收集 Prometheus Server 产生的告警信息,并根据您的配置发送给各个接收者。当触发告警时,在 Alertmanager 页面,如下图所示,可以看到自定义告警信息采集成功。
具体可以参考:https://help.aliyun.com/document_detail/468826.html
04 分布式追踪
分布式追踪是 Service Mesh 中实现可观测性的重要组成部分之一,是一种用于对应用程序进行概要分析和监视的方法,尤其是针对使用微服务架构构建的应用程序。在微服务架构中,服务之间的通信是通过网络进行的,因此需要采用分布式追踪技术来对服务之间的调用关系进行跟踪和监控。在 Istio 中,可以使用 Jaeger、Zipkin 等分布式追踪工具来实现这个功能。在分布式追踪里,存在 Trace 和 Span 两个重要概念:
- Span:分布式追踪的基本组成单元,表示一个分布式系统中的单独的工作单元,每一个 Span 可以包含其它 Span 的引用。多个 Span 在一起构成了 Trace。
- Trace:微服务中记录的完整的请求执行过程,一个完整的 Trace 由一个或多个 Span 组成。
虽然 Istio 代理能够自动发送 Span 信息,但是应用程序仍然需要传播适当的 HTTP 标头,以便在代理发送 Span 时,可以将 Span 正确地关联到单个跟踪中。为此,应用程序需要收集以下标头并将其从传入请求传播到任何传出请求:
- x-request-id
- x-b3-traceid
- x-b3-spanid
- x-b3-parentspanid
- x-b3-sampled
- x-b3-flags
- x-ot-span-context
追踪数据生成规则配置
基于 Telemetry CRD,阿里云服务网格 ASM 提供了如下图所示的图形化界面,简化用户定义分布式链路追踪数据的生成规则配置。
对应地, 生成的定义内容如下:
tracing: - customTags: mytag1: literal: value: fixedvalue mytag2: header: defaultValue: value1 name: myheader1 mytag3: environment: defaultValue: value1 name: myenv1 providers: - name: zipkin randomSamplingPercentage: 90
追踪采集配置
需要将采集到的数据发送到云托管服务或者自建服务中。在云托管服务中,可以使用云原生应用管理服务来实现数据的收集和分析。具体可以参考:https://help.aliyun.com/document_detail/149551.html
在自建服务中,可以使用开源的数据收集和分析工具(如 Zipkin、Jaeger 等)来实现数据的收集和分析。具体可以参考:https://help.aliyun.com/document_detail/176527.html
05 总结
在 Service Mesh 中,不同的服务可能需要采集不同的可观测性数据,因此需要支持针对网格代理与网关 Pod 分别定义采集配置规则,并统一标准化采集配置规则,以便更好地支持云原生应用的可观测性。
总的来说,可观测性在云原生应用中扮演着非常重要的角色,它可以帮助我们实时监控服务的运行情况和性能指标,发现并解决服务故障和瓶颈,从而提高应用的可靠性和性能。因此,借助于 Service Mesh 的无侵入式可观测性的实现,基于标准的统一化的可观测数据生成与采集配置,一定可以更好地支持云原生应用的发展。