目录
一、前言
二、OpenTelemetry 的出现
三、OpenTelemetry 架构
四、收集、转换、转发遥测数据的工具Collector
五、基于 OpenTelemetry && Kubernetes 的解决方案
六、基于 Kubernetes 的 OpenTelemetry 实现
6.1、通过 Helm 的方式进行部署
6.2、通过 kubectl 的方式进行部署
七、来点实战
7.1、集成OpenTelemetry SDK
7.2、部署OpenTelemetry Collector
八、数据处理与可视化
九、总结
随着云计算、微服务和容器化技术的快速发展,现代应用程序的架构变得越来越复杂。这种复杂性为运维人员和开发者带来了新的挑战,特别是在监控、追踪和诊断分布式系统的行为和性能方面。
传统的监控工具和框架往往专注于单一的领域,如日志记录、度量收集或分布式追踪。然而,这些工具之间的互操作性和数据标准化程度有限,导致在大规模、多语言的云原生环境中实施全面可观测性变得困难且成本高昂。
在此背景下,OpenTelemetry 应运而生。作为一项由行业领导者和开源社区共同推动的倡议,OpenTelemetry 旨在提供一个统一、标准化的框架,用于收集、处理和导出跨多种编程语言和平台的可观测性数据。
OpenTelemetry 的诞生是对现有问题的一种回应,它整合了先前两个重要的开源项目 OpenTracing 和 OpenCensus 的经验和最佳实践。这两个项目分别在分布式追踪和度量收集方面做出了重要贡献,但各自存在的碎片化和不兼容性问题限制了它们在复杂环境中的应用。
通过合并这两个项目并引入更广泛的社区支持,OpenTelemetry 致力于创建一个通用的、 vendor-neutral 的解决方案,使得开发人员和运维人员能够更容易地实现端到端的可观测性,无论他们的应用程序是基于何种语言、运行在何种环境之上。
OpenTelemetry(也称为 OTel)是一个开源可观测性框架,由工具、API 和 SDK 的集合组成。
要了解 OTel 的功能,了解可观测性会有所帮助。松散定义的可观测性是指根据系统生成的外部数据(通常是日志、指标和跟踪)的知识来了解系统内部发生的情况的能力。
拥有如何收集和发送可观测性数据的标准格式是 OpenTelemetry 发挥作用的地方。作为云原生计算基金会 (CNCF) 的孵化项目,OTel 旨在提供一套统一的与供应商无关的库和 API,主要用于收集数据并将其传输到某个地方。自项目启动以来,包括 Dynatrace 在内的许多供应商都加入了进来,帮助简化和更易用的丰富数据收集工作。
为了理解为什么可观测性和 OTel 的可观测性方法如此重要?那让我们先深入地了解遥测数据本身:
在 Tracing 实践中有一个原则,遥测数据收集过程需要与业务逻辑处理正交。意思就是遥测数据收集并传递到遥测后端服务的过程不占用业务逻辑的信道/线程,尽量较少监测客户端对原有业务逻辑的影响。Collector是基于这个原则实践的产物。
代码仓库:opentelemetry-collector
从架构层面来说,Collector 有两种模式。一种是把 Collector 部署在应用相同的主机内(如K8S的DaemonSet),或者部署在应用相同的 Pod 里面 (如K8S中的Sidecar),应用采集到的遥测数据,直接通过回环网络传递给 Collector。这种模式统称为 Agent模式。
另一种模式是把 Collector 当作一个独立的中间件,应用把采集到的遥测数据往这个中间件里面传递。这种模式称之为 Gateway 模式。
两种模式既可以单独使用,也可以组合使用,只需要数据出口的数据协议格式跟数据入口的数据协议格式保持一致。
OpenTelemetry 在 Collector 内部设计中,一套数据的流入、处理、流出的过程称为pipeline。
一个pipeline有三部分组件组合而成,它们分别是 receiver/processor/exporter。
receiver:负责按照对应的协议格式监听接收遥测数据,并把数据转给一个或者多个processor。
processor:负责做遥测数据加工处理,如丢弃数据,增加信息,转批处理等,并把数据传递给下一个processor或者传递给一个或多个exporter。
exporter:负责把数据往下一个接收端发送(一般是遥测后端),exporter可以定义同时从多个不同的processor中获取遥测数据。
Collector Pipeline 从上面的设计可以看出,Collector 除了提供让遥测数据收集与业务逻辑处理正交的能力,还充当了遥测数据对接遥测后端的适配器。Collector可以接收 Otlp、Zipkin、Jaeger等任意格式的数据,然后以 Otlp、Zipkin、Jaeger等任意格式的数据转发出去。这一切只取决于你需要输入或输出的格式是否有对应的 receiver 和 exporter 实现。Otlp 相关实现都是在 opentelemetry-collector 仓库中。而 Otlp 以外的协议实现,则是可以参考下面代码仓库。
在 Kubernetes 上部署一个 OpenTelemetry 收集器,这个收集器将负责接收和处理跟踪数据。一旦部署完成,我们可以使用 OpenTelemetry 提供的 OTEL 检测库(基于 Go 语言编写的应用程序)将跟踪数据发送到收集器。
一旦跟踪数据到达收集器,它将被传送到 Jaeger 收集器,进一步处理和存储。最后,我们可以使用 Jaeger 的用户界面(UI)来可视化这些跟踪数据,以便更好地理解应用程序的性能和行为。
下面的图示展示了这个流程,包括应用程序、OpenTelemetry 收集器和 Jaeger 之间的交互,以及跟踪数据的流动路径。具体可参考:
基础数据:
Kubernetes 1.24+
6 GB of free RAM for the application
Helm 3.9+ (for Helm installation method only)
添加 OpenTelemetry Helm 仓库:
$ helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
通过 Helm 安装 my-otel-demo :
$ helm install my-otel-demo open-telemetry/opentelemetry-demo
注意:需要 OpenTelemetry Demo Helm 图表版本 0.11.0 或更高版本才能执行下面提到的所有使用方法。
通过以下命令 部署 OpenTelemetry 应用,安装到 Kubernetes 集群。
$ kubectl create namespace otel-demo
$ kubectl apply --namespace otel-demo -f https://raw.githubusercontent.com/open-telemetry/opentelemetry-demo/main/kubernetes/opentelemetry-demo.yaml
选择编程语言并集成SDK
据你的应用程序所使用的编程语言(如Java、Python、Go、Node.js等),从 OpenTelemetry 官网下载对应的语言SDK,并按照官方文档进行集成。配置 Tracer实例,设置 Span 处理器,添加资源标签,确保每个请求或操作都生成相应的Spans,以便于追踪和分析
// Java示例:
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Scope;
public class MyService {
private static final Tracer TRACER = GlobalOpenTelemetry.get().getTracer("my-service");
public void handleRequest() {
try (Scope scope = TRACER.spanBuilder("handleRequest").startScopedSpan()) {
// 处理请求逻辑
} catch (Exception e) {
TRACER.getCurrentSpan().recordException(e);
throw e;
}
}
}
自动注入SDK到Pods
在 Kubernetes 中,可以利用Operator或者 Init Containers 自动为所有 Pod 注入 OpenTelemetry SDK,确保所有的应用程序都能透明地产生可观测性数据。
# DaemonSet 部署示例
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: otel-collector
spec:
selector:
matchLabels:
app: otel-collector
template:
metadata:
labels:
app: otel-collector
spec:
containers:
- name: otel-collector
image: otel/opentelemetry-collector-contrib:latest
args: [ "--config=/etc/otel-collector-config.yaml" ]
volumeMounts:
- mountPath: /etc/otel-collector-config.yaml
name: config-volume
subPath: otel-collector-config.yaml
volumes:
- name: config-volume
configMap:
name: otel-collector-config
配置OpenTelemetry Collector
创建 ConfigMap 存储 OpenTelemetry Collector 的配置文件,指定 Jaeger 作为后端导出器,并根据需要配置其他接收器和处理器。例如,配置 OTLP 协议接收数据,并将它们发送到 Jaeger。
yamlapiVersion: v1
kind: ConfigMap
metadata:
name: otel-collector-config
data:
otel-collector-config.yaml: |
receivers:
otlp:
protocols:
grpc:
http:
exporters:
jaeger:
endpoint: "jaeger-collector:14250"
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch] # 可选,使用批处理提高效率
exporters: [jaeger]
# 其他可选配置项,如metrics、logs等...
部署Jaeger 在 Kubernetes 集群中部署 Jaeger,包括 Jaeger Collector、Query 和 UI 组件,用于接收和存储 OpenTelemetry 发送过来的跟踪数据,并提供查询和分析界面。
查看和分析追踪数据 访问 Jaeger UI,利用其丰富的查询功能,对从应用程序收集到的跟踪数据进行深度分析。这些数据可用于优化服务性能、识别瓶颈、排查故障以及理解服务间的依赖关系。此外,还可以通过 Grafana 等可视化工具对接 Jaeger 数据源,创建自定义仪表板,以直观展示集群内服务的性能状态和拓扑结构。
总结而言,在 Kubernetes 环境中成功集成了 OpenTelemetry 后,不仅能够实现从应用程序到 Jaeger 后端系统的完整数据流转,而且提供了强大的可观测性和调试工具,显著提升了整个云原生环境的运维效率和稳定性。同时,通过灵活配置和扩展 OpenTelemetry 的功能,我们可以轻松应对不同规模和复杂度的业务场景需求。
OpenTelemetry 与 Kubernetes 结合,构建了一套强大的云原生环境下的可观测性解决方案。不仅简化了数据采集流程,提高了运维效率,还大大提升了对云原生应用的整体理解能力,助力企业实现敏捷开发、持续交付和高效的DevOps实践。