Ingress-nginx: Session affinity does not work when no "rules" are defined

Created on 10 Apr 2019  路  7Comments  路  Source: kubernetes/ingress-nginx

Is this a request for help? (If yes, you should use our troubleshooting guide and community support channels, see https://kubernetes.io/docs/tasks/debug-application-cluster/troubleshooting/.):

What keywords did you search in NGINX Ingress controller issues before filing this one? (If you have found any duplicates, you should instead reply there.):


Is this a BUG REPORT or FEATURE REQUEST? (choose one): BUG REPORT

NGINX Ingress controller version: 0.24.0

Kubernetes version (use kubectl version): kubectl version
Client Version: version.Info{Major:"1", Minor:"13", GitVersion:"v1.13.3", GitCommit:"721bfa751924da8d1680787490c54b9179b1fed0", GitTreeState:"clean", BuildDate:"2019-02-04T04:49:22Z", GoVersion:"go1.11.5", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"12+", GitVersion:"v1.12.6-eks-d69f1b", GitCommit:"d69f1bf3669bf00b7f4a758e978e0e7a1e3a68f7", GitTreeState:"clean", BuildDate:"2019-02-28T20:26:10Z", GoVersion:"go1.10.8", Compiler:"gc", Platform:"linux/amd64"}

Environment:

  • Cloud provider or hardware configuration: AWS EKS
  • OS (e.g. from /etc/os-release): Ubuntu 18.04
  • Kernel (e.g. uname -a): Linux ip-10-0-1-248 4.15.0-1032-aws #34-Ubuntu SMP Thu Jan 17 15:18:09 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
  • Install tools:
  • Others:

What happened:

It appears that session affinity cookies are not sent to default backends if they do not appear in a "rule" section. Example:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: app
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/affinity: cookie
    nginx.ingress.kubernetes.io/session-cookie-path: "*"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
    nginx.ingress.kubernetes.io/session-cookie-name: "INGRESSCOOKIE"
spec:
  backend:
    serviceName: app
    servicePort: 80
  tls:
  - hosts:
    - "*.example.com"
    - example.com
    - "*.example.run"
    - example.run
    secretName: example-com-ssl

Requests to example.com will not receive the INGRESSCOOKIE headers.

If I add rule definitions, which in my mind should be "default" rules, eg:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: app
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/affinity: cookie
    nginx.ingress.kubernetes.io/session-cookie-path: "*"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
    nginx.ingress.kubernetes.io/session-cookie-name: "INGRESSCOOKIE"
spec:
  backend:
    serviceName: app
    servicePort: 80
  tls:
  - hosts:
    - "*.example.com"
    - example.com
    - "*.example.run"
    - example.run
    secretName: example-com-ssl
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              serviceName: app
              servicePort: 80
            path: /

Now requests receive the proper set-cookie header. I would imagine that because this rule is essentially default: (ie: other than the cookie appearing, there is no functional difference between having the [hostname] "/" -> [default backend] rule and not having it, since it uses the default backend anyways), it should behave the same way with or without a rules section.

I could be wrong, but this doesn't seem correct, and particularly when I have a large handful of domains that land on the same service, this incurs a ton of duplication of rules which ought to be satisfied by the default backend.

What you expected to happen:

I expect a "default backend" with valid Hosts to behave the same as when they're listed in "empty" rules. I expected INGRESSCOOKIE for all domains (example.com, *.example.com, example.run, *.example.run) to respond with the set-cookie header.

How to reproduce it (as minimally and precisely as possible):

Create an Nginx ingress as defined above, minimally:

spec:
  backend:
    serviceName: app
    servicePort: 80
  tls:
  - hosts:
    - "example.com"

This should behave the same as:

spec:
  backend:
    serviceName: app
    servicePort: 80
  tls:
  - hosts:
    - "example.com"
  rules:
    - host: example.com
      http:
        paths:
          - backend:
              serviceName: app
              servicePort: 80
            path: /

I suppose this is possibly just a misunderstanding of how Nginx ingress controller is behaving re: creating server blocks for me, and so I would be fine with this issue being resolved by a documentation update if this behavior is intentional.

Anything else we need to know:

Nginx ingress controller is excellent! Extremely satisfied so far, and looking forward to contributing when I have some spare time! Thank you very much, and please let me know if I can do anything to help recreate this bug!

lifecyclrotten

Most helpful comment

We got same issue, affinity cookie isn't set for host defined through server-alias annotation. Ingress definition:
```apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: internal-nginx
nginx.ingress.kubernetes.io/affinity: cookie
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
nginx.ingress.kubernetes.io/server-alias: management.example.com
creationTimestamp: 2019-06-05T10:13:44Z
generation: 1
labels:
app.kubernetes.io/instance: management-ingress
app.kubernetes.io/managed-by: Tiller
name: management-ingress
spec:
rules:

  • host: internal-management.example.com
    http:
    paths:

    • backend:

      serviceName: management

      servicePort: 443

      path: /

      tls:

  • hosts:

    • internal-management.example.com

      secretName: wildcard.example.com

      status:

      loadBalancer:

      ingress:

    • ip: 172.21.15.193```

```curl -I https://management.example.com
HTTP/2 200
server: nginx/1.15.10
date: Mon, 10 Jun 2019 07:18:06 GMT
content-type: text/html;charset=UTF-8
vary: Accept-Encoding
content-language: en
cache-control: s-maxage=600
expires: Mon, 10 Jun 2019 07:18:03 GMT
vary: X-LANG-SET,Accept-Encoding
strict-transport-security: max-age=15724800; includeSubDomains

curl -I https://internal-management.example.com
HTTP/2 200
server: nginx/1.15.10
date: Mon, 10 Jun 2019 07:19:04 GMT
content-type: text/html;charset=UTF-8
vary: Accept-Encoding
set-cookie: INGRESSCOOKIE=1560151143.493.45.49544; Path=/; Secure; HttpOnly
content-language: en
cache-control: s-maxage=600
expires: Mon, 10 Jun 2019 07:19:03 GMT
vary: X-LANG-SET,Accept-Encoding
strict-transport-security: max-age=15724800; includeSubDomains```

All 7 comments

I too have just come across this problem which is causing issues for us. In our case though we have the domains defined as aliases under nginx.ingress.kubernetes.io/server-alias and it has the same behavior as you mentioned above. Only when we add it as a rule does it fix the issue

An example
```apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: web
namespace: web
annotations:
kubernetes.io/ingress.class: nginx-web
nginx.ingress.kubernetes.io/server-alias: web.myapp.com
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "route"
nginx.ingress.kubernetes.io/session-cookie-hash: "sha1"
nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"
spec:
rules:

  • host: web.k8s.myapp.com
    http:
    paths:

    • backend:

      serviceName: web

      servicePort: 80

      ```

In the above example, the affinity cookie route will only be set when making requests to web.k8s.myapp.com and not web.myapp.com

We got same issue, affinity cookie isn't set for host defined through server-alias annotation. Ingress definition:
```apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: internal-nginx
nginx.ingress.kubernetes.io/affinity: cookie
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
nginx.ingress.kubernetes.io/server-alias: management.example.com
creationTimestamp: 2019-06-05T10:13:44Z
generation: 1
labels:
app.kubernetes.io/instance: management-ingress
app.kubernetes.io/managed-by: Tiller
name: management-ingress
spec:
rules:

  • host: internal-management.example.com
    http:
    paths:

    • backend:

      serviceName: management

      servicePort: 443

      path: /

      tls:

  • hosts:

    • internal-management.example.com

      secretName: wildcard.example.com

      status:

      loadBalancer:

      ingress:

    • ip: 172.21.15.193```

```curl -I https://management.example.com
HTTP/2 200
server: nginx/1.15.10
date: Mon, 10 Jun 2019 07:18:06 GMT
content-type: text/html;charset=UTF-8
vary: Accept-Encoding
content-language: en
cache-control: s-maxage=600
expires: Mon, 10 Jun 2019 07:18:03 GMT
vary: X-LANG-SET,Accept-Encoding
strict-transport-security: max-age=15724800; includeSubDomains

curl -I https://internal-management.example.com
HTTP/2 200
server: nginx/1.15.10
date: Mon, 10 Jun 2019 07:19:04 GMT
content-type: text/html;charset=UTF-8
vary: Accept-Encoding
set-cookie: INGRESSCOOKIE=1560151143.493.45.49544; Path=/; Secure; HttpOnly
content-language: en
cache-control: s-maxage=600
expires: Mon, 10 Jun 2019 07:19:03 GMT
vary: X-LANG-SET,Accept-Encoding
strict-transport-security: max-age=15724800; includeSubDomains```

Same issue here that we set wild card domain matching in server-alias, but the session affinity only works on those domains appear in spec.rules.[n].host

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle stale

Stale issues rot after 30d of inactivity.
Mark the issue as fresh with /remove-lifecycle rotten.
Rotten issues close after an additional 30d of inactivity.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle rotten

Rotten issues close after 30d of inactivity.
Reopen the issue with /reopen.
Mark the issue as fresh with /remove-lifecycle rotten.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/close

@fejta-bot: Closing this issue.

In response to this:

Rotten issues close after 30d of inactivity.
Reopen the issue with /reopen.
Mark the issue as fresh with /remove-lifecycle rotten.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/close

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

natemurthy picture natemurthy  路  3Comments

oilbeater picture oilbeater  路  3Comments

whereisaaron picture whereisaaron  路  3Comments

geek876 picture geek876  路  3Comments

yuyang0 picture yuyang0  路  3Comments