I'm setting up a Kubernetes cluster which contains three applications, each running within their own respective pod and service. The web frontends of these applications should be accesible at ports 80, 9000 and 15672. There are also a number of Backend-APIs running in their own pods and services, which should be accesible at their respective ports. The cluster is accessed through a NGINX reverse proxy with the following ingress-definition:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
namespace: my-namespace
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
tls:
- hosts:
- myapp.com
secretName: my-certificat
rules:
- host: myapp.com
http:
paths:
- backend:
serviceName: my-service-1
servicePort: 8092
path: /api/someroute/(.*)
- backend:
serviceName: my-service-2
servicePort: 30003
path: /api/someotherroute/(.*)
- backend:
serviceName: my-other-frontend
servicePort: 9000
path: /other/(.*)
- backend:
serviceName: my-yetanother-frontend
servicePort: 15672
path: /yetanother/(.*)
- backend:
serviceName: my-main-frontend
servicePort: 80
path: /(.*)
This works for the api-services, but not for the frontends. Was I to enter a URI like myapp.com/other/
in my browser it would make a call to my-other-frontend:9000/other/
, instead of my-other-frontend:9000/
. This can of course be solved with a rewrite annotation like nginx.ingress.kubernetes.io/rewrite-target: /$1
, the problem is, that this would also apply to the api-services, and those actually need the complete route in their call, so a general rewrite rule would break them.
So my question is: Is it possible to define rewrite rules that only apply to specific paths?
I would advise to split your ingress into 2 based on your different annotations.
1) First one for api-services, called my-api-ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-api-ingress
namespace: my-namespace
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
tls:
- hosts:
- myapp.com
secretName: my-certificat
rules:
- host: myapp.com
http:
paths:
- backend:
serviceName: my-service-1
servicePort: 8092
path: /api/someroute/(.*)
- backend:
serviceName: my-service-2
servicePort: 30003
path: /api/someotherroute/(.*)
2) And second one, lets say my-front-ingress
with nginx.ingress.kubernetes.io/rewrite-target: /$1
annotation for rest of your frontends. Based on your question I believe you dont need the detailed instruction for ingress creation with rewrite annotation.
EDIT1: Yes, its possible to create multiple ingresses with the same host. But please pay attention which exactly nginx ingress. Refer to @LazerBass answer with his investigations.
In short, based on nginx ingress comparation table,
The nginxinc controller does not support merging Ingress rules with the same host. You can use it only with Mergeable Ingresses
The easiest way is to use regular kubernetes/ingress-nginx
Hope that helps.