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
Related
I'm trying to connect my web service using ingress on bare metal kubernetes with metallb.
Since I'm trying to service at least to different service, but I only have one possible ip address.
I set rules for ingress as follows:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ad-ingress-service3
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernets.io/app-root: /root/team_AD/leejh/ui/
# nginx.ingress.kubernetes.io/enable-rewrite-log: "true"
spec:
rules:
- host: "team.ads"
http:
paths:
- path: /wine(/|$)(.*)
pathType: Prefix
backend:
service:
name: ui-svc2
port:
number: 100
I can see my index.html page, but my index.js which is in the same directory with index.html, is not.
On chrome console, I got 404 error, saying http://team.ads/index.js not found.
What should I do?
I'm expecting when I type http://team.ads/wine in the address bar, I can get my first webpage.
But .js and .css files are not found.
I have a simple website running in my Kubernetes cluster and exposed to the Internet using Traefik. My Ingress object looks like this (the only things I've changed here are the name and domain names):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-staging
kubernetes.io/ingress.class: traefik
name: my-cool-website
namespace: default
spec:
rules:
- host: my-cool-website.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-cool-website
port:
number: 80
- host: www.my-cool-website.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-cool-website
port:
number: 80
tls:
- hosts:
- my-cool-website.com
- www.my-cool-website.com
secretName: my-cool-website-tls
This works. It allows me to access the site either from my-cool-website.com or from www.my-cool-website.com. But what I'd like to have happen is that if someone visits the former, that Traefik automatically redirects them to the latter. I found a couple of guides online that recommended creating a Traefik middleware, so I did just that, but unfortunately it doesn't work as intended. Here is my middleware definition:
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: my-cool-website-force-www
spec:
redirectRegex:
regex: ^https?://my-cool-website.com/(.*)
replacement: https://www.my-cool-website.com/${1}
And then I add the following annotation back to the ingress object:
traefik.ingress.kubernetes.io/router.middlewares: my-cool-website-force-www
But as soon as I do that, it breaks my web app. By that I mean, when that annotation is applied, instead of serving my website, I start seeing a generic nginx page that looks like this when I try to access the domain (and also it does not do the redirect):
I have to assume this Hello World page is being served by Traefik as some sort of generic default page, as it definitely does not originate from my pod. So that tells me something about this middleware (or perhaps how I'm calling it with the annotation) isn't working. What am I missing?
I figured it out, by port-forwarding to the Traefik Dashboard and looking at the service there. It was showing an error for the middleware not found. I then clicked over to the middlewares and realized that they end up with a longer canonical name. So in my annotation I had to change the reference from my-cool-website-force-www to default-my-cool-website-force-www#kubernetescrd and then everything worked.
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
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.
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!