Grafana Tempo笔记03: 使用OpenTelemetry Collector将跟踪数据发送Tempo
2023-06-06
可以使用Grafana Agent将分布式追踪数据发送到Tempo,但这不是必需的。实际上,Tempo服务是一个暴露符合Open Telemetry TraceService标准的gRPC端点,通过HTTP Basic授权进行访问。任何能够使用正确的HTTP请求头调用该端点的工具都可以发送跟踪数据。
本文将展学习如何使用OpenTelemetry Collector完成这个过程。
安装OpenTelemetry Operator #
OpenTelemetry Operator是一个用于部署和管理OpenTelemetry组件的Kubernetes Operator。它是一个自定义的Kubernetes控制器,使用Operator模式自动化了OpenTelemetry环境的部署、配置和管理过程。
OpenTelemetry Operator简化了在Kubernetes环境中部署和管理OpenTelemetry Collector、OpenTelemetry Agent等组件的流程。它可以通过自定义资源定义(Custom Resource Definitions,CRDs)和声明式配置,对OpenTelemetry组件进行集中化的管理。使用OpenTelemetry Operator,可以轻松地在Kubernetes集群中创建、配置和管理OpenTelemetry组件的实例。它提供了许多有用的功能,例如自动创建和管理配置文件、自动注入收集器和代理配置、自动监视和扩展等。
首先要参考OpenTelemetry for Kubernetes 指南中的内容,安装OpenTelemetry Operator,注意此文档中给出了OpenTelemetry Operator,Kubernetes,Cert Manager的兼容性矩阵。
我是使用Helm安装的OpenTelemetry Operator,因为本文是OTLE Collector和Tempo的内容,所以省略安装过程。
安装和配置OpenTelemetry Collector #
这里将OTLE Collector以DaemonSet的形式运行在k8s集群中的每个节点上。
创建类型为OpenTelemetryCollector的CRD文件yaml文件,otelcol.yaml:
1apiVersion: opentelemetry.io/v1alpha1
2kind: OpenTelemetryCollector
3metadata:
4 name: otel-collector
5 namespace: olte
6spec:
7 mode: daemonset
8 hostNetwork: true
9 config: |
10 receivers:
11 otlp:
12 protocols:
13 grpc:
14
15 processors:
16 batch:
17
18 exporters:
19 otlp:
20 endpoint: tempo-distributor.tempo-test.svc.cluster.local:4317
21 tls:
22 insecure: true
23 # headers:
24 # authorization: Basic <base64 data>
25
26 service:
27 # extensions: [pprof, zpages, health_check]
28 pipelines:
29 traces:
30 receivers: [otlp]
31 processors: [batch]
32 exporters: [otlp]
spec.mode: daemonset
表示 OpenTelemetry Collector 将以DaemonSet模式运行,即在每个节点上都会运行一个Collector实例。hostNetwork: true
表示使用宿主机的网络命名空间进行通信。spec.config
部分包含了Collector的详细配置。在该配置中,包含了以下组件:receivers
配置了接收器,这里使用oltp
协议的grpc
接收器。processors
配置了处理器,这里使用了批处理器batch
。exporters
配置了导出器,这里使用了oltp
导出器,并为其指定了tempo distributor的端点地址(tempo-distributor.tempo-test.svc.cluster.local:4317
),同时设置了不安全传输(insecure: true
)。
- service 配置了服务相关的参数,这里定义了追踪数据的pipeline。该pipeline使用了前面定义的接收器、处理器和导出器,将追踪数据从接收器接收、经过处理器处理,最终导出到tempo。
部署完成后,查看otel-collector是否运行:
1k get po -n otel | grep otel-collector
2otel-collector-collector-2jvn5 1/1 Running 0 19m
3otel-collector-collector-4rqqg 1/1 Running 0 19m
4otel-collector-collector-7gp7s 1/1 Running 0 19m
5otel-collector-collector-7r2xn 1/1 Running 0 19m
6otel-collector-collector-7zf2r 1/1 Running 0 19m
7...
观测追踪数据 #
为了观测追踪数据,这里使用java的spring boot快速写一个程序,并将其构建为容器镜像,部署到Kubernetes集群中。
1@RestController
2public class FooController {
3
4 @Autowired
5 private StringRedisTemplate redisTemplate;
6
7 @Autowired
8 private FooMapper fooMapper;
9
10
11 @GetMapping("/otel-test")
12 public String otel() {
13 redisTemplate.opsForValue().set("otel-test", "otel");
14 String val = redisTemplate.opsForValue().get("otel-test");
15 int num = acctSupplierMapper.deleteById(-999L);
16 return val + num;
17 }
18}
REST接口/otel-test
,依次Redis SET, Redis GET和MySQL DELETE操作。
将此容器镜像部署到Kubernetes中时,通过环境变量的形式配置应用面向OLTE Collector的配置:
1```yaml
2env:
3 # 设置JAVA_OPTS的值, 在构建的容器镜像的启动命令中会使用这个值
4 # 通过-javaagent将opentelemetry-javaagent.jar添加,
5 # 这样将在JVM启动时加载OLTE Java Agent,使其能够对应用进行自动的分布式追踪和metrics监控。
6 # 通过-Dotel.traces.sampler.arg=1,将采样器采样率设置为1,表示将对所有跟踪数据进行采样。
7 - name: JAVA_OPTS
8 value: >-
9 -javaagent:/opt/javaagent/opentelemetry-javaagent.jar
10 -Dotel.traces.sampler.arg=1
11
12 # 通过引用Pod的状态中的 hostIP 字段获取值,并将其设置为环境变量HOST_IP的值
13 # 因为OLTE Collector以DaemonSet Pod和hostNetwork的模式运行在K8S节点上,
14 # 通过获取和设置应用容器所在K8S节点的HOST_IP,方便后边设置OTEL_EXPORTER_OTLP_ENDPOINT
15 - name: HOST_IP
16 valueFrom:
17 fieldRef:
18 apiVersion: v1
19 fieldPath: status.hostIP
20
21 # 通过引用Pod的元数据中的标签'app'的值,
22 # 并将其设置为环境变量OTEL_SERVICE_NAME的值
23 - name: OTEL_SERVICE_NAME
24 valueFrom:
25 fieldRef:
26 apiVersion: v1
27 fieldPath: metadata.labels['app']
28
29 # 使用环境变量HOST_IP的值拼接字符串,设置OTEL_EXPORTER_OTLP_ENDPOINT的值
30 # OTEL Collector的gRPC端口是4317
31 - name: OTEL_EXPORTER_OTLP_ENDPOINT
32 value: http://$(HOST_IP):4317
33
34 # 设置OTEL_EXPORTER_OTLP_PROTOCOL 的值为grpc
35 - name: OTEL_EXPORTER_OTLP_PROTOCOL
36 value: grpc
37
38 # 设置OTEL_TRACES_SAMPLER的值为 parentbased_traceidratio
39 - name: OTEL_TRACES_SAMPLER
40 value: parentbased_traceidratio
41
42 # 设置OTEL_INSTRUMENTATION_COMMON_DEFAULT_ENABLED 的值为 'false'
43 # 后边单独设置OTEL_INSTRUMENTATION_XXX_ENABLED
44 # 这个例子是一个Spring WebMVC的程序,只访问了redis和mysql
45 # 实际使用时推荐直接将设置OTEL_INSTRUMENTATION_COMMON_DEFAULT_ENABLED设置为true
46 - name: OTEL_INSTRUMENTATION_COMMON_DEFAULT_ENABLED
47 value: 'false'
48
49 - name: OTEL_INSTRUMENTATION_TOMCAT_ENABLED
50 value: 'true'
51
52 - name: OTEL_INSTRUMENTATION_SPRING_WEBMVC_ENABLED
53 value: 'true'
54
55 - name: OTEL_INSTRUMENTATION_JDBC_ENABLED
56 value: 'true'
57
58 - name: OTEL_INSTRUMENTATION_LETTUCE_ENABLED
59 value: 'true'
将此应用部署到K8S集群后:
1kubectl get deploy,po -l app=foo-api
2NAME READY UP-TO-DATE AVAILABLE AGE
3deployment.apps/foo-api-v1 1/1 1 1 10m
4
5NAME READY STATUS RESTARTS AGE
6pod/foo-api-v1-569f9ddf78-5pbbf 1/1 Running 0 11m
多次访问这个应用的REST接口/otel-test
。
在Grafana中配置Tempo数据源,测试查询分布式追踪数据。
总结 #
本文介绍了如何使用OpenTelemetry Collector将分布式追踪数据发送到Tempo,并利用Grafana对追踪数据进行可视化分析。以下是本文的主要内容:
- 可以使用Grafana Agent将分布式追踪数据发送到Tempo,但这不是必需的。Tempo服务暴露了符合OpenTelemetry TraceService标准的gRPC端点,因此任何能够发送符合标准的工具都可以发送跟踪数据到Tempo。
- 使用OpenTelemetry Operator可以简化在Kubernetes环境中部署和管理OpenTelemetry组件的流程。OpenTelemetry Operator是一个自定义的Kubernetes控制器,通过CRD和声明式配置,集中化管理OpenTelemetry组件的部署、配置和管理。
- 首先需要安装OpenTelemetry Operator,可以参考OpenTelemetry for Kubernetes指南进行安装。
- 通过定义OpenTelemetryCollector的CRD文件在Kubernetes集群中以DaemonSet模式部署OpenTelemetry Collector。
- 为了观测追踪数据,可以编写一个使用OpenTelemetry的Java Spring Boot应用程序,并将其部署到Kubernetes集群中。通过设置环境变量来配置应用程序与OpenTelemetry Collector的连接和跟踪配置。
- 最后,在Grafana中配置Tempo数据源,可以使用查询语言对分布式追踪数据进行可视化分析。
通过本文可以学习如何使用OpenTelemetry Collector和Tempo来收集和可视化分布式追踪数据。