Skip to main content
Metrics tell you something is slow. Logs tell you what happened in a single service. But when a request traverses multiple microservices and latency spikes, how do you find the specific service causing the delay? Distributed tracing solves this. OpenTelemetry (OTel) is the vendor-neutral instrumentation standard that applications use to emit traces. Jaeger is a popular tracing backend that receives, stores, indexes, and visualizes those traces. In short: OpenTelemetry controls how traces are generated and exported; Jaeger handles collection, indexing, and visualization. In this guide you’ll enable tracing for a missing service (the frontend) and inspect traces in the Jaeger UI.

What to check first: cluster workloads and Jaeger

Confirm Jaeger and your microservices are running:
Example output (for reference):
If you open the Jaeger UI you might notice some services (inventory, order, payment) appear in the service dropdown while frontend-svc is missing. The frontend pod can be running and receiving traffic but still not appear in Jaeger if it is not configured to emit traces. The application needs OpenTelemetry environment variables to know to produce and export tracing data.

How tracing is enabled (overview)

You will add OpenTelemetry environment variables to the frontend deployment so the application exports traces to the Jaeger collector using OTLP:
  • OTEL_SERVICE_NAME: name shown in Jaeger (e.g., frontend-svc)
  • OTEL_EXPORTER_OTLP_ENDPOINT: OTLP endpoint for the Jaeger collector (cluster DNS)
  • OTEL_EXPORTER_OTLP_PROTOCOL: grpc (4317) or http/protobuf (4318)
  • OTEL_TRACES_EXPORTER: typically otlp
These variables instruct the OpenTelemetry SDK in your app where and how to send traces.

Verify the Jaeger collector service and its ports

Before patching the deployment, confirm the collector service and exposed OTLP ports in the observability namespace:
Example output showing the jaeger-collector with OTLP ports:
Quick reference: gRPC uses port 4317; HTTP/protobuf uses 4318. Make sure the protocol you set in OTEL_EXPORTER_OTLP_PROTOCOL matches the port you target — mismatch is a frequent cause of missing traces.
Ensure the container name you patch matches the container name defined in the deployment. Patching the wrong container leaves the environment variables unapplied and the service will continue not to emit traces.

Patch the frontend deployment to emit traces

Create or edit a patch that injects the OpenTelemetry environment variables into the frontend container. Example patch snippet (YAML):
Apply the patch and wait for the rollout:
Notes:
  • If your cluster uses the collector in a different namespace, update the endpoint DNS accordingly (for example, jaeger-collector.<namespace>.svc.cluster.local).
  • Choose grpc and port 4317 together, or http/protobuf and port 4318 together.

Confirm traces in Jaeger

After the new pod starts with the environment variables applied:
  1. Open the Jaeger UI (see Jaeger docs: https://www.jaegertracing.io/docs/latest/getting-started/).
  2. Refresh the service dropdown — frontend-svc should now be available.
  3. Search for traces and inspect any trace to view the waterfall visualization.
The image shows a Jaeger UI trace visualization for a "GET" request to "frontend-svc" with multiple service calls, depicting the duration and sequence of various service operations over a timeline.
Interpretation tips:
  • The top-level span is the overall request (frontend); nested spans are downstream calls.
  • The widest span typically indicates where time is being spent — start investigating there (in the example, inventory-svc dominates latency).
  • In large systems, the waterfall view quickly highlights the slowest component and the sequence of calls.

Troubleshooting checklist

  • Confirm the four OpenTelemetry environment variables are present in the running pod:
    • kubectl describe pod <pod-name> -n workloads or kubectl exec -n workloads <pod> -- printenv | grep OTEL
  • Verify the OTLP endpoint points to the correct collector service DNS and port.
  • Ensure OTEL_EXPORTER_OTLP_PROTOCOL matches the endpoint port:
    • grpc → port 4317
    • http/protobuf → port 4318
  • Make sure OTEL_TRACES_EXPORTER is set to otlp.
  • Confirm you patched the correct deployment and container name.
If traces do not appear, the most common issues are: incorrect collector endpoint (DNS or port), protocol/port mismatch, or patching the wrong container name. Double-check those first.

Wrap-up and next steps

This walkthrough showed how to enable OpenTelemetry instrumentation for a Kubernetes-deployed service and visualize distributed traces in Jaeger. Try these steps in a lab or test cluster, and experiment with different OTLP protocols and collector configurations to understand how instrumented services communicate with Jaeger. Further reading:

Watch Video

Practice Lab