OpenTelemetry 在服务网格架构下的最佳实践
【百度云原生导读】OpenTelemetry 由著名的 OpenTracing、 OpenCensus 两个产品在 2019 年合并而来,拥有广泛的应用场景和强大的开发团队。2021年,OpenTelemetry 的使用成为新的行业规范,通过在各个数据源之间建立一致性,使得数据收集以及处理更加便捷。那么,如何在服务网格架构中引入 OpenTelemetry 进而获取可观测 trace 能力,实践过程中会遇到哪些问题?本文对相关问题做了总结并给出了解法,最后通过一个 Demo 手把手教你在 Istio 中安装 OpenTelemetry。
1. OpenTelemetry 介绍
OpenTelemetry(简称 OTel)是一系列的工具、APIs 和 SDKs。使用 OpenTelemetry 可以产生、收集、输出一系列遥测数据(telemetry data 如 trace、metrics 和 log)帮助用户分析应用程序的性能和行为。
OpenTelemetry 是厂商无关的,并且作为工业级别标准被大量的厂商支持。另外,OpenCensus(Google)和 OpenTracing(Uber)是其前身。
其架构如下所示:
主要包含了以下几个部分:
-
Instrumentation:包含自动方式API 、SDK 方式接入 OpenTelemetry。
-
OTLP: OpenTelemetry 定义的传输协议。
-
OpenTelemetry Collector:提供厂商无关的解决方案,用于实现 数据的接收(receive), 处理(process)和 输出(export)的功能。
2. OpenTelemetry 在 Service Mesh 架构下的实践
目前 Istio 实现可观测 trace 方案 可以总结为:
-
需要业务透传对应的 header 信息(从入向请求中获取对应的 header 信息、并在出向请求中添加响应 header 信息)。
-
Sidecar 自动向监控系统发送Span信息。
通过对 Istio 方案可观测 trace 的分析,可以发现几个问题:
-
对业务代码是有侵入的 Trace 上下文传播(Trace Context propagation),需要业务透传相应的 header 信息。
-
所有的 Span 数据都由 Sidecar 侧生成,业务内部方法级别监控信息无法采集。
在业界 APM 的技术方案中,JavaAgent(一种字节码技术,对业务无侵入)作为主流的技术方案。同样 OpenTelemetry auto-instrumentation 通过 Java Agent 提供的动态注入字节码的技术实现任意 Java 应用遥测数据的采集,其支持了非常多的广为流行的库和框架。
2.1 无侵入式Trace上下文传播
对于Java应用程序,OpenTelemetry JavaAgent支持的 Trace context propagation 如下:
-
"tracecontext"
: W3C Trace Context (addbaggage
as well to include W3C baggage) -
"baggage"
: W3C Baggage -
"b3"
: B3 Single -
"b3multi"
: B3 Multi -
"jaeger"
: Jaeger (includes Jaeger baggage) -
"xray"
: AWS X-Ray -
"ottrace"
: OT Trace
上述 b3multi/b3(以x-b3开头)
恰好是 Istio 中要求透传的 header 信息。
2.2 业务内部方法级别监控
目前 OpenTelemetry JavaAgent 已经支持大量的库、框架以及应用服务器,能够采集业务内部方法级别执行逻辑。
2.3 trace信息与业务日志关联
通常在业务排查问题中,不仅仅要查看对应的 trace 链路信息,同时也要基于对应的 trace_id、span_id 查看对应的业务日志信息。
OpenTelemetry Java Agent 已经预置了很多关于当前 span 的信息在 log 的 MDC(Mapped Diagnostic Context)中,业务可以方便配置这些信息,业务可以方便在业务日志中打印对应的 trace_id、span_id 信息。如下为SpringBoot 中使用 logback 的配置示例:
logging.pattern.level = trace_id=%mdc{trace_id} span_id=%mdc{span_id} trace_flags=%mdc{trace_flags} %5p
2.4 系统架构
-
JavaAgent 将采集的数据发送至 OpenTelemetry Collector 。
-
Sidecar 将生成的 trace span 信息发送至 OpenTelemetry Collector。
-
OpenTelemetry Collector 将数据输出至监控系统如 jaeger 或 Kafka 中。
-
用户可以通过对应的 UI 查看 trace 数据。
2.5 实践
本文主要用于演示,均无高可用部署。
2.5.1 安装istio
下载 istio 安装包(本文以1.13.2 为例):http://github.com/istio/istio/releases
$ istioctl install -f istio-opentelemtry-iop.yaml
istio-opentelemetry-iop.yaml的内容如下所示:
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
meshConfig:
defaultConfig:
holdApplicationUntilProxyStarts: true
tracing:
sampling: 100
enablePrometheusMerge: false
# 定义扩展的providers
extensionProviders:
- name: otel-trace
zipkin:
service: otel-collector.istio-system.svc.cluster.local
port: 9411
maxTagLength: 56
components:
ingressGateways:
- name: istio-ingressgateway
enabled: true
特别说明:上述extensionProviders 属性中定义了otel-trace,其信息为opentelemetry Collector 的地址(其本身可以接收 zipkin 格式的trace,因此此处定义的是zipkin的信息)
2.5.2 安装OpenTelemetry Collector
按照http://github.com/open-telemetry/opentelemetry-operator 安装 OpenTelemetry Collector。假设安装的 K8S Service 为:otel-collector.istio-system.svc.cluster.local:9411,9411为接收 zipkin 数据格式的端口。
opentelemetry-collector-config.yaml的内容如下所示:
# collector的receivers配置
receivers:
otlp:
protocols:
grpc:
http:
zipkin:
processors:
batch:
memory_limiter:
# collector的exporters配置,
exporters:
zipkin:
endpoint: "http://zipkin.istio-system.svc.cluster.local:9411/api/v2/spans"
service:
pipelines:
traces:
# 对于trace数据,开启otlp、zipkin协议端口提供服务
receivers: [otlp, zipkin]
processors: [memory_limiter, batch]
# 对于trace数据,最后输出至zipkin中
exporters: [zipkin]
2.5.3 安装 jaeger
kubectl apply -f http://raw.githubusercontent.com/istio/istio/release-1.14/samples/addons/jaeger.yaml
由于 collector exporters 输出的 trace 数据格式为 zipkin,jaege 兼容 zipkin 格式 trace 数据,因此最终 trace 数据可通过 jaeger 展示。
2.5.4 提交Telemetry CRD
提交 Telemetry CRD,将 envoy 对接的 trace 的信息变更为 otel-trace,即为 Opentelemetry Collector。
$ kubectl apply -f mesh-trace-telemetry.yaml
mesh-trace-telemetry.yaml的内容如下所示:
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
name: mesh-trace-telemtry
namespace: istio-system
spec:
tracing:
- providers:
- name: otel-trace
randomSamplingPercentage: 100
2.5.5 部署Mesh应用
为对应的命名空间 default 开启自动 Sidecar 注入功能:
$ kubectl label namespace default istio-injection=enabled --overwrite
按照K8S的方式部署微服务应用 consumer-demo 和 provider-demo。应用程序说明:
-
consumer-demo:服务消费方,向外提供 HTTP 接口,该接口会调用服务提供方 provider-demo 提供的 HTTP 接口,调用 provider-dem 的调用形式包括 RestTemplate 和 Fegin。
-
provider-demo:服务提供方,提供 HTTP 接口。
应用程序启动需要加上对应的参数,如下所示:
# 启动时要指定javaagent
# -Dotel.resource.attributes=service.name=provider-demo 在span中的service信息
# -Dotel.propagators=b3multi 透传b3multi header
java -javaagent:/opentelemetry-javaagent.jar -Dotel.resource.attributes=service.name=provider-demo -Dotel.propagators=b3multi -jar provider-demo-1.0-SNAPSHOT.jar
部署时需要在容器的环境中添加对应的配置:
env:
- name: OTEL_TRACES_EXPORTER # javaagent输出otlp协议类型数据
value: otlp
- name: OTEL_EXPORTER_OTLP_ENDPOINT # collector地址
value: http://otel-collector.istio-system.svc.cluster.local:4317
- name: OTEL_JAVAAGENT_ENABLED # 开启javaagent功能
value: 'true'
2.5.6 观察Mesh监控数据
如下图为本文consumer-demo和provider-demo在业务访问中产生的监控数据(以监控系统Jaeger为例):
3.总结
通过在 Service Mesh 架构中引入 OpenTelemetry,可以总结带来的业务收益如下:
-
通过 OpenTelemtry auto-instrumentation 机制可实现无侵入式 Trace 上下文传播,使得业务无感接入 Service Mesh 可观测性。
-
通过 OpenTelemtry auto-instrumentation 机制可实现业务内部方法级别的监控数据采集,弥补 Service Mesh 只能在 Sidecar 侧采集监控数据的缺陷。
-
通过 OpenTelemetry Logger MDC auto-instrumentation 机制能够将监控信息对应的 trace_id、span_id 等信息配置输出在业务日志中,方便业务排查问题。
为服务更多客户,百度智能云现已推出服务网格产品CSM(Cloud Service Mesh),为用户提供高可靠、免运维、开放的云原生微服务治理产品,火热公测中,欢迎对服务网格感兴趣的开发者与我们一起探讨实践。
更多产品介绍与使用请点击阅读原文或直接访问以下链接:
http://cloud.baidu.com/product/csm.html
---------- END ----------
重磅!云原生计算交流群成立
扫码添加小助手即可申请加入,一定要备注:名字 - 公司 / 学校 - 地区,根据格式备注,才能通过且邀请进群。
了解更多微服务、云原生技术的相关信息,请关注我们的微信公众号【百度云原生】!
- 如何治理资源浪费?百度云原生成本优化最佳实践
- OpenTelemetry 在服务网格架构下的最佳实践
- 百度可观测系列 | 如何构建亿级指标的高可用 TSDB 存储集群?
- 百度可观测系列 | 采集亿级别指标,Prometheus 集群方案这样设计
- AI 原生云:是“现在式”也是“未来时”
- 服务网格在联通的落地实践
- 深入理解百度在离线混部技术
- 百度可观测系列 | 基于 Prometheus 的大规模线上业务监控实践
- 殊途同归,Proxyless Service Mesh在百度的实践与思考
- 实践 | 百信银行基础设施容器化改造之路
- 云原生计算动态周报9.6-9.12
- 云原生计算动态周报9.6-9.12
- 百度混部实践系列 | 如何提高 K8S 集群资源利用率?
- 云原生计算动态周报8.30-9.5
- 云原生计算动态周报8.30-9.5
- 服务网格在百度核心业务大规模落地实践
- 云原生计算动态周报8.23-8.29
- 云原生计算动态周报8.23-8.29
- 如何用3分钟搭建一个属于自己的网站?
- 云原生计算动态周报8.16-8.22