The purpose of this blog post is to explain how Kubernetes Ingress working with Nginx Ingress Controller.
Recently we wanted to verify session affinity of sticky sessions with cookies, when we use Nginx multiple Ingress Controllers.
According to Nginx documentation, this should work since it use consistent hashing for session affinity.
This is a good , simple video tutorial about consistent hashing.
Let's try out from installation to testing this setup. Here I am using AWS EKS as Kubernetes provider.
Steps:
1. Install Nginx Ingress Controller
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.0/deploy/static/provider/aws/deploy.yaml
- Once installed increased the number of replicas at ngress-nginx-controller deployment to 2
2. Install back-end service and pods
service-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hostname-app
spec:
replicas: 2
selector:
matchLabels:
app: hostname-app
template:
metadata:
labels:
app: hostname-app
spec:
containers:
- name: hostname-app
image: k8s.gcr.io/serve_hostname:1.1
---
apiVersion: v1
kind: Service
metadata:
name: hostname-svc
spec:
ports:
- port: 80
targetPort: 9376
protocol: TCP
selector:
app: hostname-app
kubectl apply -f service-deployment.yaml
3. Configure Ingress Rules
ingress-rules.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-rules
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"
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
spec:
ingressClassName: nginx
rules:
- host: hostname.mydomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: hostname-svc
port:
number: 80
kubectl apply -f ingress-rules.yaml
4. Verify Installation
a. Now you can see two controller pods are running in ingress-nginx namespace.
b. Controllers are expose as AWS ELB to outer world.
c. Sample application, service , pods and ingress-rules created in default namespace.
5. Testing without sticky session cookie headers
- You can see we have to set http Host header as Ingress-Rules host configuration.
- Also you can see the pod host name in the response is not same every time.
- As you can see, both controllers received requests, which means Nginx-Controller-Service has load balanced the requests between two controller pods.
6. Let's do the same testing with sticky session cookie header
- As you can see , now response has same pod name, for every request.
- Also requests load balanced between each controllers.
7. Key Points
- Kubernetes Ingress is abstract service, real implementation is based on ingressClassName: nginx .
- What ever the changes made to Ingress-Rules will be reflected in Ingress-Controller Pods.
- If you don't use correct http Host header, you will get HTTP 404 response, which is the default response from Ingress-Inginx-Controller.
- Ingress-Controller will generate session cookie header for the first response based on pod name/ip (hash value), and it will included in subsequent request.
- So second request can be routed to previous same pod that initial request made.