Skip to content


# Sticky sessions

This example demonstrates how to achieve session affinity using cookies.

## Deployment

Session affinity can be configured using the following annotations:

Name | Description | Value
--- | --- | ---
nginx.ingress.kubernetes.io/affinity | Type of the affinity, set this to `cookie` to enable session affinity | string (NGINX only supports `cookie`)
nginx.ingress.kubernetes.io/session-cookie-name | Name of the cookie that will be created | string (defaults to `INGRESSCOOKIE`)
nginx.ingress.kubernetes.io/session-cookie-path | Path that will be set on the cookie (required if your Ingress paths use regular expressions) | string (defaults to the currently matched path)
nginx.ingress.kubernetes.io/session-cookie-max-age | Time until the cookie expires, corresponds to the `Max-Age` cookie directive | number of seconds
nginx.ingress.kubernetes.io/session-cookie-expires | Legacy version of the previous annotation for compatibility with older browsers, generates an `Expires` cookie directive by adding the seconds to the current date | number of seconds

You can create the example Ingress to test this:

    kubectl create -f ingress.yaml

## Validation

You can confirm that the Ingress works:

    $ kubectl describe ing nginx-test
    Name:           nginx-test
    Namespace:      default
    Address:
    Default backend:    default-http-backend:80 (10.180.0.4:8080,10.240.0.2:8080)
    Rules:
      Host                          Path    Backends
      ----                          ----    --------
      stickyingress.example.com
                                    /        nginx-service:80 (<none>)
    Annotations:
      affinity: cookie
      session-cookie-name:      INGRESSCOOKIE
      session-cookie-expires: 172800
      session-cookie-max-age: 172800
    Events:
      FirstSeen LastSeen    Count   From                SubObjectPath   Type        Reason  Message
      --------- --------    -----   ----                -------------   --------    ------  -------
      7s        7s      1   {nginx-ingress-controller }         Normal      CREATE  default/nginx-test

    $ curl -I http://stickyingress.example.com
    HTTP/1.1 200 OK
    Server: nginx/1.11.9
    Date: Fri, 10 Feb 2017 14:11:12 GMT
    Content-Type: text/html
    Content-Length: 612
    Connection: keep-alive
    Set-Cookie: INGRESSCOOKIE=a9907b79b248140b56bb13723f72b67697baac3d; Expires=Sun, 12-Feb-17 14:11:12 GMT; Max-Age=172800; Path=/; HttpOnly
    Last-Modified: Tue, 24 Jan 2017 14:02:19 GMT
    ETag: "58875e6b-264"
    Accept-Ranges: bytes

In the example above, you can see that the response contains a `Set-Cookie` header with the settings we have defined. This cookie is created by NGINX, it contains a randomly generated key corresponding to the upstream used for that request (selected using consistent hashing) and has an `Expires` directive. If the user changes this cookie, NGINX creates a new one and redirects the user to another upstream.

If the backend pool grows NGINX will keep sending the requests through the same server of the first request, even if it's overloaded.

When the backend server is removed, the requests are re-routed to another upstream server. This does not require the cookie to be updated because the key's consistent hash will change.

When you have a Service pointing to more than one Ingress, with only one containing affinity configuration, the first created Ingress will be used. This means that you can face the situation that you've configured session affinity on one Ingress and it doesn't work because the Service is pointing to another Ingress that doesn't configure this.