How to rewrite url to backend while preserving browser url in nginx ingress?
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 therewrite-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.
Related videos on Youtube
Natan
Updated on September 18, 2022Comments
-
Natan over 1 year
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?
-
-
Vincent Gerris over 3 yearsgood 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).