19

I'm trying to rewrite the path to the service while preserving the browser url with nginx ingress on kubernetes.

What I need is this:

  • http://example.com/path => http://service
  • http://example.com/path/bar => http://service/bar
  • http://example.com/path/file.css => http://service/file.css

That is, make the /path be the root (or some different url) in the upstream server.

From what I see here, this is done using a trailing slash on the proxy_pass, but nginx ingress doesn't seem to have this option.

Is this possible nginx ingress?

2 Answers 2

16

Is it Possible on Nginx Ingress?

  • Yes, In order to achieve it you can use rewrite-target.

  • It will create a capture group and send it to the appropriate service. Here is an Ingress example:

apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: "rewrite" annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: rules: - http: example.com paths: - path: /foo(/|$)(.*) backend: serviceName: echo-svc servicePort: 80 

In this ingress definition, any characters captured by (.*) will be assigned to the placeholder $2, which is then used as a parameter in the rewrite-target annotation.

This ingress will do the following:

  • Requests to /foo will be delivered to echo1-svc as /
  • Requests to /foo/bar will be delivered to echo1-svc as /bar
  • Requests to /foo/file.css will be delivered to echo-svc as /file.css
  • Nginx Ingress uses Path Priority:

In NGINX, regular expressions follow a first match policy. In order to enable more accurate path matching, ingress-nginx first orders the paths by descending length before writing them to the NGINX template as location blocks.


Example:

$ kubectl apply -f echo-ingress.yaml ingress.networking.k8s.io/echo-ingress created $ kubectl get ingress NAME HOSTS ADDRESS PORTS AGE echo-ingress mydomain.com 35.188.7.149 80 48s $ tail -n 1 /etc/hosts 35.188.7.149 mydomain.com $ curl mydomain.com/foo/bar {"path": "/bar", ...suppressed output... "os": {"hostname": "echo-deploy-764d5df7cf-6m5nz"} } $ curl mydomain.com/foo {"path": "/", "os": {"hostname": "echo-deploy-764d5df7cf-6m5nz"} } 

If you have any question let me know in the comments.

3
  • good answer. note that ingress-nginx has to be installed in the cluster to work. also this is interesting to know how to go about multipath : github.com/kubernetes/ingress-nginx/issues/6139 (thus making two ingress yaml files). Commented Feb 1, 2021 at 17:59
  • 2
    Missing pathType? Commented Sep 11, 2022 at 12:49
  • if we have diff services which have same "/' basepath, it is work? Commented Jul 28, 2023 at 12:25
0

In short: yes it is. Make sure not to confuse nginx-ingress (which you use as a label in your question ) and ingress-nginx, those are different. It works with ingress-nginx by installing it according to documentation. The provided answer from @Will R.O.F. shows how and the documentation can be found here: https://kubernetes.github.io/ingress-nginx/user-guide/ingress-path-matching/

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.