Kubernetes: path based only works with root - kubernetes

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!

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

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

Prometheus dashboard exposed over ingress controller

I am trying to setup Prometheus in k8 cluster, able to run using helm. Accessing dashboard when i expose prometheus-server as LoadBalancer service using external ip.
Same does not work when I try to configure this service as ClusterIP and making it as backend using ingress controller. Receiving 404 error, any thoughts on how to troubleshoot this?
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ops-ingress
annotations:
#nginx.org/server-snippet: "proxy_ssl_verify off;"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- http:
paths:
- path: /prometheus(/|$)(.*)
backend:
serviceName: prometheus-server
servicePort: 80
with above ingress definition in place, url “http://<>/prometheus/ getting redirected to http://<>/graph/ and then 404 error page getting rendered. When url adjusted to http://<>/prometheus/graph some of webcontrols gets rendered with lots of errors on browser console.
Prometheus might be expecting to have control over the root path (/).
Please change the Ingress to prometheus.example.com and it should work fine. (Changing it to a subdomain)
Please change your Ingress configuration file, add host field:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ops-ingress
annotations:
#nginx.org/server-snippet: "proxy_ssl_verify off;"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: prometheus.example.com
http:
paths:
- path: /prometheus(/|$)(.*)
backend:
serviceName: prometheus-server
servicePort: 80
then apply changes executing command:
$ kubectl aply -f your_ingress_congifguration_file.yaml
The host header field in a request provides the host and port
information from the target URI, enabling the origin server to
distinguish among resources while servicing requests for multiple
host names on a single IP address.
Please take a look here: hosts-header.
Ingress definition: ingress.
Useful information: helm-prometheus.
Useful documentation: ingress-path-matching.

Kubernetes Ingress not loading static assets

I have a ReactJS front end, Spring boot backend app deployed on a baremetal Kubernetes cluster which is running Kubernetes Ingress and requests are proxied to it by HAProxy. When visiting the URL of the app, I can see it loads the index.html of the app but all other requests to static assets are not done properly.
The ingress resource of my app:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
namespace: app
name: app-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /$3
spec:
rules:
- host: devops
http:
paths:
- path: /dev/app1(/|$)(.*)
backend:
serviceName: app1
servicePort: 80
When inspecting the page which loads using Chrome Developer tools, I see that there are 6 outgoing calls to the static assets. The call that retrieves the index.html of the app completes succesfully but the calls that retrieve the static assets (ex: http://devops/dev/app1/static/js/4.2761693d.chunk.js) does not work properly as it retrieves the index.html page as well. (only the index.html page is served by all calls basically)
I had a feeling it is because of the nginx.ingress.kubernetes.io/rewrite-target annotation but removing it causes a 404 even on the index.html page.
I am using nginx ingress controller 0.25.1
EDIT:
This is the output when I exec into the container and run curl localhost:8080/dev/app1/static/js/4.2761693d.chunk.js (error fallback page)
This is the output when I run curl localhost:8080/tatic/js/4.2761693d.chunk.js (correctly loads the css)
Somehow, when I change the rewrite annotation to this, it works:
nginx.ingress.kubernetes.io/rewrite-target: /$2
I didnt change anything else.
Now the application is accessible at devops/dev/app1/ (but it does not work without the / at the end)
I am not sure how this works. I had no logic behind it, I was just changing values in the ingress file to see if anything works.
Can someone explain why it works?
You are most likely using rewrite target for wrong reasons. In this case all elements should start with /dev/app1 including inner calls. What you are doing is working for index page because you wrote it to have "/dev/app1" in before and ingress redirected it to "/" but inner call just called "/static/js/4.2761693d.chunk.js" . This caused the problem basically, because ingress didn't know the route therefore your service never get called to get the js file.
Im using kubernetes 1.25.2 along with Nginx-Ingress v2.4.1
https://docs.nginx.com/nginx-ingress-controller/installation/installation-with-manifests/
Just us the below 2...the Path should have / at the end.
annotations:
nginx.org/rewrites: "serviceName=app1-svc rewrite=/;serviceName=app2-svc rewrite=/"
spec:
path: /app1/
below is my Ingress resource file manifest...
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: relouat-ingress
namespace: relouat
annotations:
#nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.org/rewrites: "serviceName=app1-svc rewrite=/;serviceName=app2-svc rewrite=/"
spec:
ingressClassName: nginx
rules:
- host: uat.relo.com
http:
paths:
- backend:
service:
name: app1-svc
port:
number: 2041
path: /app1/
pathType: Prefix
- backend:
service:
name: app2-svc
port:
number: 2042
path: /app2/
pathType: Prefix

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