在Kubernetes上使用Jaeger的分布式追踪基础设施
转载请注明来源:https://janrs.com/2023/03/%e5%9c%a8kubernetes%e4%b8%8a%e4%bd%bf%e7%94%a8jaeger%e7%9a%84%e5%88%86%e5%b8%83%e5%bc%8f%e8%bf%bd%e8%b8%aa%e5%9f%ba%e7%a1%80%e8%ae%be%e6%96%bd/
作为分布式系统(或任何系统)的一个组成部分,监测基础设施的重要性怎么强调都不过分。监控不仅要跟踪二进制的 "上升 "和 "下降 "模式,还要参与到复杂的系统行为中。监测基础设施的设置可以让人们深入了解性能、系统健康和长期的行为模式。
这篇文章介绍了监控基础设施的一个方面–分布式跟踪。
微服务架构中的可观察性
Kubernetes已经成为微服务基础设施和部署的事实上的协调器。这个生态系统非常丰富,是开源社区中发展最快的系统之一。带有Prometheus、ElasticSearch、Grafana、Envoy/Consul、Jaeger/Zipkin的监控基础设施构成了一个坚实的基础,以实现整个堆栈的指标、日志、仪表盘、服务发现和分布式跟踪。
分布式追踪
分布式跟踪能够捕获请求,并建立一个从用户请求到数百个服务之间互动的整个调用链的视图。它还能对应用程序的延迟(每个请求花了多长时间)进行检测,跟踪网络调用的生命周期(HTTP、RPC等),并通过获得瓶颈的可见性来确定性能问题。
下面的章节将介绍在Kubernetes设置中使用Jaeger对gRPC服务进行分布式跟踪。Jaeger Github Org有专门的Repo,用于Kubernetes中Jaeger的各种部署配置。这些都是很好的例子,我将尝试分解每个Jaeger组件和它的Kubernetes部署。
Jaeger组件
Jaeger是一个开源的分布式跟踪系统,实现了OpenTracing规范。Jaeger包括存储、可视化和过滤跟踪的组件。
架构图
Jaeger客户端
应用程序跟踪仪表从Jaeger客户端开始。下面的例子使用Jaeger Go库从环境变量初始化追踪器配置,并启用客户端指标。
package tracer
import (
"io"
"github.com/uber/jaeger-client-go/config"
jprom "github.com/uber/jaeger-lib/metrics/prometheus"
)
func NewTracer() (opentracing.Tracer, io.Closer, error) {
// load config from environment variables
cfg, _ := jaegercfg.FromEnv()
// 博客原来:janrs.com
// create tracer from config
return cfg.NewTracer(
config.Metrics(jprom.New()),
)
}
Go客户端使通过环境变量初始化Jaeger配置变得简单。一些需要设置的重要环境变量包括JAEGER_SERVICE_NAME、JAEGER_AGENT_HOST和JAEGER_AGENT_PORT。Jaeger Go客户端支持的环境变量的完整列表列在这里。
为了给你的gRPC微服务添加追踪功能,我们将使用gRPC中间件来启用gRPC服务器和客户端的追踪功能。 grpc-ecosystem/go-grpc-middleware有一个很棒的拦截器集合,包括支持OpenTracing提供者的服务器端和客户端的拦截器。
grpc_opentracing包暴露了opentracing拦截器,可以用任何opentracing.Tracer实现来初始化。在这里,我们用连锁的单项和流拦截器初始化了一个gRPC服务器。启用它将创建一个根serverSpan,对于每个服务器端的gRPC请求,追踪器将为服务中定义的每个RPC调用附加一个Span。
package grpc_server
import (
"github.com/opentracing/opentracing-go"
"github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
"github.com/grpc-ecosystem/go-grpc-middleware"
"google.golang.org/grpc"
"github.com/masroorhasan/myapp/tracer"
)
func NewServer() (*grpc.Server, error) {
// initialize tracer
tracer, closer, err := tracer.NewTracer()
defer closer.Close()
if err != nil {
return &grpc.Server{
}, err
}
opentracing.SetGlobalTracer(tracer)
// initialize grpc server with chained interceptors # janrs.com
s := grpc.NewServer(
grpc.StreamInterceptor(grpc_middleware.ChainStreamServer(
// add opentracing stream interceptor to chain
grpc_opentracing.StreamServerInterceptor(grpc_opentracing.WithTracer(tracer)),
)),
grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer(
// add opentracing unary interceptor to chain
grpc_opentracing.UnaryServerInterceptor(grpc_opentracing.WithTracer(tracer)),
)),
)
return s, nil
}
为了实现对gRPC服务的上游和下游请求的追踪,gRPC客户端也必须用客户端开放追踪拦截器进行初始化,如下例所示。
package grpc_client
import (
"github.com/opentracing/opentracing-go"
"github.com/grpc-ecosystem/go-grpc-middleware/tracing/opentracing"
"github.com/grpc-ecosystem/go-grpc-middleware"
"google.golang.org/grpc"
"github.com/masroorhasan/myapp/tracer"
)
func NewClientConn(address string) (*grpc.ClientConn, error) {
// initialize tracer #博文来源:janrs.com
tracer, closer, err := tracer.NewTracer()
defer closer.Close()