Pavol Loffay
Jun 7, 2018 · 3 min read

Modern service mesh architectures provides several new capabilities which significantly simplify application code by removing infrastructure related dependencies. In addition to that this architecture simplifies features like canary deployment by smart routing and much more.

In this blog post we are going to look at how distributed context propagation or baggage can be used by Istio routing rules.

Screenshot from Kiali — a service mesh observability tool

Imagine a scenario where you want to redirect all Safari users to a specific version of a service using theUser-Agent HTTP header. This is useful in canary deployments when a new version is rolled out for a specific subset of users. However the header is present only at the first service. If the routing rule is for a service lower in a call graph then the header has to be propagated through all intermediate services. This is a great use-case for distributed context propagation which is a feature of many tracing systems. We are going to look at OpenTracing using Jaeger implementation.

Distributed context propagation/baggage items are key:value string pairs associated with Span/SpanContext and are propagated in-band to all descendant spans within a trace.

If your service mesh is instrumented with OpenTracing then this feature should be available. On the other hand if your services are not instrumented then you can pass the User-Agent header along with other tracing headers, which unfortunately requires changes in all intermediate services.

Istio by default uses B3 propagation, which does not standardize baggage header. However baggage support can be configured in the Brave (Zipkin java client) library, and often uses the header formatbaggage-key:value. Jaeger implements a B3 codec that uses the same format for baggage. The current status of B3 baggage implementation can be found here.


Demo

Baggage can be set on the current active span as follows:

tracer.activeSpan().setBaggageItem("user-agent", userAgent);

This has to be done in the first service. The last thing we have to do is to define a routing rule for the baggage header. The following route definition forwards all requests containing baggage with entry user-agent:Safari.

apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
name: recommendation-safari
spec:
destination:
namespace: tutorial
name: recommendation
precedence: 2
match:
request:
headers:
baggage-user-agent:
regex: ".*Safari.*"
route:
- labels:
version: v2

Or following for newer Istio versions (after 0.8.0)

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: recommendation-safari
spec:
hosts:
- recommendation
http:
- match:
- headers:
baggage-user-agent:
regex: ".*Safari.*"
route:
- destination:
host: recommendation
subset: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: recommendation-destination
spec:
host: recommendation
subsets:
- name: v2
labels:
version: v2

Now all should be configured and Safari users should be forwarded to Recommendation service of version 2.


Video

The following video demonstrates Istio routing via OpenTracing baggage in redhat-developer-demos/istio-tutorial.


JaegerTracing

Open source distributed tracing platform at Cloud Native Computing Foundation (incubating). https://jaegertracing.io

Thanks to Gary Brown and Yuri Shkuro

Pavol Loffay

Written by

Software engineer at Red Hat

JaegerTracing

Open source distributed tracing platform at Cloud Native Computing Foundation (incubating). https://jaegertracing.io

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade