nginx-ingress sticky-session for websocket application

5/27/2019

I have a websocket .net application inside K8s cluster. I need to implement sticky session for the websocket using the nginx opensource.

I have read the documentation of nginx and kubernetes. https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md#session-affinity

It says we can use below configuration for sticky session:

nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "ingresscoookie"
nginx.ingress.kubernetes.io/session-cookie-hash: "sha1"
nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
nginx.ingress.kubernetes.io/session-cookie-max-age: "172800

but this doesnot seem to work. I have tried the example code provided by kubernetes here https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/affinity/cookie/ingress.yaml.

This works for me, so I believe cookie based session affinity does not seem to work for websockets.

On further digging the documentation it says that I can use IP hashing algorithm. so I tried using below annotation.

nginx.ingress.kubernetes.io/upstream-hash-by: "$remote_addr"

this also failed. The requests are still balanced using the default algorithm.

How can I achieve session persistence?

-- Madie
azure-kubernetes
nginx-ingress
sticky-session
websocket

1 Answer

11/6/2019

Stale post I know, but might help others. Did you remove/comment out the affinity and session annotations ?

This snippet works for me, but notably doesn't work if you've left the other annotations in (Like you, I couldn't get cookie based affinity to work - and I needed sticky sessions as antiforgery tokens were created locally to my webservices).

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hello-world-ingress
  namespace: nginx
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.org/ssl-services: "hello-world-svc"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/upstream-hash-by: $remote_addr
spec:
  tls:
    - hosts:
      - nginx.mydomain.co.uk
      secretName: tls-certificate
  rules:
  - host: nginx.mydomain.co.uk
    http:
      paths:
      - path: /web1(/|$)(.*)      
        backend:
          serviceName: hello-world-svc
          servicePort: 80
-- Antony Cook
Source: StackOverflow