I try to port an ASP.NET Core 1 application with Identity to Kubernetes. The login doesn't work and I got different errors like The anti-forgery token could not be decrypted. The problem is that I'm using a deployment with three replica sets so that further request were served by different pods that don't know about the anti-forgery token. Using replicas: 3
it works.
In the same question I found a sticky session documentation which seems a solution for my problem. The cookie name .AspNetCore.Identity.Application
is from my browser tools.
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: myapp-k8s-test
annotations:
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: ".AspNetCore.Identity.Application"
spec:
replicas: 3
template:
metadata:
labels:
app: myapp-k8s
spec:
containers:
- name: myapp-app
image: myreg/myapp:0.1
ports:
- containerPort: 80
env:
- name: "ASPNETCORE_ENVIRONMENT"
value: "Production"
imagePullSecrets:
- name: registrypullsecret
This doesn't work, either with or without leading dot at the cookie name. I also tried adding the following annotations
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/session-cookie-hash: sha1
What is required to allow sticky sessions on Kubernetes with ASP.NET Core?
Found out that I made two logical mistakes:
I assumed that Kubernetes will look into the cookie and create some mapping of cookie hashes to pods. But instead, another session is generated and append to our http header. nginx.ingress.kubernetes.io/session-cookie-name
is only the name of those generated cookie. So per default, it's not required to change them.
The annotations must be present on the ingress, NOT the deployment (stupid c&p mistake)
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: myapp-k8s-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-hash: sha1
spec:
tls:
- hosts:
- myapp-k8s.local
rules:
- host: myapp-k8s.local
http:
paths:
- path: /
backend:
serviceName: myapp-svc
servicePort: 80
This works as expected.