可以使用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数据源,测试查询分布式追踪数据。

otle-collector-to-tempo.png

总结

本文介绍了如何使用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来收集和可视化分布式追踪数据。

参考