I have multiple namespaces which utilize different services
Some of these services expose the same paths, i.e. /ready
I'de like to create an ingress rule per namespace/service so the external path of namespaceA/ready will actually go to the service under namespaceA at /ready path
I read about rewrite but if I understand it correctly, it will redirect namespaceA/ready to /ready globally, meaning it will just act as if the path was /ready, regardless to the namespace.
I'm not sure. But you may have a little misunderstanding between rewrite and redirect. Rewrite rules won't cause redirect, it rewrite the request then send it to the specific backend. It's totally reasonable and common to configure two rewrite rules rewriting two paths with the same suffix to two different backend.
Rewrite works like this:
$ curl mydomain.io/test/moretest
404 page not found
$ kubectl logs test-server
Request method=GET path=/moretest status=404 user-agent=curl/7.29.0redirect however, works like this:
# curl mydomain.io/test/moretest
Moved Permanently
# curl mydomain.io/moretest
404 page not found
$ kubectl logs test-server
Request method=GET path=/test/moretest status=302 user-agent=curl/7.29.0
Request method=GET path=/moretest status=404 user-agent=curl/7.29.0I'm not familiar with Nginx. I know how to achieve this with Traefik, though. For instance, this yaml file will do:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: myappA
namespace: namespaceA
annotations:
traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip
spec:
rules:
- host: mydomain.io
http:
paths:
- path: /namespaceA
backend:
serviceName: myapp
servicePort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: myappB
namespace: namespaceB
annotations:
traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip
spec:
rules:
- host: mydomain.io
http:
paths:
- path: /namespaceB
backend:
serviceName: myapp
servicePort: 80All the request for /namespaceA/ready will be rewritten to /ready then being sent to myapp in namespaceA.
All the request for /namespaceB/ready will be rewritten to /ready then being sent to myapp in namespaceB.
In addition to Lentil1016 answer, here is the example of the same rewrite solution for nginx-ingress-controller.
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
ingress.kubernetes.io/ssl-redirect: 'false'
nginx.ingress.kubernetes.io/force-ssl-redirect: 'false'
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: myapp
namespace: namespaceA
spec:
rules:
- host: mydomain.io
http:
paths:
- backend:
serviceName: myapp
servicePort: 80
path: /namespaceA(/|$)(.*)
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: myapp
namespace: namespaceB
spec:
rules:
- host: mydomain.io
http:
paths:
- backend:
serviceName: myapp
servicePort: 80
path: /namespaceB(/|$)(.*)For example, the ingress definition above will result in the following rewrites:
For destination service myapp in the namespace namespaceA:
mydomain.io/namespaceA rewrites to mydomain.io/
mydomain.io/namespaceA/ rewrites to mydomain.io/
mydomain.io/namespaceA/ready/ rewrites to mydomain.io/ready/For destination service myapp in the namespace namespaceB:
mydomain.io/namespaceB rewrites to mydomain.io/
mydomain.io/namespaceB/ rewrites to mydomain.io/
mydomain.io/namespaceB/ready/ rewrites to mydomain.io/ready/Note: You may need to use nginx-config ConfigMap to completely switch off ssl-redirect for nginx-ingress-controller.
Note: There are two kinds of nginx-ingress-controllers, kubernetes and nginxinc. ConfigMap options and annotations could be different for each of them.
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-config
namespace: nginx-ingress # <--- or ingress-nginx, depends on your installation
data:
redirect-to-https: "false"
ssl-redirect: "false"