Rewriting Kubernetes services in an Nginx ingress

5/15/2019

I have multiple APIs all listening on '/api' and a web front end listening on '/'.

Is there a way which I can write my ingress definition to rewrite the paths to something like the following?

/api/      -> /api/ on service1
/api2/api/ -> /api/ on service2
/api3/api/ -> /api/ on service3
/          -> /     on service4

I know I can change the APIs to listen to something else but don't want to do that. I know I can also just rewrite all to /api/ and let service3 act as the default but there may be other services which need routing elsewhere in the future.

I've heard that you could use multiple ingresses but I'm not sure how that would affect performance and if it's best practice to do so.

Also, is there any way to debug which route goes to which service?

Thanks, James

-- James B.
kubernetes
kubernetes-ingress
nginx-ingress
url-rewriting

2 Answers

5/15/2019

If you are using Nginx, you should be able to configure your Ingress for path matching like this:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
  - host: test.com
    http:
      paths:
      - path: (/api/.*)
        backend:
          serviceName: service1
          servicePort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress-2
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  rules:
  - host: test.com
    http:
      paths:
      - path: /api2/.*
        backend:
          serviceName: service2
          servicePort: 80
      - path: /api3/.*
        backend:
          serviceName: service3
          servicePort: 80
      - path: /.*
        backend:
          serviceName: service4
          servicePort: 80

More info

-- Rahman
Source: StackOverflow

5/15/2019

With help from @Rahman - see other answer. I've managed to get this to work with a single ingress.

I've had to post this as an additional answer because of the character limit.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-name
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  tls:
  - secretName: tls-secret
  rules:
  - host: localhost
    http:
      paths:
      - path: /(api/.*)
        backend:
          serviceName: service1
          servicePort: 80
      - path: /api2/(api.*)
        backend:
          serviceName: service2
          servicePort: 80
      - path: /api3/(api.*)
        backend:
          serviceName: service3
          servicePort: 80
      - path: /(.*)
        backend:
          serviceName: service4
          servicePort: 80

Just for context for anyone else stumbling upon this in the future, service 1 is a main API, service 2 and 3 are other APIs under another subdomain and service 4 is a web frontend.

-- James B.
Source: StackOverflow