14. 使用 Linkerd 进行分布式跟踪
在实践中使用分布式跟踪
可能很复杂,
为了从高层次解释您得到了什么以及它是如何完成的,
请查看服务网格中的分布式跟踪:四个误区。
本指南将引导您完成
emojivoto
的配置
和启用
跟踪。关于使用 Linkerd
使用分布式跟踪的最佳方式的一些建议,请跳到最后。
要使用分布式跟踪,您需要:
- 安装 Linkerd-Jaeger 扩展。
- 修改您的应用程序以发出跨度。
在 emojivoto
中,一旦所有这些步骤都完成,就会有一个看起来像这样的拓扑:
前提条件
- 要使用本指南,您需要在集群上安装
Linkerd
。 如果您还没有这样做,请按照安装 Linkerd 指南进行操作。
安装 Linkerd-Jaeger 扩展
获取分布式跟踪设置的第一步是将 Linkerd-Jaeger
扩展安装到您的集群上。
这个扩展由一个收集器(collector)
、一个 Jaeger 后端
和一个 Jaeger-injector
组成。
收集器消费从网格
和您的应用程序
发出的跨度
,
并将它们发送到 Jaeger 后端
,后者存储它们并提供 dashboard
以查看它们。
Jaeger-injector
负责配置 Linkerd 代理
以发出 span
。
要安装 Linkerd-Jaeger
扩展,请运行以下命令:
linkerd jaeger install | kubectl apply -f -
您可以通过运行以下命令来验证 Linkerd-Jaeger
扩展是否已正确安装:
linkerd jaeger check
安装 Emojivoto
将 emojivoto
添加到您的集群并使用 Linkerd proxy
注入它:
linkerd inject https://run.linkerd.io/emojivoto.yml | kubectl apply -f -
在进入下一步之前,请确保一切都已启动并使用 kubectl
运行以下命令:
kubectl -n emojivoto rollout status deploy/web
修改应用
与服务网格
的大多数功能不同,分布式跟踪
需要修改应用程序的源。
跟踪需要某种方式将传入的请求与您的应用程序与传出的请求绑定到相关服务。
为此,将向每个请求添加一些 header
,其中包含跟踪的唯一ID
。
Linkerd
使用 b3
propagation 传播格式将这些东西联系在一起。
我们已经修改了 emojivoto
以使用此信息检测其请求,此
commit
显示了这是如何完成的。
对于大多数编程语言,它只需要添加一个客户端库来处理这个问题。
Emojivoto
使用 OpenCensus
客户端,但也可以使用其他客户端。
要在 emojivoto 中启用跟踪,请运行:
kubectl -n emojivoto set env --all deploy OC_AGENT_HOST=collector.linkerd-jaeger:55678
此命令将添加一个环境变量
,使应用程序能够传播上下文
并发出跨度
。
探索 Jaeger
随着 vote-bot
开始跟踪每个请求,跨度现在应该出现在 Jaeger
。要进入 UI
,运行:
linkerd jaeger dashboard

您可以在下拉列表中搜索任何服务,然后单击 Find Traces
。vote-bot
是一个很好的入门方式。

单击特定跟踪将提供所有详细信息,您将能够看到每个代理的跨度!

该输出中肯定有很多 linkerd-proxy
跨度。
在内部,代理具有服务器端
和客户端
。
当请求通过代理时,由服务器接收,然后由客户端发出。
对于在两个网格 Pod
之间传递的单个请求,总共会有 4
个跨度。
当请求遍历该代理时,两个将在源
端,当远程代理接收到请求时,两个将在目标
端。
集成 Dashboard
设置好 Linkerd-Jaeger
扩展后,
由于代理添加了应用元数据
作为 trace
属性,
用户可以通过点击 Metrics Table
中的 Jaeger
图标,
直接从 linkerd-web
仪表板直接跳转到相关资源 trace
,如下图 :

要获得该功能,您需要安装(或升级)Linkerd-Viz
扩展,指定暴露 Jaeger UI
的服务。
默认情况下,这将是这样的:
linkerd viz install --set jaegerUrl=jaeger.linkerd-jaeger:16686
清理
要进行清理,请通过运行以下命令卸载 Linkerd-Jaeger 扩展
和 emojivoto
:
linkerd jaeger uninstall | kubectl delete -f -
kubectl delete ns emojivoto
带上你自己的 Jaeger
如果您有一个现有的 Jaeger
安装,
您可以配置 OpenCensus
收集器向它发送跟踪,
而不是 Linkerd-Jaeger
扩展中内置的 Jaeger
实例。
创建以下 YAML
文件,该文件禁用内置 Jaeger 实例
并指定 OpenCensus 收集器
的配置。
cat <<EOF > jaeger-linkerd.yaml
jaeger:
enabled: false
collector:
config: |
receivers:
otlp:
protocols:
grpc:
http:
opencensus:
zipkin:
jaeger:
protocols:
grpc:
thrift_http:
thrift_compact:
thrift_binary:
processors:
batch:
extensions:
health_check:
exporters:
jaeger:
endpoint: my-jaeger-collector.my-jaeger-ns:14250
insecure: true
service:
extensions: [health_check]
pipelines:
traces:
receivers: [otlp,opencensus,zipkin,jaeger]
processors: [batch]
exporters: [jaeger]
EOF
linkerd jaeger install --values ./jaeger-linkerd.yaml | kubectl apply -f -
您需要确保将本示例中的 my-jaeger-collector.my-jaeger-ns:14250
的
exporters.jager.endpoint
设置为适合您环境的值。
这应该指向端口 14250
上的 Jaeger Collector
。
YAML
文件与 Helm values.yaml 合并,后者显示了可以配置的其他可能值。
也可以手动编辑 OpenCensus 配置以将其导出到它支持的任何后端。 有关完整列表,请参阅 OpenCensus 文档。
故障排除
我没有看到代理的任何跨度
Linkerd proxy
使用 b3
propagation 传播格式。
一些客户端库,例如 Jaeger
,默认使用不同的格式。
您需要将客户端库配置为使用 b3
格式让代理
参与跟踪。
建议
Ingress
ingress
是分布式跟踪的一个特别重要的组件,因为它创建每个跟踪的根
跨度,
并负责决定是否应该对该跟踪进行采样
。
让 ingress
做出所有采样决策可确保对整个轨迹
进行采样
或不采样
,
并避免创建“部分轨迹(partial traces)”
。
分布式跟踪
系统都依赖于服务来传播有关从接收
到的请求到发送
的请求的当前跟踪的元数据
。
这一元数据
称为跟踪上下文
,通常编码在一个或多个请求 header
中。
有许多不同的跟踪上下文 header
格式,虽然我们希望生态系统最终会收敛于像 W3C
tracecontext 跟踪上下文这样的开放标准,
但我们今天只使用 b3
format。
作为最早广泛使用的格式之一,它具有最广泛的支持,尤其是在 Nginx
等入口中。
此参考架构包括一个简单的 Nginx
配置,该配置对 50%
的跟踪进行采样
并将跟踪数据
发送到
收集器(使用 Zipkin
协议)。任何入口控制器
都可以在这里代替 Nginx
使用,只要它:
- 支持概率采样
- 以 b3 格式编码跟踪上下文
- 在
OpenCensus collector
支持的协议中发出span
如果使用 helm
安装 ingress-nginx
,您可以使用以下命令配置跟踪:
controller:
config:
enable-opentracing: "true"
zipkin-collector-host: linkerd-collector.linkerd
客户端库
虽然服务可以手动传播跟踪传播header
,但使用执行以下三件事的库通常要容易得多:
- 将跟踪上下文从传入请求头传播到传出请求头
- 修改跟踪上下文(即开始一个新的跨度)
- 将此数据传输到
跟踪收集器(trace collector)
我们建议在您的服务中使用 OpenCensus
并使用以下内容对其进行配置:
OpenCensus agent exporter
将通过 gRPC API
将跟踪数据导出到 OpenCensus collector
。
如何配置 OpenCensus
的详细信息会因语言而异,但有许多流行语言的指南。
您还可以使用我们的示例应用程序
Emojivoto
在 Go
中查看端到端示例。
您可能会注意到 OpenCensus
项目存在维护模式并且将成为 OpenTelemetry 的一部分。
不幸的是,OpenTelemetry
尚未准备好生产
,因此 OpenCensus
仍然是我们目前的建议。
也可以使用许多其他跟踪客户端库。只需确保正在使用 b3
传播格式,
并且客户端库
可以以 collector
已配置为接收的格式导出其跨度
。
收集器: OpenCensus
OpenCensus collector
从 OpenCensus agent exporter
接收跟踪数据,
并可能在将该数据发送到 Jaeger
之前进行转换和过滤。
将 OpenCensus exporter
发送到 OpenCensus collector
为我们提供了很大的灵活性:
我们可以切换到 OpenCensus
支持的任何后端,而无需中断应用程序。
后端: Jaeger
Jaeger 是使用最广泛的跟踪后端之一,并且有充分的理由:它易于使用并且在可视化跟踪方面做得很好。 但是,可以改用 OpenCensus 支持的任何后端。
Linkerd
如果您的应用程序注入了 Linkerd
,Linkerd proxy
将
参与跟踪并将跟踪数据发送到 OpenCensus collector
。
这丰富了跟踪数据,并允许您准确查看请求在代理和线路上花费的时间。
虽然 Linkerd
只能主动参与使用 b3
传播格式的 trace
,
但 Linkerd
将始终透明地转发未知的请求头,
这意味着它永远不会干扰使用其他传播格式的跟踪。