Member-only story

Sticky Sessions in Kubernetes

Zhimin Wen
3 min readMar 31, 2019

--

In 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 controller

The 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/v1beta1
kind: Ingress
metadata:
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 K3s

K3s comes by default with the Traefik controller. I will demonstrate the session affinity with it.

Create a sample app

Let'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)
}

--

--

Responses (3)