Traffic shaping with Istio and Kubernetes
Tags: kubernetes, devops
Published: 2023-05-15 12:51:41

You can roll out an app only to a subset of your users in Kubernetes using canary releases with Istio, Kiali and the Gateway API.

_Let's start by looking at an example._

The current cluster has three apps:

1. A backend that exposes an API at version v1.
1. Another app on version v2.
1. A frontend component that consumes the API.

![Two apps deployed in a Kubernetes cluster](https://res.cloudinary.com/learnk8s/image/upload/v1684120791/threads/split-2_wlekqx.png)

Ideally, the frontend should consume 80% of requests from v1 and only 20% from v2.

_But how?_

You can use a Service Mesh for that.

![Splitting traffic with a Service mesh](https://res.cloudinary.com/learnk8s/image/upload/v1684120790/threads/split-3_xppkyj.png)

As soon as you install the service mesh, **each pod in the cluster gains an extra container.**

The container proxies all the outgoing and incoming requests.

![An Envoy proxies intercepting all outgoing and incoming requests](https://res.cloudinary.com/learnk8s/image/upload/v1684120791/threads/split-4_apbni5.png)

**The proxy is automatically injected using a mutating webhook.**

Before the pod is stored in etcd, the YAML definition is modified, and the proxy is injected.

![A mutating webhook automatically injects the proxy in the pod](https://res.cloudinary.com/learnk8s/image/upload/v1684120790/threads/split-5_m8d2oo.png)

A service mesh is helpful because you can:

- Monitor metrics.
- Trace dependencies between components.
- Decide traffic splits.

![Why you might want to use use a service mesh](https://res.cloudinary.com/learnk8s/image/upload/v1684120791/threads/split-6_e737l1.png)

I generated some traffic to test it and used Kiali to trace it.

**It automatically mapped all the components and the direction of the traffic.**

All without any hints from my side!

_What about the canary release though?_

![Mapping microservices with Kiali](https://res.cloudinary.com/learnk8s/image/upload/v1684120790/threads/split-7_temteb.png)

You can use a service mesh to fine-tune how much traffic each app consumes.

To test it, I created an 80-20 split between the two backends.

In this example, I'm using an HTTPRoute:

![HTTPRoute Custom Resource Definition](https://res.cloudinary.com/learnk8s/image/upload/v1684120791/threads/split-8_buw5n6.png)

[HTTPRoute is an object part of the Gateway API](https://gateway-api.sigs.k8s.io/api-types/httproute/) that lets you gradually increase and decrease the traffic and which you can use to transition from an 80-20 split to 0-100.

![Demo of splitting traffic in Kubernetes](https://res.cloudinary.com/learnk8s/image/upload/v1684120809/threads/shifting-preview_i5vs5z.gif)

Service meshes can also:

1. Help you roll out shadow releases.
1. Encrypt intrapod traffic.
1. Mirror traffic between cluster.
1. Inspect and rewrite traffic.
1. Enforce policies.
1. Inject faults to test the resilience.

And more!

_Which one should you use?_

[At Learnk8s we've put together a spreadsheet to compare them.](https://docs.google.com/spreadsheets/d/1Bxf8VW9n-YyHeBiKdXt6zytOgw2cQlsDnK1gLUvsZ4A/edit#gid=907731238)

And finally, if you've enjoyed this thread, you might also like:

- [The Kubernetes workshops that we run at Learnk8s.](https://learnk8s.io/training)
- [This collection of past threads.](https://twitter.com/danielepolencic/status/1298543151901155330)
- [The Kubernetes newsletter I publish every week.](https://learnk8s.io/learn-kubernetes-weekly)