Search code examples
kuberneteskubernetes-ingress

Kubernetes ingress path rules longest match first not working


I have a deployment that has a single ingress definition that uses paths to direct requests for two services/pods on the backend

  • one pod is for api
  • one pod is for ui

The web address should only go to api if the URL contains /api/<anything>, otherwise everything else should go to ui.

My ingress setup looks like this

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp
  namespace: "myapp"
  labels:
    app.kubernetes.io/name: myapp
spec:
  ingressClassName: nginx
  rules:
    - host: myapp.dev
      http:
        paths:
          - path: /api/
            pathType: Prefix
            backend:
              service:
                name: myapp-api
                port:
                  name: http
          - path: /
            pathType: Prefix
            backend:
              service:
                name: mayapp-ui
                port:
                  name: http

If I test with https://myapp.dev/api/endpoint, the requests are sent round robin to both backend pods (I can see the requests in the logs in the ui pod).

I was under the impression that as /api/endpoint was in the path, it should always match on the longest rule and only ever send to the api pod?

Have I misunderstood how path matching works?

Many thanks


Solution

  • Your paths are not unique.

    You should add the rewrite-target under annotations:

    metadata:
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: "/$1"
      namespace: default
    

    and edit the paths names to map your cases:

     paths:
      - path: /(.*)
        pathType: Prefix
        backend:
          service:
            name: mayapp-ui
            port:
              name: http
      - path: /(api(?:/|$).*)
        pathType: Prefix
        backend:
          service:
            name: myapp-api
            port:
              name: http