Dynamic redirect using ingress - service

I have 2 questions:
1) I have a kubernetes cluster with multiple services and I want to use ingress to dynamically redirect the traffic to the cluster.
I expect the configuration to look something like this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /service1/*
backend:
serviceName: service1
servicePort: 80
path: /*
- path: /service2/*
backend:
serviceName: service2
servicePort: 80
path:/*
So basically I want all the traffic to /service1/endpoint to be redirected to s1:80/endpoint dynamically.
2) Let's say I have 2 web services - service1 & service2.
I want the users to work with the following URL in their browser:
kube/serviceN/endpoint
Is there a way to do that without having my users redirected to service1/endpoint?
Thanks!

I believe your ingress definition to be almost correct:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /service1
backend:
serviceName: service1
servicePort: 80
- path: /service2
backend:
serviceName: service2
servicePort: 80
This should work if you have an ingress correctly deployed!

I hope I have understood your question properly but if so, what you have provided as an example is pretty close to the mark. The below config should work as described.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /service1/
backend:
serviceName: service1
servicePort: 80
- path: /service2/
backend:
serviceName: service2
servicePort: 80
Good luck :)

Related

Redirect trafic from one app (workload) to other if there is prefix?

I have two apps (workloads): app1 and app2. My goal is to redirect trafic from app1 to app2 if there is the diona prefix. For example:
app1/diona > app2/<api>
Now I have such rules:
rules:
- host: host
http:
paths:
- backend:
serviceName: ingress-37ce1ad1e8214375784d1e50805c056c
servicePort: 80
path: /diona
When I check app1/diona endpoint in logs of app2 there is an error:
Not Found: /diona
How can I redirect trafic correctly without realizing diona prefix in app2?
You can achieve it using nginx ingress controller. You code will look like this
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
name: rewrite
spec:
rules:
- host: host
http:
paths:
- backend:
serviceName: ingress-37ce1ad1e8214375784d1e50805c056c
servicePort: 80
path: /diona
If you want to redirect app1/diona/* to app2/*, change annotations to
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
name: rewrite
spec:
rules:
- host: host
http:
paths:
- backend:
serviceName: ingress-37ce1ad1e8214375784d1e50805c056c
servicePort: 80
path: /diona/(.*)
Reference

Route traffic using ingress

I had a working example of a project a year back, which is not working anymore.
It's basically related to change in the behavior of nginx.ingress.kubernetes.io/rewrite-target property mentioned here - https://github.com/kubernetes/ingress-nginx/tree/master/docs/examples/rewrite
I have 3 application and I want to route based on conditions.
/* to frontend-cluster-ip-service
/api/battleship/* to battleship-cluster-ip-service
/api/connect4/* to connect-four-cluster-ip-service
The working example that was working an year back was
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: frontend-cluster-ip-service
servicePort: 3000
- path: /api/connect4/
backend:
serviceName: connect-four-cluster-ip-service
servicePort: 8080
- path: /api/battleship/
backend:
serviceName: battleship-cluster-ip-service
servicePort: 8080
However, this is not working anymore and only routing to / , i.e to frontend-cluster-ip-service is working. Routing to other serives fails and I get 404.
Then I came to know about the change in nginx.ingress.kubernetes.io/rewrite-target.
I tried following then
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: frontend-cluster-ip-service
servicePort: 3000
- path: /api/connect4(/|$)(.*)
backend:
serviceName: connect-four-cluster-ip-service
servicePort: 8080
- path: /api/battleship(/|$)(.*)
backend:
serviceName: battleship-cluster-ip-service
servicePort: 8080
Now the routing to connect-four-cluster-ip-service and battleship-cluster-ip-service is working but frontend-cluster-ip-service is not working and few js files loads are showing error:
I had the same issue with a bit more complicated rewrite (it was only for one different path).
Making multiple Ingresses for each path worked for me but might not be the cleanest solution.
My ingress definition:
https://github.com/FORTH-ICS-INSPIRE/artemis/blob/master/artemis-chart/templates/ingresses.yaml

Rewriting Kubernetes services in an Nginx ingress

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
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.
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

Kubernetes ingress nginx not matching sub paths

I'm trying to make a simple example of ingress-nginx on google cloud, but it's not matching the subpaths:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /one
backend:
serviceName: test-one-backend
servicePort: 80
- path: /two
backend:
serviceName: test-two-backend
servicePort: 80
When I call, http://server/one works, but when I call http://server/one/path I get a 404.
I'd tried several things like using regex, but is simply not working
The backends are just, echo servers that reply always on any path.
You need to use a /* at the end of the path:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /one/*
backend:
serviceName: test-one-backend
servicePort: 80
- path: /two
backend:
serviceName: test-two-backend
servicePort: 80
It's not really documented widely as of today, but in essence the path translates to a location {} block in the nginx.conf
Attention it changed in version 0.22.0 of ingress-nginx. checkout example at https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/rewrite/README.md
Now you have to work with captured groups to pass a subpath to the rewrite-target.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: rewrite
namespace: default
spec:
rules:
- host: rewrite.bar.com
http:
paths:
- backend:
serviceName: http-svc
servicePort: 80
path: /something(/|$)(.*)
This definition matches the exact string for the path. If you want to include subdirectories you can use the wildcard *. Your modified definition should look like this:
- path: /one/*
backend:
serviceName: test-one-backend
servicePort: 80
I am not sure if http://server/one (without the slash at the end) still works. In that case you have to keep your old definition and add another one like the above.

How to specify a prefix to a service exposed with an ingress

I want exposing various services with a single ingress.
rules:
- http:
paths:
# The path is the URL prefix for the service, e.g. /api/* or just /*
# Note that the service will receive the entire URL with the prefix
- path: /service1/*
backend:
serviceName: service1
servicePort: 5000
- path: /service2/*
backend:
serviceName: service2
servicePort: 5000
The problem is the whole URL including the prefix is passed to the underlying services so all requests return 404 errors: service1 and api don't respond on /service1/some/path but directly on /some/path
How can I specify a prefix to the underlying services?
UPDATE
I tried using rewrite-target as follows. Requests are sent to the rasa-nlu service, but they all trigger 404 because rasa-nlu still gets the /nlu
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress
annotations:
ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /nlu
backend:
serviceName: rasa-nlu
servicePort: 5000
This might be what you are looking for;
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
ingress.kubernetes.io/rewrite-target: /
name: rewrite
namespace: default
spec:
rules:
- host: rewrite.bar.com
http:
paths:
- backend:
serviceName: echoheaders
servicePort: 80
path: /something
Note the annotation to rewrite-target.
Found this here
This thread might be solved till now, but just for the sake of solution.
below will solve the issue, the default path will be /nlu when it is added to the re-write annotation.
It is from the nginx re-write rule which gets applies to the definition of location directive.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress
annotations:
ingress.kubernetes.io/rewrite-target: /nlu
spec:
rules:
- http:
paths:
- path: /nlu
backend:
serviceName: rasa-nlu
servicePort: 5000