Sticky Sessions in Kubernetes

Sticky Sessions in KubernetesZhimin WenBlockedUnblockFollowFollowingMar 31In the migration journey to the cloud, not all apps are stateless immediately.

Sometimes, we still need the session affinity or sticky session for the request to come to the same pod replica that was responding to the request before.

Nginx ingress controllerThe kubernetes ingress controllers, such as Nginx ingress controller already has these requirement considered and implemented.

The ingress controller replies the response with a Set-Cookie header to the first request.

The value of the cookie will map to a specific pod replica.

When the subsequent request come back again, the client browser will attach the cookie and the ingress controller is therefore able to route the traffic to the same pod replica.

The configuration is normally achieved with annotations.

See the following example from https://kubernetes.

github.

io/ingress-nginx/examples/affinity/cookie/ingress.

yaml.

apiVersion: extensions/v1beta1kind: Ingressmetadata: name: nginx-test annotations: nginx.

ingress.

kubernetes.

io/affinity: "cookie" nginx.

ingress.

kubernetes.

io/session-cookie-name: "route" nginx.

ingress.

kubernetes.

io/session-cookie-expires: "172800" nginx.

ingress.

kubernetes.

io/session-cookie-max-age: "172800"spec: rules: – host: stickyingress.

example.

com http: paths: – backend: serviceName: http-svc servicePort: 80 path: /By setting the annotations in the ingress object, we can make sure the subsequent request will still be served by the same pod.

Traefik ingress controller on K3sK3s comes by default with the Traefik controller.

I will demonstrate the session affinity with it.

Create a sample appLet's have a toy golang app, whose HTTP handler will just print out the hostname.

package mainimport ( "fmt" "net/http" "os")func greet(w http.

ResponseWriter, r *http.

Request) { fmt.

Fprintf(w, "You are served by host:%s.

", os.

Getenv("HOSTNAME"))}func main() { http.

HandleFunc("/", greet) http.

ListenAndServe(":8080", nil)}Compile it, build a Docker image and push into docker hub.

Attached is the DockerfileFROM alpineRUN mkdir -p /myappADD myapp /myappRUN chmod a+rx /myapp/myappCMD ["/myapp/myapp"]Deploy into K3sNothing special, just export the KUBECONFIG, you have the familiar kubectl the same as K8s.

export KUBECONFIG=~/k3s/k3s.

yamlApply the following sample Kubernetes object files, including ingress, service, and deployment.

—apiVersion: extensions/v1beta1kind: Ingressmetadata: annotations: kubernetes.

io/ingress.

class: traefik labels: app: session-affinity name: session-affinityspec: rules: – host: sess.

192.

168.

64.

5.

nip.

io http: paths: – path: / backend: serviceName: session-affinity servicePort: 8080—apiVersion: v1kind: Servicemetadata: name: session-affinity labels: app: session-affinity annotations: traefik.

ingress.

kubernetes.

io/affinity: "true" traefik.

ingress.

kubernetes.

io/session-cookie-name: "sticky"spec: type: NodePort ports: – port: 8080 targetPort: 8080 protocol: TCP name: http selector: app: session-affinity-demo—apiVersion: apps/v1kind: Deploymentmetadata: name: session-affinity-demo labels: app: session-affinity-demospec: replicas: 3 selector: matchLabels: app: session-affinity-demo template: metadata: labels: app: session-affinity-demo spec: containers: – name: session-affinity-demo image: zhiminwen/session-sticky:v1.

0In the ingress object, we instruct it in the annotations to use the Traefik ingress controller.

Note the sticky session in Traefik is defined in the Service object with the annotation, which is different comparing with the Nginx ingress controller.

Instead of a random cookie name, we define it as “sticky”.

We have 3 replicas running.

TestingLaunch the browser, go to the expected Ingress host, sess.

192.

168.

64.

5.

nip.

ioYou can see the greeting message of the hostname.

Note upon the very first response, the Set-Cookie is set in the response header.

Refresh the browser, you will see the request is served by the same pod.

This was because of the Cookie which was set by the browser.

.. More details

Leave a Reply