zipkin
Zipkin 是一个开源的分布式追踪系统。zipkin 插件对 APISIX 进行插桩,并根据 Zipkin API 规范 将追踪信息发送到 Zipkin。
该 插件还可以将追踪信息发送到其他兼容的收集器,例如 Jaeger 和 Apache SkyWalking,它们都支持 Zipkin v1 和 v2 API。
示例
下面的示例展示了使用 zipkin 插件的不同用例。
发送追踪到 Zipkin
以下示例展示了如何使用 Zipkin API v2 追踪路由请求并将追踪信息发送到 Zipkin。你还将了解跨度版本 2 与跨度版本 1 之间的区别。
在 Docker 中启动一个 Zipkin 实例:
- Docker
- Kubernetes
docker run -d --name zipkin -p 9411:9411 openzipkin/zipkin
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: aic
name: zipkin
spec:
replicas: 1
selector:
matchLabels:
app: zipkin
template:
metadata:
labels:
app: zipkin
spec:
containers:
- name: zipkin
image: openzipkin/zipkin
ports:
- containerPort: 9411
---
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: zipkin
spec:
selector:
app: zipkin
ports:
- port: 9411
targetPort: 9411
type: ClusterIP
应用清单:
kubectl apply -f zipkin-server.yaml
创建一个启用了 zipkin 的路由,并使用默认的跨度版本 2:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "zipkin-tracing-route",
"uri": "/anything",
"plugins": {
"zipkin": {
"endpoint": "http://127.0.0.1:9411/api/v2/spans",
"sample_ratio": 1,
"span_version": 2
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org": 1
}
}
}'
services:
- name: httpbin
routes:
- uris:
- /anything
name: zipkin-tracing-route
plugins:
zipkin:
endpoint: "http://127.0.0.1:9411/api/v2/spans"
sample_ratio: 1
span_version: 2
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
将配置同步到网关:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: zipkin-plugin-config
spec:
plugins:
- name: zipkin
config:
endpoint: "http://zipkin.aic.svc.cluster.local:9411/api/v2/spans"
sample_ratio: 1
span_version: 2
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: zipkin-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: zipkin-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: zipkin-route
spec:
ingressClassName: apisix
http:
- name: zipkin-route
match:
paths:
- /anything
upstreams:
- name: httpbin-external-domain
plugins:
- name: zipkin
enable: true
config:
endpoint: "http://zipkin.aic.svc.cluster.local:9411/api/v2/spans"
sample_ratio: 1
span_version: 2
将配置应用到集群:
kubectl apply -f zipkin-ic.yaml
❶ 根据需要调整 Zipkin HTTP 端点的 IP 地址。
❷ 将采样率配置为 1 以追踪每个请求。
❸ 将跨度版本设置为 2。
发送请求到该路由:
curl "http://127.0.0.1:9080/anything"
你应该收到类似于以下的 HTTP/1.1 200 OK 响应:
{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Host": "127.0.0.1",
"User-Agent": "curl/7.64.1",
"X-Amzn-Trace-Id": "Root=1-65af2926-497590027bcdb09e34752b78",
"X-B3-Parentspanid": "347dddedf73ec176",
"X-B3-Sampled": "1",
"X-B3-Spanid": "429afa01d0b0067c",
"X-B3-Traceid": "aea58f4b490766eccb08275acd52a13a",
"X-Forwarded-Host": "127.0.0.1"
},
...
}
导航到 http://127.0.0.1:9411/zipkin 的 Zipkin web UI 并点击 Run Query,你应该看到与请求对应的追踪:

点击 Show 查看更多追踪详情:

请注意,使用跨度版本 2 时,每个被追踪的请求都会创建以下跨度:
request
├── proxy
└── response
其中 proxy 代表从请求开始到 header_filter 开始的时间,response 代表从 header_filter 开始到 log 开始的时间。
自 API7 企业版 3.9.10 和 APISIX 3.17.0 起,请求跨度包含 apisix.response_source 标签,用于分类响应来源:apisix(由 APISIX 生成,如插件拒绝)、nginx(NGINX 代理错误)或 upstream(来自上游服务的真实响应)。
现在,更新路由上的插件以使用跨度版本 1:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes/zipkin-tracing-route" -X PATCH \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"plugins": {
"zipkin": {
"span_version": 1
}
}
}'
更新 adc.yaml,将 span_version 设置为 1:
services:
- name: httpbin
routes:
- uris:
- /anything
name: zipkin-tracing-route
plugins:
zipkin:
endpoint: "http://127.0.0.1:9411/api/v2/spans"
sample_ratio: 1
span_version: 1
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
将配置同步到网关:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
更新 zipkin-ic.yaml,将 span_version 设置为 1:
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: zipkin-plugin-config
spec:
plugins:
- name: zipkin
config:
endpoint: "http://zipkin.aic.svc.cluster.local:9411/api/v2/spans"
sample_ratio: 1
span_version: 1
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: zipkin-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: zipkin-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
更新 zipkin-ic.yaml,将 span_version 设置为 1:
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: zipkin-route
spec:
ingressClassName: apisix
http:
- name: zipkin-route
match:
paths:
- /anything
upstreams:
- name: httpbin-external-domain
plugins:
- name: zipkin
enable: true
config:
endpoint: "http://zipkin.aic.svc.cluster.local:9411/api/v2/spans"
sample_ratio: 1
span_version: 1
重新应用配置:
kubectl apply -f zipkin-ic.yaml
发送另一个请求到该路由:
curl "http://127.0.0.1:9080/anything"
在 Zipkin web UI 中,你应该看到一个新的追踪,其详情类似于以下内容:

请注意,使用较旧的跨度版本 1 时,每个被追踪的请求都会创建以下跨度:
request
├── rewrite
├── access
└── proxy
└── body_filter
发送追踪到 Jaeger
以下示例展示了如何追踪对路由的请求并将追踪信息发送到 Jaeger。
在 Docker 中启动一个 Jaeger 实例:
- Docker
- Kubernetes
docker run -d --name jaeger \
-e COLLECTOR_ZIPKIN_HOST_PORT=9411 \
-p 16686:16686 \
-p 9411:9411 \
jaegertracing/all-in-one
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: aic
name: jaeger
spec:
replicas: 1
selector:
matchLabels:
app: jaeger
template:
metadata:
labels:
app: jaeger
spec:
containers:
- name: jaeger
image: jaegertracing/all-in-one
env:
- name: COLLECTOR_ZIPKIN_HOST_PORT
value: "9411"
ports:
- containerPort: 16686
- containerPort: 9411
---
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: jaeger
spec:
selector:
app: jaeger
ports:
- name: ui
port: 16686
targetPort: 16686
- name: zipkin
port: 9411
targetPort: 9411
type: ClusterIP
应用清单:
kubectl apply -f jaeger-server.yaml
创建一个带有 zipkin 插件的路由:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "zipkin-tracing-route",
"uri": "/anything",
"plugins": {
"zipkin": {
"endpoint": "http://127.0.0.1:9411/api/v2/spans",
"sample_ratio": 1
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org": 1
}
}
}'
services:
- name: httpbin
routes:
- uris:
- /anything
name: zipkin-tracing-route
plugins:
zipkin:
endpoint: "http://127.0.0.1:9411/api/v2/spans"
sample_ratio: 1
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
将配置同步到网关:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: zipkin-jaeger-plugin-config
spec:
plugins:
- name: zipkin
config:
endpoint: "http://jaeger.aic.svc.cluster.local:9411/api/v2/spans"
sample_ratio: 1
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: zipkin-jaeger-route
spec:
parentRefs:
- name: apisix
hostnames:
- "jaeger.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: zipkin-jaeger-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: zipkin-jaeger-route
spec:
ingressClassName: apisix
http:
- name: zipkin-jaeger-route
match:
hosts:
- "jaeger.example.com"
paths:
- /*
upstreams:
- name: httpbin-external-domain
plugins:
- name: zipkin
enable: true
config:
endpoint: "http://jaeger.aic.svc.cluster.local:9411/api/v2/spans"
sample_ratio: 1
将配置应用到集群:
kubectl apply -f zipkin-jaeger-ic.yaml
❶ 根据需要调整 Zipkin HTTP 端点的 IP 地址。
❷ 将采样率配置为 1 以追踪每个请求。
发送请求到该路由:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9080/anything"
curl "http://127.0.0.1:9080/anything"
curl "http://127.0.0.1:9080/anything" -H "Host: jaeger.example.com"
你应该收到 HTTP/1.1 200 OK 响应。
导航到 http://127.0.0.1:16686 的 Jaeger web UI,选择 APISIX 作为服务,然后点击 Find Traces,你应该看到与请求对应的追踪:

同样,点击进入追踪后,你应该会发现更多跨度详情:

在日志记录中使用追踪变量
以下示例展示了如何配置 zipkin 插件以设置以下内置变量,这些变量可用于日志插件或访问日志:
zipkin_context_traceparent:父级链路 IDzipkin_trace_id: 当前跨度的链路 IDzipkin_span_id:当前跨度的跨度 ID
启用这些变量的访问日志输出,并允许插件设置 NGINX 变量:
- Host or Docker
- Kubernetes (Helm)
在网关配置文件中新增或更新以下配置:
nginx_config:
http:
enable_access_log: true
access_log_format: '{"time": "$time_iso8601","zipkin_context_traceparent": "$zipkin_context_traceparent","zipkin_trace_id": "$zipkin_trace_id","zipkin_span_id": "$zipkin_span_id","remote_addr": "$remote_addr"}'
access_log_format_escape: json
plugin_attr:
zipkin:
set_ngx_var: true
❶ access_log_format: 自定义访问日志格式以使用 zipkin 插件变量。
❷ set_ngx_var: 设置 zipkin 变量。
重新加载网关以使配置更改生效。
对于 Helm 部署,请更新用于渲染访问日志格式和 plugin_attr.zipkin 的 values,并保留 values 文件中的其他配置。
对于 APISIX Helm Chart,设置以下 values:
apisix:
nginx:
logs:
enableAccessLog: true
accessLogFormat: '{"time": "$time_iso8601","zipkin_context_traceparent": "$zipkin_context_traceparent","zipkin_trace_id": "$zipkin_trace_id","zipkin_span_id": "$zipkin_span_id","remote_addr": "$remote_addr"}'
accessLogFormatEscape: json
pluginAttrs:
zipkin:
set_ngx_var: true
对于 API7 网关 Helm Chart,设置以下 values:
logs:
enableAccessLog: true
accessLogFormat: '{"time": "$time_iso8601","zipkin_context_traceparent": "$zipkin_context_traceparent","zipkin_trace_id": "$zipkin_trace_id","zipkin_span_id": "$zipkin_span_id","remote_addr": "$remote_addr"}'
accessLogFormatEscape: json
pluginAttrs:
zipkin:
set_ngx_var: true
然后使用当前网关 release 对应的 Chart 应用 values 文件:
helm upgrade <release-name> <chart-name> -n <namespace> -f values.yaml
生成请求时,你应该看到类似于以下的访问日志条目:
{"time": "23/Jan/2024:06:28:00 +0000","zipkin_context_traceparent": "00-61bce33055c56f5b9bec75227befd142-13ff3c7370b29925-01","zipkin_trace_id": "61bce33055c56f5b9bec75227befd142","zipkin_span_id": "13ff3c7370b29925","remote_addr": "172.28.0.1"}