K8S Ingress controller redirect to the wrong path

5/24/2021

I have an Nginx ingress controller running on one k8s namespace, and on another k8s namespace, I defined a pod, a service, and an ingress resource. this is the ingress resource definition:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  ingressClassName: general-internal
  rules:
  - host: example.com
    http:
      paths:
      - path: "/my-app(/|$)(.*)"
        backend:
          serviceName: my-app-svc
          servicePort: 443

now, when I access this link:

http://example.com/my-app/some-path/

then everything is ok because the "my-app-svc" knows the path "/some-path/" and returns a 200 response (the forwarding is to http://my-app-svc/some-path and that's great because my-app-svc doesn't and shouldn't know or care for the /my-app prefix that exists only for the nginx ingress controller so it will know to forward that request to "my-app-svc" internally).

but when I access this link (notice no "/" in the end):

http://example.com/my-app/some-path

I get a redirection response from the "my-app-svc" service, and the "Location" header contains "/some-path/", so the redirection is to:

http://example.com/some-path/

which does not lead to the "my-app-svc" service because it doesn't have the "/my-app" prefix.

If the Location header was "/my-app/some-path/" instead of "/some-path/" then everything was ok because the redirection would be to:

http://example.com/my-app/some-path/

which would give me the 200 response.

the question is, how can I do that the ingress controller will add a "my-app" prefix to the Location header when it returns the redirection response to the client?

Thanks

-- Ofir Yahav
kubernetes
kubernetes-ingress

1 Answer

5/26/2021

Thanks to my co-worker, we found a solution for the problem:

The solution is to add these annotations to the ingess resource:

nginx.ingress.kubernetes.io/proxy-redirect-from: /
nginx.ingress.kubernetes.io/proxy-redirect-to: /my-app/

meaning:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/proxy-redirect-from: /
    nginx.ingress.kubernetes.io/proxy-redirect-to: /my-app/
spec:
  ingressClassName: general-internal
  rules:
  - host: example.com
    http:
      paths:
      - path: "/my-app(/|$)(.*)"
        backend:
          serviceName: my-app-svc
          servicePort: 443

It seems that the annotations above check the "Location" header in the redirection response to the client, and replace the first / with /my-app/ and only after this change - the redirection response is sent to the client.

-- Ofir Yahav
Source: StackOverflow