本文介绍如何使用OpenTelemetry对Kong进行链路追踪。Kong是一个云原生、平台无关、可扩展的API网关,提供负载均衡、安全性、监控和API管理功能,并支持各种插件以扩展其功能。Kong OpenTelemetry 插件支持采集Kong的调用链数据并上报至可观测链路 OpenTelemetry 版,只需添加少量配置即可开启链路追踪。
使用限制
Kong版本要求:3.1.x及以上版本。
Kong链路追踪功能只支持HTTP协议(HTTP/HTTPS),不支持TCP和UDP。
Kong OpenTelemetry插件目前仅支持通过HTTP方式上报,不支持gRPC方式上报。
前提条件
接入步骤(自动埋点)
Kong OpenTelemetry插件支持采集Kong的调用链数据并上报至可观测链路 OpenTelemetry 版,您只需修改Kong的配置文件即可开启链路追踪。
一、为Kong开启链路追踪
方法一:在环境变量里设置
KONG_TRACING_INSTRUMENTATIONS
:开启链路追踪。KONG_TRACING_SAMPLING_RATE
:采样率,取值范围为0到1.0。1.0为全部采样,0为不采样。
KONG_TRACING_INSTRUMENTATIONS=all
KONG_TRACING_SAMPLING_RATE=1
方法二:在kong.conf配置文件中设置
tracing_instrumentations
:开启链路追踪。tracing_sampling_rate
:采样率,取值范围为0到1.0。1.0为全部采样,0为不采样。
# kong.conf
tracing_instrumentations = all
tracing_sampling_rate = 1.0
...
二、配置OpenTelemetry上报参数
使用以下三种方法配置OpenTelemetry上报参数时,请替换以下参数:
${HTTP_ENDPOINT}
:HTTP接入点,请替换为前提条件中获取到的HTTP接入点,例如http://tracing-analysis-dc-hk.aliyuncs.com/adapt_xxxxx/api/otlp/traces
。${SERVICE_NAME}
:应用名,自定义。此名称将会作用Kong的应用名称在可观测链路 OpenTelemetry 版控制台中展示。
方法一:在kong.yaml
中设置OpenTelemetry上报地址和应用名称
# kong.yaml
...
plugins:
...
- name: opentelemetry
config:
traces_endpoint: ${HTTP_ENDPOINT}
resource_attributes:
service.name: ${SERVICE_NAME}
方法二:通过Kong Admin API设置OpenTelemetry上报地址和应用名称
curl -X POST http://localhost:8001/plugins/ \
--header "accept: application/json" \
--header "Content-Type: application/json" \
--data '
{
"name": "opentelemetry",
"config": {
"traces_endpoint": "${HTTP_ENDPOINT}",
"resource_attributes": {
"service.name": "${SERVICE_NAME}"
}
}
}
'
方法三:在Kubernetes中创建KongClusterPlugin资源,并设置OpenTelemetry上报地址和应用名称
apiVersion: configuration.konghq.com/v1
kind: KongClusterPlugin
metadata:
name: <global-opentelemetry>
annotations:
kubernetes.io/ingress.class: kong
labels:
global: "true"
config:
traces_endpoint: ${HTTP_ENDPOINT}
resource_attributes:
service.name: ${SERVICE_NAME}
plugin: opentelemetry
设置完OpenTelemetry上报地址和应用名称后,需要重启Kong网关,即可为Kong开启OpenTelemetry链路追踪。
三、查看Kong调用链
完成以上配置后,您可通过Kong创建路由并进行访问,以生成调用链。然后登录可观测链路 OpenTelemetry 版控制台,查看由OpenTelemetry生成的Kong调用链。
在应用列表页面查看Kong应用。
在调用链分析页面打开Kong的调用链,查看请求耗时、客户端IP、 HTTP状态码、HTTP路由等信息。
四、高级配置(可选)
配置一:设置Kong OpenTelemetry插件使用的链路透传协议(Trace上下文格式)
在默认情况下,Kong OpenTelemetry使用W3C作为链路透传协议,这意味着插件只会识别上游传入的W3C协议请求头,并向下透传W3C协议请求头。如果您需要Kong支持其他透传协议,可以修改config.propagation.extract
、config.propagation.inject
和config.propagation.default_format
参数。
以下面的配置为例,插件将按照W3C(OpenTelemetry)、b3(Zipkin)、Jaeger、OT(OpenTracing)的顺序尝试从HTTP请求头中提取Trace上下文,preserve
意味着Kong的链路向下透传时保留原始格式。如果未识别到上下文,将使用default_format
中定义的W3C格式生成Trace。
# kong.yaml
...
plugins:
...
- name: opentelemetry
config:
...
propagation:
extract: [ w3c, b3, jaeger, ot ]
inject: [ preserve ]
default_format: "w3c"
配置二:设置Kong OpenTelemetry插件生效范围
Kong OpenTelemetry插件支持四种生效范围,分别是全局生效、应用级别生效、路由级别生效和Consumer级别生效。默认情况下Kong OpenTelemetry插件全局生效,如果您希望修改生效范围,请参考以下配置进行修改。
为单个应用开启
请将
${SERVICE_NAME|ID}
替换为允许插件生效的服务名称或服务ID。# kong.yaml plugins: ... - name: opentelemetry service: ${SERVICE_NAME|ID} config: traces_endpoint: ${HTTP_ENDPOINT} resource_attributes: service.name: ${SERVICE_NAME}
为单个路由开启
请将
${ROUTE_NAME|ID}
替换为允许插件生效的路由名称或路由ID。# kong.yaml plugins: ... - name: opentelemetry route: ${ROUTE_NAME|ID} config: traces_endpoint: ${HTTP_ENDPOINT} resource_attributes: service.name: ${SERVICE_NAME}
为单个Consumer开启
请将
${CONSUMER_NAME|ID}
替换为允许插件生效的Consumer名称或Consumer ID。# kong.yaml plugins: ... - name: opentelemetry consumer: ${CONSUMER_NAME|ID} config: traces_endpoint: ${HTTP_ENDPOINT} resource_attributes: service.name: ${SERVICE_NAME}
配置三:设置采集的Kong链路类型
Kong允许通过tracing_instrumentations
配置项或KONG_TRACING_INSTRUMENTATIONS
环境变量来指定要采集的链路类型。类型如下表所示。
参数取值 | 描述 |
off | 关闭链路追踪 |
all | 启用以下所有类型的链路追踪 |
request | 只启用请求级别的链路追踪 |
db_query | 追踪数据库查询 |
dns_query | 追踪DNS查询 |
router | 追踪路由器执行,包括路由器重建 |
http_client | 追踪OpenResty HTTP客户端请求 |
balancer | 追踪负载均衡器重试 |
plugin_rewrite | 追踪插件迭代器在重写阶段的执行 |
plugin_access | 追踪插件迭代器在访问阶段的执行 |
plugin_header_filter | 追踪插件迭代器在头部过滤阶段的执行 |
操作示例
下文将通过一个例子演示如何采集Kong网关及后端应用的调用链,并上报至可观测链路 OpenTelemetry 版。
准备工作
确认已安装Git、Docker和Docker Compose,Docker版本 ≥ 20.10.0。
项目结构
仅展示本示例需要的文件。
docker-kong/compose/
│
├── docker-compose.yml # Docker Compose配置文件
│
├── config/
│ └── kong.yaml # Kong声明式配置文件
│
└── backend/
├── Dockerfile # 后端服务的Dockerfile
├── main.js
├── package.json
└── package-lock.json
操作步骤
下载
Kong/docker-kong
开源项目。git clone https://github.com/Kong/docker-kong.git && cd docker-kong/compose
创建后端服务(以Node.js应用为例)。
本步骤会创建一个使用Express框架的Node.js应用,该应用在7001端口启动并暴露
/hello
端点。创建应用目录。
mkdir backend && cd backend
创建package.json。
cat << EOF > package.json { "name": "backend", "version": "1.0.0", "main": "index.js", "scripts": {}, "keywords": [], "author": "", "license": "ISC", "description": "", "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/auto-instrumentations-node": "^0.52.0", "axios": "^1.7.7", "express": "^4.21.1" } } EOF
创建main.js。
cat << EOF > main.js "use strict"; const axios = require("axios").default; const express = require("express"); const app = express(); app.get("/", async (req, res) => { const result = await axios.get("http://localhost:7001/hello"); return res.status(201).send(result.data); }); app.get("/hello", async (req, res) => { console.log("hello world!") res.json({ code: 200, msg: "success" }); }); app.use(express.json()); app.listen(7001, () => { console.log("Listening on http://localhost:7001"); }); EOF
创建Dockerfile。
说明请按照前提条件中的步骤获取HTTP接入点,并替换
${HTTP_ENDPOINT}
。cat << EOF > Dockerfile FROM node:20.16.0 WORKDIR /app COPY package*.json ./ RUN npm install COPY . . ENV OTEL_TRACES_EXPORTER="otlp" ENV OTEL_LOGS_EXPORTER=none ENV OTEL_METRICS_EXPORTER=none ENV OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="${HTTP_ENDPOINT}" ENV OTEL_NODE_RESOURCE_DETECTORS="env,host,os" ENV OTEL_SERVICE_NAME="ot-nodejs-demo" ENV NODE_OPTIONS="--require @opentelemetry/auto-instrumentations-node/register" EXPOSE 7001 CMD ["node", "main.js"] EOF
为Kong开启链路追踪,并将后端服务添加到Docker Compose中。
从
backend
目录回到上层目录。cd ..
修改docker compose。
vim docker-compose.yml
在
docker-compose.yml
文件中为Kong添加环境变量,开启链路追踪。... services: kong: ... environment: ... # 新增两个环境变量 KONG_TRACING_INSTRUMENTATIONS: all KONG_TRACING_SAMPLING_RATE: 1.0 ... ...
在
docker-compose.yml
文件中定义名为backend-api
的Nodejs后端服务。... services: ... backend-api: build: context: ./backend dockerfile: Dockerfile environment: NODE_ENV: production ports: - "7001:7001" networks: - kong-net ...
在Kong中配置后端服务和路由规则,并启用OpenTelemetry插件。
进入conf文件夹。
cd config
将以下内容追加到kong.yaml中。
说明请按照前提条件中的步骤获取HTTP接入点,并替换
${HTTP_ENDPOINT}
。cat << EOF >> kong.yaml services: - name: backend-api url: http://backend-api:7001 routes: - name: main-route paths: - /hello plugins: - name: opentelemetry config: traces_endpoint: ${HTTP_ENDPOINT} # 请替换为实际的HTTP接入点 headers: X-Auth-Token: secret-token resource_attributes: service.name: kong-dev EOF
启动Kong和后端服务。
回到上层目录。
cd ..
在
docker-compose.yml
文件所在目录中执行命令,启动Kong和后端服务。docker compose up -d
通过Kong访问后端服务。
curl http://localhost:8000/hello # 预期输出:{"code":200,"msg":"success"}
前往可观测链路 OpenTelemetry 版控制台,查看Kong及后端服务的调用链。
说明在本例中,Kong在应用列表页面的名称显示为kong-dev,后端应用名称为ot-nodejs-demo。
常见问题
启用Kong OpenTelemetry插件后,在可观测链路 OpenTelemetry 版控制台没有看到Kong的调用链。
将Kong的日志级别设置为debug(设置环境变量KONG_LOG_LEVEL=debug或者在kong.conf文件中设置log_level=debug),重新生成请求,然后查看日志中是否输出了Kong的调用链信息。
Kong的调用链无法与其他应用串联。
请确认其他应用使用的链路透传协议与Kong的透传协议是否相同,默认情况下Kong使用W3C作为透传协议。
Kong OpenTelemetry插件是否会对Kong网关的性能产生影响?
启用Kong OpenTelemetry插件可能会对Kong网关产生影响。推荐调整链路采样率(具体方法,请参见一、为Kong开启链路追踪),并调整OpenTelemetry插件上报调用链的批次大小、重试次数和重试时间。插件具体配置,请参见 Kong OpenTelemetry Configuration。