how to setup yaml ingress in google cloud with redirect - kubernetes

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

Related

How to service multiple solution webui through one port using k8s ingress service

I need to service gitlab, nexus and jupyterhub based on URL using one open port using k8s ingress.
If the path is written as "/" when create ingress, it works normally, but if you write "/nexus" like this, a problem occurs during the redirection process.
Have any of you solved the same problem? Please help.
my ingress.yaml as below
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
creationTimestamp: "2022-04-06T05:56:40Z"
generation: 7
name: nexus-ing
namespace: nexus
resourceVersion: "119075924"
selfLink: /apis/extensions/v1beta1/namespaces/nexus/ingresses/nexus-ing
uid: 4b4f97e4-225e-4faa-aba3-6af73f69c21d
spec:
ingressClassName: nginx
rules:
- http:
paths:
- backend:
serviceName: nexus-service
servicePort: 8081
path: /nexus(/|$)(.*)
pathType: ImplementationSpecific
status:
loadBalancer:
ingress:
- ip: 172.30.1.87
That's a problem with nexus itself. Your ingress works as intended, and you cannot do more from this side.
The problem here is that nexus webpage, i.e. index.html, requests resources in such a way that it's looking at the wrong place. You can see this by opening the network tab and inspecting the request URL of the missing statics.
To see what I mean, let's examine the below HTML image tags.
<img id="1" src="./statics/some-image.svg" alt="some image" />
<img id="2" src="/statics/some-image.svg" alt="some image" />
You can see that the first one, is using relative path, and would work with your configuration since the request URL would be relative to the location in the browser and then the nexus part gets stripped by the ingress controller.
However, the second one is using absolute path, so it will not have the nexus part in the request URL and the ingress controller will not be able to route it to the correct service.
This is a common problem when stripping path prefixes. It only works fully when the application you are serving when stripping a prefix is correctly configured.
In your case this means, checking the documentation of the services, if you have any way to influence this.
It may be more straight forward to route based on hostname instead of path. I.e nexus.myhost.com. For that, you would need a domain and point the corresponding A records to your ingress services IP / use a wildcard record.
I solve this problem by myself
I edited my pc hosts file
172.30.1.87 nexus.k8s.io
172.30.1.87 gitlab.k8s.io
I edited each Ingress in same service namespace
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
namespace: nexus
spec:
ingressClassName: nginx
rules:
- host: nexus.k8s.io
http:
paths:
- backend:
serviceName: nexus-service
servicePort: 8081
path: /
status:
loadBalancer:
ingress:
- ip: 172.30.1.87
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
name: gitlab-ingress
namespace: gitlab
spec:
ingressClassName: nginx
rules:
- host: gitlab.k8s.io
http:
paths:
- backend:
serviceName: gitlab-webservice
servicePort: 8181
path: /
status:
loadBalancer:
ingress:
- ip: 172.30.1.87
connect test
ingress Hostname + ingress Controller Nodeport

Kubernetes fanout ingress but with the root domain serving the client

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.

Is there a way url redirect internally to particular service based on context path?

There are multiple same pods running in one cluster but different namespaces. This is the web application running in Kubernetes. I have the URL <HOSTNAME>:<PORT>/context/abc/def/...... I want to redirect to particular service based on the context. Is there a way i can achieve it using ingress controller ? Or Is there any way i can achieve it using different ports through ingress ?
My web application works fine if the URL is <HOSTNAME>:<PORT>/abc/def/...... Since i have to access the different pods using the same URL, I am adding context to it. Do we have any other way to achieve this use case ?
You can do that with rewrite-target. In example below i used <HOSTNAME> value of rewrite.bar.com and <PORT> with value 80.
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: context-service
servicePort: 80
path: /context1(/|$)(.*)
- backend:
serviceName: context-service2
servicePort: 80
path: /context2(/|$)(.*)
For example, the ingress definition above will result in the following rewrites:
rewrite.bar.com/context1 rewrites to rewrite.bar.com/ for context 1 service.
rewrite.bar.com/context2 rewrites to rewrite.bar.com/ for context 2 service.
rewrite.bar.com/context1/new rewrites to rewrite.bar.com/new for context 1 service.
rewrite.bar.com/context2/new rewrites to rewrite.bar.com/new for context 2 service.
You can manage how the traffic is pointed to the correct service by using the rules configuration of the ingress, here is a simple example from the documentation:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: app-ingress
spec:
rules:
- http:
paths:
- path: /abc
backend:
serviceName: abc-service
servicePort: 80
- path: /context
backend:
serviceName: context-service
servicePort: 80

Kubernetes: path based only works with root

I have an EKS cluster and currently use path based routing. I previously posted this thread, so all my configuration is on there: Kubernetes: 502 (Bad getaway)
My ingress controller is from there: https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/mandatory.yaml
Here is my ingress:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: simple-fanout-example
namespace : default
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: domain.com
http:
paths:
- path: /bleble(/|$)(.*)
backend:
serviceName: bleble-svc
servicePort: 8080
- path: /hello-world
backend:
serviceName: hello-world-svc
servicePort: 8080
This works absolutly fine, until you try to go anywhere that is not the domain.com/bleble or domain.com/hello-world. The services need to refer to each other, and the uri they request is just domain.com, which obviously doesn't work because the service is at domain.com/nameoftheservice.
The 2 problems are :
The service name is bleble, so we decided the path should be /bleble. I saw on this documentation (kubernetes.github.io/ingress-nginx/examples/rewrite) that adding (/|$)(.*) would allow rewrite. We want to use url as domain.com/bleble/swagger or domain.com/bleble/clients, ... But when we type those, it brings back to what was on /bleble
I need bleble to get an info from hello-world. Right now, instead of going from domain.com/bleble to domain.com/hello-world, it goes from domain.com/bleble to domain.com. it seems to only be able to call the host name, and not the path.
I've tried doing a single ingress resource and have nginx.ingress.kubernetes.io/app-root : /bleble but this doesn't seem to be working. I've tried the annotation as well nginx.ingress.kubernetes.io/rewrite-target: /coretest
Thanks for the help!

Troubleshooting kubernetes nginx controller routing

I can't get the nginx controller to route based on the hostname. The YAML below doesn't work - traffic goes to the default back-end / I get a 404. However, if I remove the value for host, the ingress controller successfully routes traffic to my-service. The service works successfully if I place it behind a load balancer but I want to have multiple services working for different host names so I want to use an ingress controller and use a single IP. Thoughts?
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-nginx
annotations:
ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: test1.mydomain.com
http:
paths:
- path: /
backend:
serviceName: my-service
servicePort: 80
The yaml looks slightly different than the rewrite example located here. The yaml is valid and kubectl apply or create should work but not produce the results you are expecting. Do you need the rewrite annotation or could you remove it and the back end service will respond without issue? If you don't need to rewrite anything try removing the yaml to just look like:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-nginx
spec:
rules:
- host: test1.mydomain.com
http:
paths:
- backend:
serviceName: my-service
servicePort: 80