same path with different service names in ingress resources - kubernetes

I'm having some issues when using a path to point to different service names, my ingress resource looks as below
nginx-static service is a nginx container which has static content... I have to load this static content while calling service-1, since both nginx-static and service-1 but I cannot keep the sme same host path.... Please suggest how to correct the below ingress resources...
kindly note static content has lot of files(csv,js,html,directories, files etc)
kind: Ingress
metadata:
name: myingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- http:
paths:
- path: "/"
backend:
serviceName: nginx-static
servicePort: 80
- path: "/"
backend:
serviceName: service1
servicePort: 8989
- path: "/test1"
backend:
serviceName: service2
servicePort: 9001
Any expert help is appreciated!!!

You cannot have the same path pointing to different backend resources. You have to put either your static files or the service into a different path, and rewrite the URL, for instance:
rewrite annotation:
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: rewrite
namespace: default
paths:
- backend:
serviceName: nginx-statix
servicePort: 80
path: /static(/|$)(.*)
- backend:
path: /
serviceName: service1
With this, your static content will be exposed under /static/, and all /static/name will be rewritten as /name by the ingress.
More info here: https://kubernetes.github.io/ingress-nginx/examples/rewrite/

Unfortunately, requirements from the initial questions aren't' clear and there were no additional clarifications given. However, I'd like to elaborate on Burak Serdar's answer and add , that Kubernetes Ingress allows you listing the same path ad port for a multiple services under condition that you are listing these for different hosts.
foo.bar.com --| |-> foo.bar.com nginx-static:80
| 178.91.123.132 |
bar.foo.com --| |-> bar.foo.com service1:8989
you can achieve that scenario with the following config:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: foo.bar.com
http:
paths:
- backend:
serviceName: nginx-static
servicePort: 80
- host: bar.foo.com
http:
paths:
- backend:
serviceName: service2
servicePort: 8989
However that would work only if you can split your web site between two hosts.
Hope that helps.
You can check more on Ingress on K8s documentation.

Related

Kubenetes Ingress API Routing

I have a react web application listening on the default path and I'm looking to include my API backend on the same URL.
A snippet of my ingress is below:
http:
paths:
- backend:
serviceName: atsweb
servicePort: 80
path: /(.*)
- backend:
serviceName: atsapi
servicePort: 80
path: /api(/|$)(.*)
My API has a bunch of functions which are routed after /api/ and I have a test page at mydomain.io/api/values which I cannot get to. My frontend service works fine.
Is it just the pathing which is incorrect?
I've deployed a standalone API just to check the container port/service ports are correct.
Looks like you copied the example from . What are your ingress annotations? Check the rewrite as it looks like is making a redirect. Nonetheless, the ingress that would work for looks like this:
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: your-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: atsweb
servicePort: 80
- path: /api/
backend:
serviceName: atsapi
servicePort: 80
Check there is no rewrite annotation. This makes your uri be appended fully to the next proxy. Thus, making mydomain.io/api/values go to atsapi:80/api/values

Any solution for multi-tenant setup with different DNS?

I have set up my frontend cluster in my Kubernetes and exposed as frontend.loaner.com and I want to point the DNS record of these both johndoe.loaner.com, janedoe.loaner.com to see the frontend.loaner.com.
Is that possible to just point two DNS to a 1 running server and works fine still having the hostname?
I read about the CNAME but it will redirect me to frontend.loaner.com
You can do it with a Kubernetes Ingress. Basically, something like this:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: frontend.loaner.com
http:
paths:
- path: /
backend:
serviceName: backend1
servicePort: 80
- host: johndoe.loaner.com
http:
paths:
- path: /
backend:
serviceName: backend2
servicePort: 80
- host: janedoe.loaner.com
http:
paths:
- path: /
backend:
serviceName: backend3
servicePort: 80
The above Ingress resource assumes you are using an Nginx Ingress Controller in your cluster.

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

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

Dynamic redirect using ingress

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 :)