在实践中使用分布式跟踪可能很复杂, 为了从高层次解释您得到了什么以及它是如何完成的, 我们整理了一个list of myths。
本指南将引导您完成 emojivoto
的配置和启用跟踪。关于使用 Linkerd
使用分布式跟踪的最佳方式的一些建议,请跳到最后。
要使用分布式跟踪,您需要:
- 安装 Linkerd-Jaeger 扩展。
- 修改您的应用程序以发出跨度。
在 emojivoto 的情况下,一旦所有这些步骤都完成,就会有一个看起来像这样的拓扑:
先决条件
- 要使用本指南,您需要在集群上安装 Linkerd。如果您还没有这样做,请按照安装 Linkerd 指南进行操作。
安装 Linkerd-Jaeger 扩展
获取分布式跟踪设置的第一步是将 Linkerd-Jaeger 扩展安装到您的集群上。这个扩展由一个收集器(collector)、一个 Jaeger 后端和一个 Jaeger-injector 组成。收集器消耗从网格和您的应用程序发出的跨度, 并将它们发送到 Jaeger 后端,后者存储它们并提供仪表板以查看它们。Jaeger-injector 负责配置 Linkerd 代理以发出 span。
要安装 Linkerd-Jaeger 扩展,请运行以下命令:
linkerd jaeger install | kubectl apply -f -
您可以通过运行以下命令来验证 Linkerd-Jaeger 扩展是否已正确安装:
linkerd jaeger check
安装 Emojivoto
将 emojivoto 添加到您的集群并使用 Linkerd 代理注入它:
linkerd inject https://run.linkerd.io/emojivoto.yml | kubectl apply -f -
在进入下一步之前,请确保一切都已启动并使用 kubectl
运行以下命令:
kubectl -n emojivoto rollout status deploy/web
修改应用
与服务网格的大多数功能不同,分布式跟踪需要修改应用程序的源。跟踪需要某种方式将传入的请求与您的应用程序与传出的请求绑定到相关服务。为此,将向每个请求添加一些标头,其中包含跟踪的唯一 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 个跨度。当请求遍历该代理时,两个将在源端,当远程代理接收到请求时,两个将在目标端。
此外,由于代理添加了应用元数据作为跟踪属性,用户可以通过单击度量表中的 Jaeger 图标, 直接从 linkerd-web 仪表板直接跳转到相关资源跟踪,如下所示
清理
要进行清理,请通过运行以下命令卸载 Linkerd-Jaeger 扩展和 emojivoto:
linkerd jaeger uninstall | kubectl delete -f - kubectl delete ns emojivoto
带上你自己的 Jaeger
如果您有一个现有的 Jaeger 安装, 您可以配置 OpenCensus
收集器向它发送跟踪, 而不是 Linkerd-Jaeger
扩展中内置的 Jaeger
实例。
linkerd jaeger install --set collector.jaegerAddr='http://my-jaeger-collector.my-jaeger-ns:14268/api/traces' | kubectl apply -f -
也可以手动编辑 OpenCensus 配置以将其导出到它支持的任何后端。有关完整列表,请参阅 OpenCensus 文档。
故障排除
我没有看到代理的任何跨度
Linkerd 代理使用 b3 propagation 传播格式。一些客户端库,例如 Jaeger
,默认使用不同的格式。您需要将客户端库配置为使用 b3
格式让代理参与跟踪。
建议
Ingress
ingress 是分布式跟踪的一个特别重要的组件,因为它创建每个跟踪的根跨度, 并负责决定是否应该对该跟踪进行采样。让 ingress 做出所有采样决策可确保对整个轨迹进行采样或不采样, 并避免创建“部分轨迹(partial traces
)”。
分布式跟踪系统都依赖于服务来传播有关从接收到的请求到发送的请求的当前跟踪的元数据。这一元数据称为跟踪上下文,通常编码在一个或多个请求标头中。有许多不同的跟踪上下文标头格式,虽然我们希望生态系统最终会收敛于像 W3C tracecontext 跟踪上下文这样的开放标准, 但我们今天只使用 b3 format。作为最早广泛使用的格式之一,它具有最广泛的支持,尤其是在 Nginx 等入口中。
此参考架构包括一个简单的 Nginx 配置,该配置对 50% 的跟踪进行采样并将跟踪数据发送到 收集器(使用 Zipkin 协议)。任何入口控制器都可以在这里代替 Nginx 使用,只要它:
- 支持概率采样
- 以 b3 格式编码跟踪上下文
- 在 OpenCensus 收集器支持的协议中发出 span
如果使用 helm 安装 ingress-nginx,您可以使用以下命令配置跟踪:
controller: config: enable-opentracing: "true" zipkin-collector-host: linkerd-collector.linkerd
客户端库
虽然服务可以手动传播跟踪传播标头,但使用执行以下三件事的库通常要容易得多:
- 将跟踪上下文从传入请求头传播到传出请求头
- 修改跟踪上下文(即开始一个新的跨度)
- 将此数据传输到跟踪收集器
我们建议在您的服务中使用 OpenCensus 并配置它:
- b3 propagation (这是默认设置)
- the OpenCensus agent exporter
OpenCensus agent exporter
将通过 gRPC API 将跟踪数据导出到 OpenCensus 收集器。如何配置 OpenCensus 的详细信息会因语言而异,但有许多流行语言的指南。您还可以使用我们的示例应用程序 Emojivoto 在 Go 中查看端到端示例。
您可能会注意到 OpenCensus 项目处于维护模式并将成为 OpenTelemetry 的一部分。不幸的是,OpenTelemetry 尚未准备好投入生产,因此 OpenCensus 仍然是我们目前的建议。
也可以使用许多其他跟踪客户端库。只需确保正在使用 b3 传播格式, 并且客户端库可以以收集器已配置为接收的格式导出其跨度。
收集器: OpenCensus
OpenCensus collector
从 OpenCensus agent exporter
接收跟踪数据, 并可能在将该数据发送到 Jaeger 之前进行转换和过滤。将 OpenCensus exporter
发送到 OpenCensus collector
为我们提供了很大的灵活性:我们可以切换到 OpenCensus
支持的任何后端,而无需中断应用程序。
后端: Jaeger
Jaeger 是使用最广泛的跟踪后端之一,并且有充分的理由:它易于使用并且在可视化跟踪方面做得很好。但是,可以改用 OpenCensus 支持的任何后端。
Linkerd
如果您的应用程序注入了 Linkerd
,Linkerd
代理将参与跟踪并将跟踪数据发送到 OpenCensus
收集器。这丰富了跟踪数据,并允许您准确查看请求在代理和线路上花费的时间。
虽然 Linkerd
只能主动参与使用 b3
传播格式的trace, 但 Linkerd
将始终透明地转发未知的请求头, 这意味着它永远不会干扰使用其他传播格式的 trace
。