Understanding Sticky Sessions in Kubernetes: A Guide for Stateful Applications

Yaswanth RYaswanth R
4 min read

Introduction

In Kubernetes, applications are typically designed to be stateless, meaning any pod can handle a request without requiring prior knowledge of a user session. However, certain use cases, such as authentication, shopping carts, or dashboards, require user sessions to be maintained across multiple requests. This is where sticky sessions (session affinity) come into play.

Sticky sessions ensure that a user's requests are consistently routed to the same backend pod, preserving session data stored in memory. In this blog, we’ll explore how sticky sessions work in Kubernetes, the different methods to implement them, and their advantages and trade-offs.


Why Sticky Sessions?

By default, Kubernetes load balances requests across all available pods in a round-robin or random manner. This can cause problems for applications that store session data in memory, as a user's subsequent requests might be routed to different pods, leading to session loss.

With sticky sessions, user requests are directed to the same pod for the duration of the session, ensuring continuity.

When to Use Sticky Sessions

✔️ When your application stores session data in memory and needs consistency.
✔️ For applications that require authentication tokens or user context to remain persistent.
✔️ When migrating legacy applications that rely on sticky sessions.

When Not to Use Sticky Sessions

❌ If your application is stateless (no in-memory session dependency).
❌ If you use external session storage like Redis, which allows any pod to access the same session data.
❌ When horizontal scaling needs to be maximized without pod affinity constraints.


Methods to Implement Sticky Sessions in Kubernetes

There are two common ways to enable sticky sessions in Kubernetes:

1. Service-Level Sticky Sessions (ClientIP Affinity)

Kubernetes Service supports sessionAffinity: ClientIP, which ensures that requests from the same client IP go to the same pod.

📌 Example Service YAML with ClientIP Affinity:

apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  selector:
    app: myapp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800  # Sticky session duration

🔹 Pros: Simple to implement, built-in Kubernetes feature.
🔹 Cons: Does not work well if clients use NAT (Network Address Translation) or proxies that change their IP addresses.


If you are using an Ingress Controller (e.g., NGINX Ingress), you can enable cookie-based sticky sessions, which are more reliable than ClientIP-based affinity.

📌 Example Ingress YAML with Cookie-Based Sticky Sessions:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  annotations:
    nginx.ingress.kubernetes.io/affinity: "cookie"
    nginx.ingress.kubernetes.io/session-cookie-name: "route"
    nginx.ingress.kubernetes.io/session-cookie-hash: "sha1"
spec:
  ingressClassName: nginx
  rules:
    - host: myapp.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: myapp-service
                port:
                  number: 80

🔹 Pros: Works regardless of client IP, supports modern application deployments.
🔹 Cons: Requires an Ingress Controller and proper configuration.


Handling Pod Failures in Sticky Sessions

A key challenge with sticky sessions is handling pod failures. What happens if the "stuck" pod goes down?

  • With Service (ClientIP) Sticky Sessions

    • The session remains tied to the failed pod until the timeoutSeconds expires.

    • The user might experience failures until the session is reassigned.

  • With Ingress (Cookie-Based) Sticky Sessions

    • The Ingress Controller detects pod failures using health checks.

    • It automatically routes requests to another healthy pod, ensuring minimal disruption.

Enhancing Reliability with Probes & Retries

To make sticky sessions more resilient, you can configure liveness and readiness probes in your Deployment YAML to ensure that Kubernetes stops sending traffic to unhealthy pods.

📌 Example Deployment YAML with Health Checks:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myregistry.com/myapp:latest
        ports:
        - containerPort: 8080
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 3

Additionally, adding retry settings in the Ingress ensures that if a pod fails, the request is retried on another healthy pod.

📌 Ingress YAML with Retry Settings:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp-ingress
  annotations:
    nginx.ingress.kubernetes.io/proxy-next-upstream: "error timeout http_502 http_503 http_504"
    nginx.ingress.kubernetes.io/proxy-next-upstream-tries: "3"

Best Practices for Sticky Sessions in Kubernetes

Use cookie-based sticky sessions with Ingress instead of ClientIP-based affinity whenever possible.
Ensure health checks (liveness & readiness probes) are properly configured.
Consider using an external session store (e.g., Redis) instead of relying on sticky sessions for long-term scalability.
Use retry mechanisms in Ingress to handle pod failures gracefully.
Monitor logs and metrics to track how sticky sessions are performing in production.


Conclusion

Sticky sessions in Kubernetes can be a useful technique for maintaining session continuity in applications that store session data in memory. While Service-level (ClientIP) sticky sessions provide a basic approach, using Ingress-based cookie affinity is generally the better choice for modern applications. However, for true scalability and resilience, it's best to externalize session storage using Redis or another distributed session management system.

By implementing proper health checks, retry strategies, and monitoring, you can ensure that sticky sessions work reliably in your Kubernetes environment.

🚀 Ready to scale your Kubernetes application? Try out these techniques and optimize your deployments today! 🚀


0
Subscribe to my newsletter

Read articles from Yaswanth R directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Yaswanth R
Yaswanth R

As a final-year Computer Science and Engineering student at Sri Eshwar College of Engineering, I am deeply passionate about technology and innovation. My academic journey has been marked by consistent performance, achieving a CGPA of 8.1, and by actively participating in hackathons and expos, including securing 1st place in the MiniProject Expo Hackathon. Beyond academics, I have a strong interest in cloud computing, DevOps methodologies, and automation tools. I have honed my skills through internships and real-world projects, including my role as a DevOps Intern at Mahat Labs Pvt. Ltd. During this experience, I automated CI/CD pipelines for .NET and Flutter applications using GitLab CI/CD, containerized microservices with Docker, and deployed them to Kubernetes clusters built with kubeadm. I also integrated SonarQube into CI/CD workflows for code quality analysis and developed custom monitoring scripts to enhance infrastructure reliability. My hands-on experience extends to tools like Jenkins, Proxmox, and AWS, where I have successfully modernized deployment workflows and streamlined software delivery processes.