Any solution for multi-tenant setup with different DNS? - kubernetes

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.

Related

same path with different service names in ingress resources

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.

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

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

Issue with Kubernetes ingress routing to Nextjs applications

So I have an interesting use case. I am running multiple micro-services on my Kubernetes cluster. My applications use NextJS which make internal calls to _next routes.
My issue came from the fact that I needed a way to differentiate between services and their requests to the _next files. So I implemented NextJS's assetPrefix feature which works perfectly in development, appending my prefix in front of _next so the requests look like .../${PREFIX}/_next/.... That way I could set up an ingress and route files base on the prefix to the appropriate service on my cluster. I set up a Kubernetes Ingress controller following this guide: https://akomljen.com/kubernetes-nginx-ingress-controller/
My ingress config is:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: dev-ingress
spec:
rules:
- host: baseurl.com
http:
paths:
- path: /auth
backend:
serviceName: auth-svc
servicePort: 80
- path: /static/auth
backend:
serviceName: auth-svc
servicePort: 80
- path: /login
backend:
serviceName: auth-svc
servicePort: 80
- path: /settings
backend:
serviceName: auth-svc
servicePort: 80
- path: /artwork
backend:
serviceName: artwork-svc
servicePort: 80
- path: /static/artwork
backend:
serviceName: artwork-svc
servicePort: 80
So here is the problem. Now that everything is set up, properly deployed, and the ingress is running following the above guide and using the above rules, my services are trying to make requests to .../_next/... instead of .../${PREFIX}/_next/... so they can't find the proper files and nothing is working. I cannot seem to figure out what is going on. Anyone have any ideas? Thanks in advance!
You are using built-in NGINX Ingress Controller that, unfortunately, has no such functionality.
My advice is to use NGINX Plus Ingress Controller annotation functionality if you can afford it.
You can find official example here.
Example:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: cafe-ingress
annotations:
nginx.org/rewrites: "serviceName=tea-svc rewrite=/;serviceName=coffee-svc rewrite=/beans/"
spec:
rules:
- host: cafe.example.com
http:
paths:
- path: /tea/
backend:
serviceName: tea-svc
servicePort: 80
- path: /coffee/
backend:
serviceName: coffee-svc
servicePort: 80
Below are the examples of how the URI of requests to the tea-svc are rewritten (Note that the /tea requests are redirected to /tea/).
/tea/ -> /
/tea/abc -> /abc
Below are the examples of how the URI of requests to the coffee-svc are rewritten (Note that the /coffee requests are redirected to /coffee/).
/coffee/ -> /beans/
/coffee/abc -> /beans/abc

Kubernetes Ingress on GKE

I deployed Kubernetes on AWS with KOPS and the nginx-ingress.
To evaluate multiple clouds (and cut costs), I want to deploy on GKE. Everything worked, except the darn Ingress's. (That was the hardest part on AWS).
Below is the Ingress I'm using on GKE. It makes two Ingresses in the dashboard, each with an IP address.
If I point my DNS at those addresses, the connection is refused. I'm checking the DNS resultion with ping.
All HTTPS fail to connect with "Unable to establish SSL connection.", except button which is "502 Bad Gateway"
HTTP fails to connect with 502 except admin which is 503.
In the Google Cloud Platform dashboard, I see two load balancers. "all" points to my SSL cert. "button" isn't doing HTTPS, but that's another problem.
Clearly I'm missing something. What did I miss?
I'm using kubectl v1.4.6 and whatever version on GKE would have installed yesterday.
```
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
# this is for nginx ingress controler on AWS
# kubernetes.io/ingress.class: "nginx"
name: all-ingress
spec:
tls:
- hosts:
- admin-stage.example.com
- dashboard-stage.example.com
- expert-stage.example.com
- signal-stage.example.com
- stage.example.com
secretName: tls-secret
rules:
- host: admin-stage.example.com
http:
paths:
- backend:
serviceName: admin-service
servicePort: http-port
path: /
- host: dashboard-stage.example.com
http:
paths:
- backend:
serviceName: dashboard-service
servicePort: http-port
path: /
- host: expert-stage.example.com
http:
paths:
- backend:
serviceName: expert-service
servicePort: http-port
path: /
- host: signal-stage.example.com
http:
paths:
- backend:
serviceName: signal-service
servicePort: http-port
path: /
- host: stage.example.com
http:
paths:
- backend:
serviceName: www-service
servicePort: http-port
path: /
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
# this is for nginx ingress controler on AWS
# kubernetes.io/ingress.class: "nginx"
ingress.kubernetes.io/ssl-redirect: "false"
name: button-ingress
spec:
tls:
- hosts:
- button-stage.example.com
secretName: tls-secret
rules:
- host: button-stage.example.com
http:
paths:
- backend:
serviceName: button-service
servicePort: http-port
path: /
```
Prashanth's comments were helpful, in the end, native cloud Ingress (AWS/GCE) isn't finished in Kubernetes enough to be useful for my purposes. There's no point learning an abstraction that is more complicated and less functional than the thing underneath.
I ended up using the nginx-ingress from this answer: Kubernetes 1.4 SSL Termination on AWS
On the resulting Ingress is an IP you can point DNS (not the "External Endpoints" on the service). Good luck!