Google Kubernetes engine inter-cluster session affinity(Sticky Session)

11/29/2019

The situation is that I have 2 applications: A and B that are in the same namespace of a cluster on gke. A is on 1 pod and B is on 2 pods.

Everytime a client communicates with our service. It connects first on A with websockets. A then sends http request to B. Since there is 2 pods of B, I would like to have session affinity between the Client from outside and with my application B so that everytime a client connects to A, it will always process his requests through the same pod of B.

Every session affinity option I saw are based on Ingress gateway or services, but since I'm already in the cluster, I don't need an Ingress.

I also saw that there is some services that provides support for http cookies. That would be good but it is always an external service like Nginx or Istio and since I'm working in a highly restricted development environment it is kind of a pain to add those service in the cluster.

Is there anything native to the gke that can provide me with http cookie session affinity or something similar?

-- Marc-Antoine Caron
google-cloud-platform
google-kubernetes-engine
kubernetes

3 Answers

11/29/2019

Everytime a client communicates with our service. It connects first on A with websockets. A then sends http request to B. Since there is 2 pods of B, I would like to have session affinity between the Client from outside and with my application B so that everytime a client connects to A, it will always process his requests through the same pod of B.

A communicate with B. A should connect to a specific instance of B depending on what end-user is connected to B.

This is sharding not session affinity but I understand what you mean. This means that your service B need a stable network identity.

Sharding by User identity

Service B need to be deployed as a StatefulSet to get a stable network identity. Then Service A can do sharding e.g. based on username or a range of IP-address or something, so requests for user X is always handled by instance Y.

With Service B deployed as StatefulSet, the instances will be named e.g. app-b-0 and app-b-1 so each instance can be addressed from Service A with a stable identity.

-- Jonas
Source: StackOverflow

11/30/2019

In a GKE cluster, when you create a Kubernetes Ingress object, the GKE ingress controller wakes up and creates a Google Cloud Platform HTTP(S) load balancer. The ingress controller configures the load balancer and also configures one or more backend services that are associated with the load balancer.

Beginning with GKE version 1.11.3-gke.18, you can use an Ingress to configure these properties of a backend service:

  • Timeout
  • Connection draining timeout
  • Session affinity

This will be useful for you and it's native of GKE Ingress.

-- Luis Javier Alvarez Rodriguez
Source: StackOverflow

11/29/2019

You could have set Client IP based session affinity, which happens at service level, like this one:

apiVersion: v1
kind: Service
metadata:
  name: svc-sa
spec:
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: http
  selector:
    app: nginx
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 3600

So, this service would route the request to the same backend (Pod), depending on the source IP address if the request.

You need to set a service anyways in front of the application B targeting the two pods. Now, the problem here is that your application A is acting as proxy, so all the requests will be considered from application A.

I know this is now a complete answer, but you might be able to do something in the application A, header wise (X-Forwarded-For), to bypass Pod A IP address, by the the IP address of the original request.

-- suren
Source: StackOverflow