可以使用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:
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
name: otel-collector
namespace: olte
spec:
mode: daemonset
hostNetwork: true
config: |
receivers:
otlp:
protocols:
grpc:
processors:
batch:
exporters:
otlp:
endpoint: tempo-distributor.tempo-test.svc.cluster.local:4317
tls:
insecure: true
# headers:
# authorization: Basic <base64 data>
service:
# extensions: [pprof, zpages, health_check]
pipelines:
traces:
receivers: [otlp]
processors: [batch]
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是否运行:
k get po -n otel | grep otel-collector
otel-collector-collector-2jvn5 1/1 Running 0 19m
otel-collector-collector-4rqqg 1/1 Running 0 19m
otel-collector-collector-7gp7s 1/1 Running 0 19m
otel-collector-collector-7r2xn 1/1 Running 0 19m
otel-collector-collector-7zf2r 1/1 Running 0 19m
...观测追踪数据
为了观测追踪数据,这里使用java的spring boot快速写一个程序,并将其构建为容器镜像,部署到Kubernetes集群中。
@RestController
public class FooController {
@Autowired
private StringRedisTemplate redisTemplate;
@Autowired
private FooMapper fooMapper;
@GetMapping("/otel-test")
public String otel() {
redisTemplate.opsForValue().set("otel-test", "otel");
String val = redisTemplate.opsForValue().get("otel-test");
int num = acctSupplierMapper.deleteById(-999L);
return val + num;
}
}REST接口/otel-test,依次Redis SET, Redis GET和MySQL DELETE操作。
将此容器镜像部署到Kubernetes中时,通过环境变量的形式配置应用面向OLTE Collector的配置:
```yaml
env:
# 设置JAVA_OPTS的值, 在构建的容器镜像的启动命令中会使用这个值
# 通过-javaagent将opentelemetry-javaagent.jar添加,
# 这样将在JVM启动时加载OLTE Java Agent,使其能够对应用进行自动的分布式追踪和metrics监控。
# 通过-Dotel.traces.sampler.arg=1,将采样器采样率设置为1,表示将对所有跟踪数据进行采样。
- name: JAVA_OPTS
value: >-
-javaagent:/opt/javaagent/opentelemetry-javaagent.jar
-Dotel.traces.sampler.arg=1
# 通过引用Pod的状态中的 hostIP 字段获取值,并将其设置为环境变量HOST_IP的值
# 因为OLTE Collector以DaemonSet Pod和hostNetwork的模式运行在K8S节点上,
# 通过获取和设置应用容器所在K8S节点的HOST_IP,方便后边设置OTEL_EXPORTER_OTLP_ENDPOINT
- name: HOST_IP
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: status.hostIP
# 通过引用Pod的元数据中的标签'app'的值,
# 并将其设置为环境变量OTEL_SERVICE_NAME的值
- name: OTEL_SERVICE_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.labels['app']
# 使用环境变量HOST_IP的值拼接字符串,设置OTEL_EXPORTER_OTLP_ENDPOINT的值
# OTEL Collector的gRPC端口是4317
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: http://$(HOST_IP):4317
# 设置OTEL_EXPORTER_OTLP_PROTOCOL 的值为grpc
- name: OTEL_EXPORTER_OTLP_PROTOCOL
value: grpc
# 设置OTEL_TRACES_SAMPLER的值为 parentbased_traceidratio
- name: OTEL_TRACES_SAMPLER
value: parentbased_traceidratio
# 设置OTEL_INSTRUMENTATION_COMMON_DEFAULT_ENABLED 的值为 'false'
# 后边单独设置OTEL_INSTRUMENTATION_XXX_ENABLED
# 这个例子是一个Spring WebMVC的程序,只访问了redis和mysql
# 实际使用时推荐直接将设置OTEL_INSTRUMENTATION_COMMON_DEFAULT_ENABLED设置为true
- name: OTEL_INSTRUMENTATION_COMMON_DEFAULT_ENABLED
value: 'false'
- name: OTEL_INSTRUMENTATION_TOMCAT_ENABLED
value: 'true'
- name: OTEL_INSTRUMENTATION_SPRING_WEBMVC_ENABLED
value: 'true'
- name: OTEL_INSTRUMENTATION_JDBC_ENABLED
value: 'true'
- name: OTEL_INSTRUMENTATION_LETTUCE_ENABLED
value: 'true'将此应用部署到K8S集群后:
kubectl get deploy,po -l app=foo-api
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/foo-api-v1 1/1 1 1 10m
NAME READY STATUS RESTARTS AGE
pod/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来收集和可视化分布式追踪数据。