What are sticky sessions and how to configure them with Istio?
The idea behind sticky sessions is to route the requests for a particular session to the same endpoint that served the first request. That way to can associate a service instance with the caller, based on HTTP headers or cookies. You might want to use sticky sessions if your service is doing an expensive operation on first request, but later caching the value. That way, if the same user makes the request, the expensive operation will not be performed and value from the cache will be used.
var (
cache = make(map[string]bool)
)
func process(userHeaderValue string) {
if cache[userHeaderValue] {
return
}
cache[userHeaderValue] = true
time.Sleep(5 * time.Second)
}
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: sticky-svc
labels:
app: sticky-svc
version: v1
spec:
replicas: 5
selector:
matchLabels:
app: sticky-svc
version: v1
template:
metadata:
labels:
app: sticky-svc
version: v1
spec:
containers:
- image: learnistio/sticky-svc:1.0.0
imagePullPolicy: Always
name: svc
ports:
- containerPort: 8080
---
kind: Service
apiVersion: v1
metadata:
name: sticky-svc
labels:
app: sticky-svc
spec:
selector:
app: sticky-svc
ports:
- port: 8080
name: http
EOF
cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: sticky-svc
spec:
hosts:
- '*'
gateways:
- gateway
http:
- route:
- destination:
host: sticky-svc.default.svc.cluster.local
port:
number: 8080
EOF
$ curl -H "x-user: ricky" http://localhost/ping
Call was processed by host sticky-svc-689b4b7876-cv5t9 for user ricky and it took 5.0002721s
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: sticky-svc
spec:
host: sticky-service.default.svc.cluster.local
trafficPolicy:
loadBalancer:
simple: LEAST_CONN
consistentHash
. This option allows us to provide session affinity based on the HTTP headers (httpHeaderName
), cookies (httpCookie
) or other properties (source IP for example, using useSourceIp: true
setting).cat <<EOF | kubectl apply -f -
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: sticky-svc
spec:
host: sticky-svc.default.svc.cluster.local
trafficPolicy:
loadBalancer:
consistentHash:
httpHeaderName: x-user
EOF
kubectl scale deploy sticky-svc --replicas=0
kubectl scale deploy sticky-svc --replicas=5
$ curl -H "x-user: ricky" http://localhost/ping
Call was processed by host sticky-svc-689b4b7876-cq8hs for user ricky and it took 5.0003232s
$ curl -H "x-user: ricky" http://localhost/ping
Call was process by host sticky-svc-689b4b7876-cq8hs for user ricky and it took 47.4µs
$ curl -H "x-user: ricky" http://localhost/ping
Call was process by host sticky-svc-689b4b7876-cq8hs for user ricky and it took 53.7µs
$ curl -H "x-user: ricky" http://localhost/ping
Call was process by host sticky-svc-689b4b7876-cq8hs for user ricky and it took 46.1µs
$ curl -H "x-user: ricky" http://localhost/ping
Call was process by host sticky-svc-689b4b7876-cq8hs for user ricky and it took 76.5µs