ingress-nginx: Annotation for redirection created only once in the wrong place

NGINX Ingress controller version: Not sure

Kubernetes version (use kubectl version):

Client Version: version.Info{Major:“1”, Minor:“15”, GitVersion:“v1.15.3”, GitCommit:“2d3c76f9091b6bec110a5e63777c332469e0cba2”, GitTreeState:“clean”, BuildDate:“2019-08-19T11:13:54Z”, GoVersion:“go1.12.9”, Compiler:“gc”, Platform:“darwin/amd64”} Server Version: version.Info{Major:“1”, Minor:“18”, GitVersion:“v1.18.15”, GitCommit:“73dd5c840662bb066a146d0871216333181f4b64”, GitTreeState:“clean”, BuildDate:“2021-01-13T13:14:05Z”, GoVersion:“go1.13.15”, Compiler:“gc”, Platform:“linux/amd64”}

Environment:

  • Cloud provider or hardware configuration: Not sure, my IT did not give me this information.

What happened:

I have two web applications, foo and bar, each having their own deployment yaml files, that will be served from the same domain:

foo.yaml:

---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
    name: foo-ingress
    annotations:
        kubernetes.io/ingress.class: nginx
        nginx.ingress.kubernetes.io/proxy-read-timeout: "1800"
        nginx.ingress.kubernetes.io/proxy-send-timeout: "1800"
        nginx.ingress.kubernetes.io/rewrite-target: /$1 
        nginx.ingress.kubernetes.io/configuration-snippet: |
            rewrite ^(/apps/foo)$ $1/ redirect;
spec:
    rules:
    - host: myhost
      http:
        paths:
        - path: /apps/foo/(.*)
          backend:
            serviceName: foo-service
            servicePort: 8080
bar.yaml:

---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
    name: bar-ingress
    annotations:
        kubernetes.io/ingress.class: nginx
        nginx.ingress.kubernetes.io/proxy-read-timeout: "1800"
        nginx.ingress.kubernetes.io/proxy-send-timeout: "1800"
        nginx.ingress.kubernetes.io/rewrite-target: /$1 
        nginx.ingress.kubernetes.io/configuration-snippet: |
            rewrite ^(/apps/bar)$ $1/ redirect;
spec:
    rules:
    - host: myhost
      http:
        paths:
        - path: /apps/bar/(.*)
          backend:
            serviceName: foo-service
            servicePort: 8080

I applied each file with

kubectl apply -f foo.yaml
kubectl apply -f bar.yaml

The problem is that the redirection from /apps/foo to /apps/foo/ (adding the extra slash) works fine. The redirection from /apps/bar does not work. I get a 404.

I opened the generated nginx.conf in the ingress pod, and it’s a bit of a mess. I have the following (removed irrelevant parts):

    location ~* "^/apps/foo/(.*)" {
       rewrite ^(/apps/foo)$ $1/ redirect;
    }
    location ~* "^/apps/bar/(.*)" {
       rewrite ^(/apps/bar)$ $1/ redirect;
    }
    location ~* "^/" {
       ...
       rewrite ^(/apps/foo)$ $1/ redirect;
    }

As you can see, the redirection is added both under the / matching (where it works) and also in the more specific matching, where it makes no sense (as it will never get there, given that without a / the rule will not match).

It is unclear to me if it’s a bug, or if it’s the intended behavior that only one of these go in the catch all match. I did not explicitly configure it anywhere, so I suspect it’s created automatically.

What you expected to happen:

Instinctively, to have the redirection for both under the catch-all regexp, or for neither.

Anything else we need to know:

I am not sure it is a bug. It certainly feels wrong, but it might be expected behavior, although I don’t see the rationale at the moment

/kind bug

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 26 (15 by maintainers)

Most upvoted comments

@stefanoborini, very likely you can achieve the redirection you want with just the annotation and without the config snippet. But first things first so please add below info like requested ;

- Environment details like where is the cluster
- kubectl get nodes,ing -A -o wide
- kubectl get all -A -o wide | grep -i ingress
- kubectl version
- kubectl get all,nodes,ing -A -o wide
- kubectl -n <ingresscontrollernamespace> describe po <ingresscontrollerpodname>
- kubectl -n <ingresscontrollernamespace> describe svc <ingresscontrollerservicename>
- kubectl -n <appnamespace> get po,svc,ing -o wide
- kubectl -n <appnamespace> describe svc <svcname>
- kubectl -n <appnamespace> describe ing <ingressname>
- Your complete and exact precise curl command and its response
- kubectl -n <ingresscontrollernamespace> logs <ingresscontrollerpodname>
- Describe what you have in the pod in the context of what the redirection should result in
- Any other information that will help