Removing url prefixes in nginx Kubernetes Ingress


Getting an NGINX ingress running on a cluster is really easy, but the documentation did not immediately tell me how to strip the path prefix off at the ingress. I know I can use something like Istio to do this for me but for this specific project I didn’t need all of the additional complexity of that tool. So, how do I have nginx rewrite away the path prefix I use to target my services? It turns out it’s simple; although nowhere near as capable as Istio’s VirtualServices.

First, let’s define (possibly) the most simple ingress possible:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  namespace: my-namespace
spec:
  rules:
  - http:
      paths:
      - pathType: Prefix
        path: /api
        backend:
          service:
            name: my-api
            port:
              number: 8080

I think this is quite straightforward: I want anything with the prefix /api to get sent to a service named my-api running at port 8080. The drawback to this ingress definition is that now my service must run expecting the path to include /api. That’s not the end of the world I suppose, but I prefer my services to not care about things outside their control.

In my case I want NGINX to basically erase that path match before the request is routed to my service. I can do that with a little regular expression with a capture group for my path: /api(/|$)(.*) instead of /api and the rewrite-target annotation, like so:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  namespace: my-namespace
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
  - http:
      paths:
      - pathType: Prefix
        path: /api(/|$)(.*)
        backend:
          service:
            name: my-api
            port:
              number: 8080

That’s it! Now the /api prefix will be “erased” – Really I’m just not including it in our rewrite target. I’ve told NGINX to rewrite the path to / plus the second capture group (that’s $2), which is anything in the (.*) capture group. As an example requests coming in to /api/person will be rewritten to /person, /api and /api/ will be rewritten to /. To learn more about regular expression capture groups read here.

Sources:

  1. https://github.com/kubernetes/ingress-nginx/blob/main/docs/examples/rewrite/README.md
  2. https://kubernetes.io/docs/concepts/services-networking/ingress/

Leave a Reply

Your email address will not be published.