2

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

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.

1
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/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.