Search code examples
cookieskubernetesgoogle-kubernetes-enginekubernetes-ingressaffinity

Problems configuring Ingress with cookie affinity


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


Solution

  • 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