Skip to main content

Configure sticky sessions with istio

· 3 min read
Sumit Joshi
DevOps Engineer

associate client requests with same server that served first request in kubernetes

What are sticky sessions?

Stickey sessions or session stickiness is method of routing traffic to same server that served the first request. Using stickey sessions we can associate client with server using header or cookies. Different load balancers provides this features such as nginx, AWS ELB, etc. We will see how can se implement the same inside the kubernetes. We are going to use istio service mesh for this.

Implementation of sticky sessions in kubernetes using istio

To demonstrate this I have created a local kubernetes cluster using minikube, installed istio and I have created a test deployment which returns the pod ID in response. By default kubernetes svc load balances by routing requests to different pods of deployment like shown in example in below ->

➜  ~ kubectl get pods                                                                                                                                   (minikube/ping-pong)
NAME READY STATUS RESTARTS AGE
ping-1-bf6c8765f-6k8lz 2/2 Running 0 2m21s
ping-1-bf6c8765f-ds2f6 2/2 Running 0 2m24s
ping-1-bf6c8765f-dt7fn 2/2 Running 0 2m34s
ping-1-bf6c8765f-vdxwq 2/2 Running 0 2m34s
ping-2-569dd6c9dd-hll62 2/2 Running 0 2m36s
➜ ~ kubectl exec -it ping-2-569dd6c9dd-hll62 bash (minikube/ping-pong)
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
I have no name!@ping-2-569dd6c9dd-hll62:/app$ curl ping-1:3001
Hello, from ping-1-bf6c8765f-dt7fn
I have no name!@ping-2-569dd6c9dd-hll62:/app$ curl ping-1:3001
Hello, from ping-1-bf6c8765f-vdxwq
I have no name!@ping-2-569dd6c9dd-hll62:/app$ curl ping-1:3001
Hello, from ping-1-bf6c8765f-dt7fn
I have no name!@ping-2-569dd6c9dd-hll62:/app$ curl ping-1:3001
Hello, from ping-1-bf6c8765f-6k8lz
I have no name!@ping-2-569dd6c9dd-hll62:/app$ curl ping-1:3001
Hello, from ping-1-bf6c8765f-dt7fn
I have no name!@ping-2-569dd6c9dd-hll62:/app$ exit
exit

Now, create a virtual service and destination rule to apply sticky sessions

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ping-1-vs
spec:
http:
- route:
- destination:
host: ping-1.ping-pong.svc.cluster.local
port:
number: 3001
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: ping-1-dr
spec:
host: ping-1.ping-pong.svc.cluster.local
trafficPolicy:
loadBalancer:
consistentHash:
httpHeaderName: userId

After applying istio virtual service and deatination rule ->

➜  test-server kubectl get pods                                                                                                                         (minikube/ping-pong)
NAME READY STATUS RESTARTS AGE
ping-1-bf6c8765f-6k8lz 2/2 Running 0 11h
ping-1-bf6c8765f-ds2f6 2/2 Running 0 11h
ping-1-bf6c8765f-dt7fn 2/2 Running 0 11h
ping-1-bf6c8765f-vdxwq 2/2 Running 0 11h
ping-2-569dd6c9dd-hll62 2/2 Running 0 11h
➜ test-server kubectl exec -it ping-2-569dd6c9dd-hll62 bash (minikube/ping-pong)
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
I have no name!@ping-2-569dd6c9dd-hll62:/app$ curl -H 'userId:xyz' ping-1:3001
Hello, from ping-1-bf6c8765f-ds2f6
I have no name!@ping-2-569dd6c9dd-hll62:/app$ curl -H 'userId:xyz' ping-1:3001
Hello, from ping-1-bf6c8765f-ds2f6
I have no name!@ping-2-569dd6c9dd-hll62:/app$ curl -H 'userId:xyz' ping-1:3001
Hello, from ping-1-bf6c8765f-ds2f6
I have no name!@ping-2-569dd6c9dd-hll62:/app$ curl -H 'userId:xyz' ping-1:3001
Hello, from ping-1-bf6c8765f-ds2f6
I have no name!@ping-2-569dd6c9dd-hll62:/app$ curl -H 'userId:xyz' ping-1:3001
Hello, from ping-1-bf6c8765f-ds2f6
I have no name!@ping-2-569dd6c9dd-hll62:/app$ curl -H 'userId:abc' ping-1:3001
Hello, from ping-1-bf6c8765f-vdxwq
I have no name!@ping-2-569dd6c9dd-hll62:/app$ curl -H 'userId:abc' ping-1:3001
Hello, from ping-1-bf6c8765f-vdxwq
I have no name!@ping-2-569dd6c9dd-hll62:/app$ curl -H 'userId:abc' ping-1:3001
Hello, from ping-1-bf6c8765f-vdxwq
I have no name!@ping-2-569dd6c9dd-hll62:/app$

As you can see in above example requests with userId header are going to same pod for specific value of userId header.