GKE No load balancing between backends pod with session affinity(sticky sessions)

12/5/2019

I have 2 backend application running on the same cluster on gke. Applications A and B. A has 1 pod and B has 2 pods. A is exposed to the outside world and receives IP address that he then sends to B via http requests in the header.

B has a Kubernetes service object that is configured like that.

apiVersion: v1
kind: Service
metadata:
  name: svc-{{ .Values.component_name }}
  namespace: {{ include "namespace" .}}
spec:
  ports:
    - port: 80
      targetPort: {{.Values.app_port}}
      protocol: TCP
  selector:
    app: pod-{{ .Values.component_name }}
  type: ClusterIP

In that configuration, The http requests from A are equally balanced between the 2 pods of application B, but when I add sessionAffinity: ClientIP to the configuration, every http requests are sent to the same B pod even though I thought it should be a round robin type of interaction.

To be clear, I have the IP adress stored in the header X-Forwarded-For so the service should look at it to be sure to which B pod to send the request as the documentation says https://kubernetes.io/docs/concepts/services-networking/service/#ssl-support-on-aws

In my test I tried to create has much load has possible to one of the B pod to try to contact the second pod without any success. I made sure that I had different IPs in my headers and that it wasn't because some sort of proxy in my environment. The IPs were not previously used for test so it is not because of already existing stickiness.

I am stuck now because I don't know how to test it further and have been reading the doc and probably missing something. My guess was that sessionAffinity disable load balancing for ClusterIp type but this seems highly unlikely...

My questions are :

Is the comportment I am observing normal? What am I doing wrong?

This might help to understand if it is still unclear what I'm trying to say : https://stackoverflow.com/a/59109265/12298812

EDIT : I did test on the client upstream and I saw at least a little bit of the requests get to the second pod of B, but this load test was performed from the same IP for every request. So this time I should have seen only a pod get the traffic...

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

1 Answer

12/6/2019

The behaviour suggests that x-forward-for header is not respected by cluster-ip service.

To be sure I would suggest to load test from upstream client service which consumes the above service and see what kind of behaviour you get. Chances are you will see the same incorrect behaviour there which will affect scaling your service.

That said, using session affinity for internal service is highly unusual as client IP addresses do not vary as much. Session affinity limits scaling ability of your application. Typically you use memcached or redis as session store which is likely to be more scalable than session affinity based solutions.

-- Parth Mehta
Source: StackOverflow