0

I was looking for how to use cookie affinity in GKE, using Ingress for that.

I've found the following link to do it: https://cloud.google.com/kubernetes-engine/docs/how-to/configure-backend-service

I've created a yaml with the following:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-bsc-deployment
spec:
  selector:
    matchLabels:
      purpose: bsc-config-demo
  replicas: 3
  template:
    metadata:
      labels:
        purpose: bsc-config-demo
    spec:
      containers:
      - name: hello-app-container
        image: gcr.io/google-samples/hello-app:1.0
---
apiVersion: cloud.google.com/v1beta1
kind: BackendConfig
metadata:
  name: my-bsc-backendconfig
spec:
  timeoutSec: 40
  connectionDraining:
    drainingTimeoutSec: 60
  sessionAffinity:
    affinityType: "GENERATED_COOKIE"
    affinityCookieTtlSec: 50
---
apiVersion: v1
kind: Service
metadata:
  name: my-bsc-service
  labels:
    purpose: bsc-config-demo
  annotations:
    beta.cloud.google.com/backend-config: '{"ports": {"80":"my-bsc-backendconfig"}}'
spec:
  type: NodePort
  selector:
    purpose: bsc-config-demo
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-bsc-ingress
spec:
  rules:
  - http:
      paths:
      - path: /*
        backend:
          serviceName: my-bsc-service
          servicePort: 80
---

Everything seems to go well. When I inspect the created Ingress I see 2 backend services. One of them has the cookie configured, but the other doesn't.

If I create the deployment, and from GCP's console, create the Service and Ingress, only one backend service appears.

Somebody knows why using a yaml I get 2, but doing it from console I only get one?

Thanks in advance

Oscar

blue
  • 33
  • 3
  • Both, YAML definitions and the Console should make the same request at the end. So either there is something not "mapped" in the UI that is included in your YAML or the requests are different. Please share the steps to replicate it in the Console. – yyyyahir Sep 10 '19 at 16:33
  • Hi. What I do in the console is: - Choose the deployment and click Expose. I choose NodePort for the service. - Once the service is created, I select it and click on "Create Ingress" - There I choose the service created before as backend service and create the Ingress - Once the Ingress is created I select the backend service (there is only one, not two) and configure session affinity with a cookie – blue Sep 12 '19 at 07:19

2 Answers2

1

Your definition is good.

The reason you have two backend's is because your ingress does not define a default backend. GCE LB require a default backend so during LB creation, a second backend is added to the LB to act as the default (this backend does nothing but serve 404 responses). The default backend does not use the backendConfig.

This shouldn't be a problem, but if you want to ensure only your backend is used, define a default backend value in your ingress definition by adding the spec.backend:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-bsc-ingress
spec:
  backend:
    serviceName: my-bsc-service
    servicePort: 80
  rules:
  - http:
      paths:
      - path: /*
        backend:
          serviceName: my-bsc-service
          servicePort: 80

But, like I said, you don't NEED to define this, the additional backend won't really come into play and no sessions affinity is required (there is only a single pod anyway). If you are curious, the default backend pod in question is called l7-default-backend-[replicaSet_hash]-[pod_hash] in the kube-system namespace

Patrick W
  • 4,603
  • 1
  • 12
  • 26
  • That was exactly the problem. Once default backend service is set in the yaml, only one is created. Thanks!! – blue Sep 13 '19 at 07:49
0

You can enable the cookies on the ingress like

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-sticky
  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"

spec:
  rules:
  - host: ingress.example.com
    http:
      paths:
      - backend:
          serviceName: http-svc
          servicePort: 80
        path: /

You can create the service like :

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 80
  sessionAffinity: ClientIP

If you are using the traefik ingress instead of the nginx and deault GKe ingress you can write the service like this

apiVersion: v1
kind: Service
metadata:
  name: session-affinity
  labels:
    app: session-affinity
  annotations:
    traefik.ingress.kubernetes.io/affinity: "true"
    traefik.ingress.kubernetes.io/session-cookie-name: "sticky"
spec:
  type: NodePort
  ports:
  - port: 8080
    targetPort: 8080
    protocol: TCP
    name: http
  selector:
    app: session-affinity-demo
Harsh Manvar
  • 27,020
  • 6
  • 48
  • 102
  • Hi, I need to use "sessionAffinity: ClientIP" in the Service to handle the affinity with a cookie? I've tried without that line, and inspecting the Ingress object from GKE I see 2 backend services and both don't have cookie configured for session affinity – blue Sep 10 '19 at 11:43