网页
综合
更新时间 2026-08-11 11:00:00
A practical guide to solving when zero+zero=two in mesh observability | CNCF
自动蜘蛛
www.cncf.io
正文约 6000 字
Enroll your company as a CNCF End User and save more than $10K in training and conference costs
Posted on August 11, 2026 by Israel Blancas, Software Engineer at Coralogix and Jose Gomez-Selles, Product Lead at VictoriaMetrics
CNCF projects highlighted in this post
A Service Mesh like Istio, together with Kiali gives you a lot on day one.
You install the mesh, point Prometheus at it, and suddenly you have request rate, latency, error rate, and a fairly good picture of service-to-service traffic. You get this visibility into the applications without touching their code, which is often enough to answer the first round of questions during an incident.
Since you also heard that OpenTelemetry is the new standard and zero-code instrumentation will avoid the burden of polluting all your code, you go all-in for it.
This happy-path is covered by every tutorial and, sure, it works. The bit that actually comes for your weekend is not being able to connect the dots. When you open your tracing UI, you can see how your traces fall apart and the spans that should be together don’t seem to be part of the same transaction. Your traces are broken now.
And this is frustrating because you were trying to put together several pieces that work great on their own. After grinding the CNCF ecosystem by installing Istio, Prometheus, logs, instrumentation in the applications and third parties, you still ended up without having a coherent picture. The request is there, the spans are there but… something doesn’t add up because, in distributed systems, every request has its own story and it is actually quite sad that, after all this effort, the point is missed.
But let’s not lose faith (yet). Actually, now is when real OpenTelemetry comes to help. Throughout the following lines, we will show how, with a few tweaks, OpenTelemetry provides a clean way to connect all the pieces: application instrumentation, context propagation, and, most importantly, a Collector that can ingest telemetry from both the application and the mesh in different formats.
To illustrate this problem (and how to solve it), let’s imagine the following setup:
In this post, we will help readers to fix this integration problem by making the mesh and the applications automatic instrumentation contribute to the same trace.
Spoiler alert: The interesting part is not that traces break. The interesting part is why they break, and how OpenTelemetry gives you a practical, standardized fix.
Istio is very good at producing useful telemetry with almost no application changes. Once sidecars are injected, you get:
For platform teams, this is valuable immediately. At zero cost. You can see whether traffic is flowing, where errors are concentrated, and whether one hop in the request path is adding latency.
If your job is to operate the mesh, that is a pretty solid starting point.
But there is still a gap between “the network looks unhealthy” and “this exact user request failed because checkout called product-catalog twice and retried after a timeout”. That gap is usually closed by tracing. And tracing is where the integration details matter.
In the demo, the OpenTelemetry applications are already instrumented. Before Istio is installed, Jaeger shows complete end-to-end traces across the demo services.
By the time Istio sidecars are added and Envoy tracing is enabled, you still have telemetry, but it is no longer unified.
In Jaeger, you start seeing two versions of the same service:
The first comes from the OpenTelemetry SDK inside the application. The second comes from the Envoy sidecar. At first glance, this looks promising. More spans should mean more visibility. In practice, what you have is two unrelated trace trees for the same request.
This is the real integration problem. You do not need more telemetry. You need the telemetry you already have to work together.
The root of all evil the issue is propagation.
The applications in the OpenTelemetry Demo emit spans using the OpenTelemetry SDK and propagate context using the standard W3C Trace Context headers. Once Istio tracing is enabled, Envoy starts generating spans as well. If Envoy does not extract the same incoming context and continue the same trace, it creates a new root span.
Now you have two stories for the same request:
Both are useful. Neither is enough on its own.
This is also why OpenTelemetry matters here. It gives you the instrumentation layer inside the applications, the Collector as the integration point, and the flexibility to receive traffic in more than one format while still forwarding everything into the same backend.
There are two practical pieces to fix this.
The first is the Collector. Instead of treating the Collector as just another exporter target, treat it as the place where the mesh and the applications meet. In the demo, the applications already send OTLP data to the Collector. To integrate Envoy cleanly, the Collector also needs to be able to receive the tracing format that Envoy can use for context extraction in a compatible way.
The second is propagation. The application and the mesh have to agree on headers (i.e. talking the same language). If the application only emits one format and the mesh expects another, or handles it differently, you get split traces. In this case, the practical fix was to have the applications emit B3 in addition to tracecontext and baggage.
That combination is what makes the integration work:
That was the theory, let’s apply it.
Envoy’s built-in OTel tracer starts a brand-new root span for every request. It never reads the incoming W3C traceparent header. The OTel SDK inside each service continues forwarding its own traceparent independently, so the two trace streams never converge.
First, we need to make sure that Envoy exports all spans to the collector, by making sure the correct service and port are defined:
After that, the actual fix, from a user perspective, is to switch Envoy to its Zipkin tracer instead. Envoy’s Zipkin tracer does extract B3 tra
本页为82搜索生成的网页快照,内容来自站内索引;演示数据的原文链接仅作示例。