containerd 自 v1.6.0 起支持 OpenTelemetry 跟踪。
跟踪目前只针对 gRPC 调用。
从 containerd 守护进程发送跟踪结果
通过配置 io.containerd.tracing.processor.v1.otlp
插件。
containerd 守护进程可以将跟踪信息发送到指定的 OpenTelemetry 端点。
version = 2[plugins."io.containerd.tracing.processor.v1.otlp"]endpoint = "http://localhost:4318"
支持以下选项。
endpoint
接收 OpenTelemetry Protocol 的服务器地址。protocol
: OpenTelemetry 支持多种协议。
默认值为 “http/protobuf”。也支持 “grpc”。insecure
: 当协议为 "grpc "时禁用传输安全。默认值为 false。 "http/protobuf "始终使用端点提供的模式,该设置的值将被忽略。
此设置的值将被忽略。
func clientWithTrace() error {exp, err := otlptracehttp.New(ctx,otlptracehttp.WithEndpoint("localhost:4318"),otlptracehttp.WithInsecure(),)if err != nil {return err}res, err := resource.New(ctx, resource.WithAttributes(semconv.ServiceNameKey.String("CLIENT NAME"),))if err != nil {return err}provider := trace.NewTracerProvider(trace.WithSampler(trace.AlwaysSample()),trace.WithSpanProcessor(trace.NewSimpleSpanProcessor(exp)),trace.WithResource(res),)otel.SetTracerProvider(provider)otel.SetTextMapPropagator(propagation.TraceContext{})...dialOpts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials()),grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor()),grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()),}client, ctx, cancel, err := commands.NewClient(context, containerd.WithDialOpts(dialOpts))if err != nil {return err}defer cancel()ctx, span := tracing.StartSpan(ctx, "OPERATION NAME")defer span.End()...
}
跟踪上的采样率和服务名称可以通过
io.containerd.internal.v1.tracing
插件配置。
version = 2[plugins."io.containerd.internal.v1.tracing"]sampling_ratio = 1.0service_name = "containerd"
从 containerd 客户端发送跟踪信息
通过配置其底层 gRPC 客户端,containerd 的 Go 客户端可以向 OpenTelemetry 端点发送
跟踪到 OpenTelemetry 端点。
请注意,Go客户端的方法和 gRPC 调用不是 1:1。单个方法调用会发出多个 gRPC 调用。
func clientWithTrace() error {exp, err := otlptracehttp.New(ctx,otlptracehttp.WithEndpoint("localhost:4318"),otlptracehttp.WithInsecure(),)if err != nil {return err}res, err := resource.New(ctx, resource.WithAttributes(semconv.ServiceNameKey.String("CLIENT NAME"),))if err != nil {return err}provider := trace.NewTracerProvider(trace.WithSampler(trace.AlwaysSample()),trace.WithSpanProcessor(trace.NewSimpleSpanProcessor(exp)),trace.WithResource(res),)otel.SetTracerProvider(provider)otel.SetTextMapPropagator(propagation.TraceContext{})...dialOpts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials()),grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor()),grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()),}client, ctx, cancel, err := commands.NewClient(context, containerd.WithDialOpts(dialOpts))if err != nil {return err}defer cancel()ctx, span := tracing.StartSpan(ctx, "OPERATION NAME")defer span.End()...
}