Sticky sessions or session affinity is a convenient strategy to keep subsequent requests always reaching the same pod.
Let's look at how it works by deploying a sample application with three replicas and one service.
In this scenario, requests directed to the service are load-balanced amongst the available replicas.
Let's deploy the ingress-nginx controller and create an Ingress manifest for the deployment.
In this case, the ingress controller skips the services and load balances the traffic directly to the pods.
While the two scenarios end up with the same outcome (i.e. requests are distributed to all replicas), there's a subtle (but essential) distinction: the Service operates on L4 (TCP/UDP), whereas the Ingress is L7 (HTTP).
Unlike the service, the Ingress controller can route traffic based on paths, headers, etc.
You can also use it to define weights (e.g. 20-80 traffic split) or sticky sessions (all requests from the same origin always land on the same pod).
The following Ingress implements sticky sessions for the nginx-ingress controller.
The ingress writes a cookie on your browser to keep track of what instance you visited.
There are two convenient settings for affinity:
- balanced — requests are redistributed if the deployment scales up.
- persistent — no matter what, the requests always stick to the same pod.
nginx-ingress can also be used for canary releases.
If you have two deployments and you wish to test a subset of the traffic for a newer version of that deployment, you can do so with a canary release (and impact a minimal amount of users).
In a canary release, each deployment has its own Ingress manifest.
However, one of those is labelled as a canary.
You can decide how the traffic is forwarded: for example, you could inspect a header or cookie.
In this example, all traffic labelled east-us is routed to the canary deployment.
You can also decide which fraction of the total traffic is routed to the canary with weights.
But if the header is omitted in a subsequent request, the user will return to see the previous deployment.
How can you fix that?
With sticky sessions!
You can combine canary releases and sticky sessions with ingress-nginx to progressively (and safely) roll out new deployments to your users.
It's important to remember that those types of canary releases are only possible for front-facing apps.
To roll out a canary release for internal microservices, you should look at alternatives (e.g. service mesh).
Is nginx-ingress the only option for sticky sessions and canary releases?
Not really, but the annotations might be different to other ingress controllers.
And finally, if you've enjoyed this thread, you might also like:
- The Kubernetes workshops that we run at Learnk8s.
- This collection of past threads.
- The Kubernetes newsletter I publish every week.
While authoring this post, I also found the following resources valuable: