Kubernetes fanout ingress but with the root domain serving the client - kubernetes

I'm having trouble getting my client container talking to the API container, I was hoping to use a fanout ingress as so:
foo.bar.com/api - routes to API container
foo.bar.com - routes to client container
My setup does render the client no problem, but all calls to the API result in 404s - so it's obviously not working. I think the 404 behaviour is a red herring, it's probably looking for Angular routes that match /api and can't find any, I don't think the routing is even happening. My Ingress yaml is below, I can share any other parts of the config if needed. Any pointers much appreciated!
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
namespace: foo-bar
name: foo-bar-ingress
annotations:
kubernetes.io/ingress.class: nginx
certmanager.k8s.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
spec:
tls:
- hosts:
- foo.bar.com
secretName: tls-secret-prod
rules:
- host: foo-bar.com
http:
paths:
- backend:
serviceName: server
servicePort: 3000
path: /api
- backend:
serviceName: client
servicePort: 80
path: /

As suggested by #HelloWorld in the comments, checking the api server routes revealed the issue to be misconfigured routing in the server not the ingress rules.

Related

how to setup yaml ingress in google cloud with redirect

I’m setting up an environment in Google Cloud with an ingress and load balancers.
I know how to setup hosts and paths to it but I can't figure out how to setup when a user goes to a specific site http://example.com/ I want him to redirect to http://example.com/en.
Note:
http => https
/ => /en
UPDATED
I added app-root: /en (but it doesn't do anything).
This is my current yaml:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: gce
kubernetes.io/ingress.global-static-ip-name: our-frontend-static-ip
networking.gke.io/managed-certificates: example-certificate
appgw.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/app-root: /en
name: example-ingress
namespace: default
spec:
rules:
- host: anotherexample.com
http:
paths:
- backend:
serviceName: anotherexample-service
servicePort: 80
- host: example.com
http:
paths:
- path: /nl
backend:
serviceName: example-nl-service
servicePort: 80
- path: /en
backend:
serviceName: example-en-service
servicePort: 80
So, there are 2 hosts in my yaml and I want: when the url is correct for 1 of the hosts: example.com it must go to example.com/en (this is for Multilanguage purposes)
We can change the settings in the loadbalancer ban after the sync from the ingress in changes it back.
Kubernetes supports multiple Ingress Controllers which are different from each other. For example, you are trying to use the Ingress GCE and there is also a popular Nginx Ingress.
The main problem in your use case is that the Ingress GCE is not supporting rewrites. An on-going feature request regarding that can be found here.
To be able to use the rewrites you will need to deploy the Nginx Ingress Controller and switch annotation in your yaml from:
kubernetes.io/ingress.class: "gce"
to:
kubernetes.io/ingress.class: "nginx"
The sources that will help you out with this are as follows:
Installation Guide
Rewrite
An example

Minikube | Ingress Service - Bad Request

I'm working on a single-node cluster which works fine with docker-compose but the reconfiguration of the same setup using Minikube Ingress Controller gives me a Bad Request response.
Bad Request
Your browser sent a request that this server could not understand.
Reason: You're speaking plain HTTP to an SSL-enabled server port.
Instead use the HTTPS scheme to access this URL, please.
My Ingress looks like this:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- http:
paths:
- path: /?(.*)
pathType: Prefix
backend:
service:
name: emr-cluster-ip-service
port:
number: 443
- path: /?(.*)
pathType: Prefix
backend:
service:
name: erp-cluster-ip-service
port:
number: 8069
How to fix this?
You are exposing HTTPS service on HTTP ingress, which is not the right thing to do. You might want to do one of the following:
Configure TLS-enabled ingress.
Configure TLS passthough on ingress object.
In both cases you also need to set nginx.ingress.kubernetes.io/ssl-redirect: "true"

Kubernetes Google OAuth2 Sign In

I'm trying to figure this out for a while and can't seem to find an answer anywhere. Maybe someone here will have an idea.
I have deployed an application on Kubernetes Cluster (in GCP). The Application is pretty much a micro-service type of app under a single domain. What I'm trying to achieve at the moment is to have a domain-wide-authentication via Google and OAuth2 protocol.
So I have a main app under the main domain https://example.com and pretty much every single path under that domain will be a separate K8s Service + Deployment. So it's a different set of containers for https://example.com/foo and different for https://example.com/bar and obviously different set of containers for the main https://example.com. I don't want to "connect" each individual App to Google due to two reasons:
Would require for me that each app has the OAuth2 Protocol implemented, and
A token granted by one app would be invalid for the other one, so it would require the user to log in each time he/she changes the URL, kind bad UX if you ask me
So, I'm trying to set up in the Kubernetes Cluster an Nginx Ingress Controller that would facilitate authentication and validate all incoming requests before they would reach any of the backend apps. This is where the problem lies...
I've managed to set up OAuth2 Proxy in my Nginx Ingress Controller and the user can log in. The whole OAuth2 Flow works. HOWEVER, the user is not forced to log in. The user can navigate to the https://example.com but he/she won't be required to have an Authentication cookie granted after successful login via Google.
Here is my YAML config for Ingress:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$escaped_request_uri"
kubernetes.io/ingress.class: "nginx"
ingress.kubernetes.io/force-ssl-redirect: "true"
name: example-com-ingress
namespace: default
spec:
tls:
- hosts:
- example.com
secretName: example-com-tls
rules:
- host: example.com
http:
paths:
- backend:
serviceName: oauth2-proxy
servicePort: http-proxy
path: /oauth2
- backend:
serviceName: example-com-nginx-service
servicePort: 80
path: /
Any ideas anyone?
Make sure that while configuring oauth2 proxy you set your cookie domain (set --cookie-domain=example.com to allow the cookie to be read).
You have to also add the whitelist-domain feature while configuring oauth2 proxy:
--whitelist-domain=example.com
Then have to create ingress' obects:
1. Expose endpoint /oauth2, look at the example below:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: oauth2-proxy
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
rules:
- host: example.com
http:
paths:
- backend:
serviceName: oauth2-proxy
servicePort: 4180
path: /oauth2
tls:
- hosts:
- example.com
secretName: example-com-tls
2. Then create ingress for your application:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example-com-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$escaped_request_uri"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
tls:
- hosts:
- example.com
secretName: example-com-tls
rules:
- host: example.com
http:
paths:
- path: /
backend:
serviceName: example-com-nginx-service
servicePort: 80
It is clearly to create two separate ingresses, but you can also create just one with two defined backends as you wanted.
Take a look here: nginx-ingress-controller-oauth2, oauth2-dynamic-callbacks, oauth2-proxy.
Once again make sure that you have follow this instruction: external-OAUTH-authentication.

Disable path rewrite for Kubernetes fan out Ingress

My Kubernetes application uses an Ingress to proxy requests to different servers, according to the URL given: I want a fanout configuration. I want the URLs of the requests not to be rewritten when forwarded to the servers. How do I do that?
I want all the /api URLs forwarded to the be service, and all others forwarded to the fe service. But I want the URLs forwarded unchanged.
For example
a request for /api/users should be forwarded to the be service as a request for /api/users.
a request for /foo should be forwarded to the fe service as a request for /foo.
My current Ingress resource is like this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
...
spec:
...
rules:
- host: ...
- http:
paths:
- path: /api
backend:
serviceName: be
servicePort: 8080
- path: /
backend:
serviceName: fe
servicePort: 80
but that does not work; it gives 404 Not Found for requests.
The Kubernetes ingress isn't rewriting your request URLs, the ingress controller is doing this (whatever you happen to be using). For instance, if your ingress controller is Nginx, you can control this behavior with annotations on the ingress.
Old question but i got a similar problem solved with nginx ingress annotations as suggested by Grant David Bachman:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
...
spec:
...
rules:
- host: ...
- http:
paths:
- path: "/(api.*)"
backend:
serviceName: be
servicePort: 8080
- path: "/(.*)"
backend:
serviceName: fe
servicePort: 80

Kubernetes Ingress - Rewrite path

I’m trying to redirect the incoming connections with an ingress of a cluster created in IBM Cloud.
I’m able to successfully set up the ingress and contact the pod.
However, when the connection reaches the endpoint
http://app1.myaddress.cloud/test1
is not rewrited to the right pod url ( The path still contains the /test1 and I want to remove that part).
Do you have any idea how to solve the issue?
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: hello-world-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts:
- app1.myaddress.cloud
secretName: myclustername
rules:
- host: app1.myaddress.cloud
http:
paths:
- path: /test
backend:
serviceName: hello-world-service-1
servicePort: 30001
I found the official IBM Cloud tutorial here.
https://cloud.ibm.com/docs/containers?topic=containers-ingress_annotation