Apache APISIX集成OpenTelemetry以收集跟踪数据
本文介绍了Apache APISIX的opentelemetry
插件概念以及如何启用和部署该插件。
背景信息
OpenTelemetry是一个开源的遥测数据采集和处理系统。它不仅提供各种用于应用端遥测数据收集和报告的SDK,还提供用于数据接收、处理和导出的数据收集端。可以导出到任何或多个OpenTelemetry后端,如Jaeger、Zipkin和OpenCensus。您可以在注册表中查看已适配OpenTelemetry Collector的插件列表。
插件介绍
Apache APISIX的opentelemetry
插件通过HTTP协议实现了Tracing数据收集,并将其发送到OpenTelemetry Collector。Apache APISIX从v2.13.0开始支持此功能。
OpenTelemetry的一个特点是其代理或SDK不与后端实现绑定,这使得用户在选择自己的后端服务时具有灵活性。换句话说,用户可以选择他们想要的后端服务,如Zipkin和Jaeger,而不会影响应用程序端。
opentelemetry
插件位于代理端,它集成了OpenTelemetry代理/SDK,并在Apache APISIX中采用其特性。它可以收集被跟踪的请求,生成trace
,并将其转发到OpenTelemetry Collector。它支持trace
协议,并将在下一个版本中支持OpenTelemetry的logs
和metrics
协议。
启用插件
您需要在conf/config.yaml
配置文件中启用opentelemetry
插件并修改收集器配置。
假设您已经在与APISIX相同的节点上部署了OpenTelemetry Collector,并开启了OTLP HTTP Receiver。
需要帮助完成OpenTelemetry Collector的部署吗?请参考下面的示例。
OTLP HTTP Receiver的默认端口是4318
,collector
的地址是OpenTelemetry Collector的HTTP Receiver地址。有关相关字段,请参阅Apache APISIX文档。
典型的配置如下所示:
plugins:
... # 已启用的其他插件
- opentelemetry
plugin_attr:
...
opentelemetry:
trace_id_source: x-request-id
resource:
service.name: APISIX
collector:
address: 127.0.0.1:4318 # OTLP HTTP Receiver地址
request_timeout: 3
方法1:为特定路由启用插件
为了更方便地显示测试效果,在示例中将sampler
临时设置为完整采样,以确保在跟踪每个请求之后生成trace
数据,这样您可以在Web UI上查看trace
相关数据。您也可以根据实际情况设置相关参数。
curl http://127.0.0.1:9080/apisix/admin/routes/1 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
-X PUT -d '
{
"uri": "/get",
"plugins": {
"opentelemetry": {
"sampler": {
"name": "always_on"
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
方法2:全局启用插件
您还可以通过Apache APISIX的插件功能全局启用opentelemetry
插件。完成全局配置后,仍然需要创建路由,否则无法进行测试。
curl 'http://127.0.0.1:9080/apisix/admin/global_rules/1' \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
-X PUT -d '{
"plugins": {
"opentelemetry": {
"sampler": {
"name": "always_on"
}
}
}
}'
方法3:通过additional_attributes自定义Span的标签
有关sampler
和additional_attributes
的配置,请参阅Apache APISIX文档。其中,additional_attributes
是一系列Key:Value
对,您可以使用它来自定义Span的标签,并可以在Web UI上显示Span。通过additional_attributes
向路由的Span中添加route_id
和http_x-custom-ot-key
,请参考以下配置:
curl http://127.0.0.1:9080/apisix/admin/routes/1001 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
-X PUT -d '
{
"uri": "/put",
"plugins": {
"opentelemetry": {
"sampler": {
"name": "always_on"
},
"additional_attributes":[
"route_id",
"http_x-custom-ot-key"
]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}'
测试和验证插件
您可以在上述三种方法中任何一个中启用opentelemetry
插件。下面的示例使用方法三的示例创建一个路由。创建成功后,查看下面的命令以访问路由:
curl -X PUT -H `x-custom-ot-key: test-ot-val` http://127.0.0.1:9080/put
访问成功后,您可以在Jaeger UI中看到类似于/put
的span的详细信息,并且您可以看到路由中的自定义标签显示在标签列表中:http_x-custom-ot-key
和route_id
。
需要注意的是,additional_attributes
配置设置为从Apache APISIX和NGINX变量中获取值作为attribute
的值,因此additional_attributes
必须是有效的Apache APISIX或NGINX变量。它还包括HTTP Header,但是在获取http*header时,您需要将http*
作为变量名称的前缀。如果变量不存在,则不会显示相应的tag
。
示例
本场景示例通过简单修改OpenTelemetry Collector示例来部署Collector、Jaeger和Zipkin作为后端服务,并启动两个示例应用程序(客户端和服务器)。其中服务器提供HTTP服务,客户端会周期性地调用由服务器提供的HTTP接口,从而形成由两个span组成的调用链。
步骤1:部署OpenTelemetry
以下以docker compose
为例。其他部署方式,请参考开始使用。
以下是部署的命令[^1]:
git clone https://github.com/open-telemetry/opentelemetry-collector-contrib.git
cd opentelemetry-collector-contrib/examples/demo
docker compose up -d
在浏览器中访问http://127.0.0.1:16886(Jaeger UI)或http://127.0.0.1:9411/zipkin(Zipkin UI)。如果能够正常访问,则部署成功。
下面的截图显示了成功访问的示例。
步骤2:配置测试环境
引入Apache APISIX服务,并在下图中显示了最终应用程序的拓扑。
追踪数据的报告过程如下。其中,由于Apache APISIX是单独部署的,而不在docker-compose的网络中,Apache APISIX通过本地映射端口(127.0.0.1:4138
)访问OpenTelemetry Collector的OTLP HTTP Receiver。
您需要确保已启用opentelemetry
插件并重新加载Apache APISIX。
以下示例创建一条路由并启用sampler
的opentelemetry
插件进行采样:
curl http://127.0.0.1:9080/apisix/admin/routes/1 \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
-X PUT -d '
{
"uri": "/hello",
"plugins": {
"opentelemetry": {
"sampler": {
"name": "always_on"
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:7080": 1
}
}
}'
修改./examples/demo/otel-collector-config.yaml
文件以添加OTLP HTTP Receiver。
receivers:
otlp:
protocols:
grpc:
http: ${ip:port} # 添加OTLP HTTP Receiver,默认端口是4318
修改docker-compose.yaml
文件。
您需要修改配置文件,将Client调用Server的接口地址更改为Apache APISIX的地址,并将OTLP HTTP Receiver和Server服务的端口映射到本地。
以下示例是修改配置后的完整docker-compose.yaml
:
version: '2'
services:
# Jaeger
jaeger-all-in-one:
image: jaegertracing/all-in-one:latest
ports:
- '16686:16686' # jaeger UI端口
- '14268'
- '14250'
# Zipkin
zipkin-all-in-one:
image: openzipkin/zipkin:latest
ports:
- '9411:9411'
# Collector
otel-collector:
image: ${OTELCOL_IMG}
command: ['--config=/etc/otel-collector-config.yaml', '${OTELCOL_ARGS}']
volumes:
- ./otel-collector-config.yaml:/etc/otel-collector-config.yaml
ports:
- '1888:1888' # pprof扩展
- '8888:8888' # 由collector暴露的Prometheus指标
- '8889:8889' # Prometheus exporter指标
- '13133:13133' # health_check扩展
- '4317' # OTLP gRPC接收器
- '4318:4318' # 添加OTLP HTTP Receiver端口映射
- '55670:55679' # zpages扩展
depends_on:
- jaeger-all-in-one
- zipkin-all-in-one
demo-client:
build:
dockerfile: Dockerfile
context: ./client
environment:
- OTEL_EXPORTER_OTLP_ENDPOINT=otel-collector:4317
- DEMO_SERVER_ENDPOINT=http://172.17.0.1:9080/hello # APISIX地址
depends_on:
- demo-server
demo-server:
build:
dockerfile: Dockerfile
context: ./server
environment:
- OTEL_EXPORTER_OTLP_ENDPOINT=otel-collector:4317
ports:
- '7080:7080' # 将Server端口映射到主机
depends_on:
- otel-collector
prometheus:
container_name: prometheus
image: prom/prometheus:latest
volumes:
- ./prometheus.yaml:/etc/prometheus/prometheus.yml
ports:
- '9090:9090'
需要注意的是,demo-client.environment.DEMO_SERVER_ENDPOINT
需要更改为您的Apache APISIX地址,并确保在容器中能够正常访问。
当然,您也可以通过docker-compose.yaml
部署Apache APISIX。详情请参见通过Docker安装。
步骤3:验证输出结果
重新部署完成后,您可以访问Jaeger UI或Zipkin UI,查看APISIX包含在Trace中的Span,如下所示:
当demo-server未进行仪表化时,通过启用该插件仍然可以获得demo-server行为的可见性。虽然这不是一个典型案例,但它是模拟对demo-server进行了真实仪表化的替代方案,并提供了很多价值。
当请求未到达demo-server时,输出结果中将不包含demo-server的span。
禁用插件
如果暂时不需要某个路由的跟踪收集,您只需修改路由配置并删除配置中的plugins
下的opentelemetry
部分。
如果通过绑定Global Rules全局启用了opentelemetry
插件,可以删除opentelemetry
全局插件的配置。
注意,禁用opentelemetry
插件只会导致APISIX的span断开连接,客户端和服务器的span仍然保持连接。
总结
在Apache APISIX集成OpenTelemetry之后,可以轻松与市场上的多个Trace系统进行连接。Apache APISIX还在积极与社区合作,创建一个更强大的生态系统。
Apache APISIX目前还在开发其他插件,以支持与更多服务的集成。如果您有兴趣,请随时在GitHub上开始讨论,或通过邮件列表进行交流。
本文的一个版本已经发布在Apache APISIX博客上。