ingress routing api prefix issue - kubernetes

paths:
- backend:
serviceName: booknotes-front-end-service
servicePort: 80
path: /
- backend:
serviceName: booknotes-back-end-service
servicePort: 3000
path: /api
Here is a rules in my ingres-nginx resource . I try to direct all traffic which starts from /api to my back end service, which works properly, but if some route in my back end will be like /api/users it doesn't work , my back end send response not found , when I run it locally this route working properly. Also I've tried delete /api prefix from my koa routing and change it to /users and then I've also changed path: /api to path: /users and this stuff are working properly. What should I do for fixing it ? If you need additional info , pls let me know !

Which version of nginx-ingress are you using?
They changed the way for defining a path.
https://kubernetes.github.io/ingress-nginx/examples/rewrite/
Starting in Version 0.22.0, ingress definitions using the annotation nginx.ingress.kubernetes.io/rewrite-target are not backwards compatible with previous versions. In Version 0.22.0 and beyond, any substrings within the request URI that need to be passed to the rewritten path must explicitly be defined in a capture group.
For example you can use a definition like this.
kind: Ingress
metadata:
name: some-ingress-name
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- http:
paths:
- path: /?(.*)
backend:
serviceName: booknotes-front-end-service
servicePort: 80
- path: /api/?(.*)
backend:
serviceName: booknotes-back-end-service
servicePort: 3000

That's because it is searching for the file /api/users, which probably doesn't exist.
Put a file in /api/users/, in the backends of the service booknotes-back-end-service, say user1, and make the requeat explicitly to /api/users/user1.
You should get 200 there.

https://cloud.google.com/kubernetes-engine/docs/tutorials/http-balancer , section step6 try replacing path /api with /api/* and / with /*

Related

Traefik 'PathPrefix' not working as expected

I have a kube service that has a /customers resource that will return all customers. It can also return a specific customer at /customers/1. I've configured Traefik ingress as follows:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
traefik.frontend.rule.type: PathPrefix
name: customerd
namespace: video
spec:
rules:
- host: custd.kube
http:
paths:
- backend:
serviceName: customerd
servicePort: http
path: /customers
- backend:
serviceName: customerd
servicePort: http
path: /custdhealth
- backend:
serviceName: customerd
servicePort: http
path: /metrics
- backend:
serviceName: customerd
servicePort: http
path: /sleeper
Note that the following annotation is present: traefik.frontend.rule.type: PathPrefix. From the Traefik documentation:
Use a * Prefix * matcher if your backend listens on a particular base
path but also serves requests on sub-paths. For instance, PathPrefix:
/products would match /products but also /products/shoes and
/products/shirts. Since the path is forwarded as-is, your backend is
expected to listen on /products.
The issue is that when I submit a request to /customers/1 the response is a 404. I've confirmed that the request doesn't reach the service. If I change PathPrefix to PathPrefixStrip requests to /customers return a 404, as expected, since the service isn't listening on /. So it seems like I'm using the annotation correctly.
Any ideas what I'm doing wrong or further troubleshooting steps?
After more debugging I figured out the problem. It wasn’t with how I was using Traefik, it was a misunderstanding on my part about how Golang HTTP routing works. My route was coded as “/customers”. Turns out this route will never satisfy “/customers/{id}”. “/customers/“ however will route both “/customers” and “/customers/{id}”. So after a simple code change it all worked.
One factor complicating my debugging efforts was this behavior isn’t visible by inspecting the (non-Golang library) code or putting in debug log messages.

Kubenetes Ingress API Routing

I have a react web application listening on the default path and I'm looking to include my API backend on the same URL.
A snippet of my ingress is below:
http:
paths:
- backend:
serviceName: atsweb
servicePort: 80
path: /(.*)
- backend:
serviceName: atsapi
servicePort: 80
path: /api(/|$)(.*)
My API has a bunch of functions which are routed after /api/ and I have a test page at mydomain.io/api/values which I cannot get to. My frontend service works fine.
Is it just the pathing which is incorrect?
I've deployed a standalone API just to check the container port/service ports are correct.
Looks like you copied the example from . What are your ingress annotations? Check the rewrite as it looks like is making a redirect. Nonetheless, the ingress that would work for looks like this:
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: your-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: atsweb
servicePort: 80
- path: /api/
backend:
serviceName: atsapi
servicePort: 80
Check there is no rewrite annotation. This makes your uri be appended fully to the next proxy. Thus, making mydomain.io/api/values go to atsapi:80/api/values

Specific requests being sent to general path on Nginx Ingress

I have a Flask Python APP that has many routes. This app (container) is served in many different deployments, one for each plan type. Example: we have one deployment called esg-enterprise to process the enterprise plan, another esg-professional for professional and so on. Finally, we have another pod just to serve our frontend application with authentication and the models it needs. All this is the same container.
As you can see in the Ingress file bellow, we have the backend rules to route the traffic to specific services. The problem is that, most of the specific requests like /task/connections/update/advanced/ or /task/connections/update/advanced/ are being sent to the root path / that should only serve the front-end (which works since they use the same container). The problem is that those specific requests are very massive causing the front end API to become unavailable. The specific services run on stronger nodes so they can handle this load, while the front-end api runs on weaker nodes. When I run kubectl get hpa I can see that most of the load (replicas) stays on the API. I even had to increase the max replicas to try to mitigate the issue. I've seen in the logs that some requests are being sent to the specific routes as they should, but the majority is not being sent.
All I wanted to do is to prevent / route to receive those specific requests.
Our ingress looks like this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/affinity: cookie
nginx.ingress.kubernetes.io/proxy-body-size: 150m
nginx.ingress.kubernetes.io/proxy-connect-timeout: "1200"
nginx.ingress.kubernetes.io/proxy-read-timeout: "1200"
nginx.ingress.kubernetes.io/proxy-send-timeout: "1200"
nginx.ingress.kubernetes.io/upstream-fail-timeout: "1200"
name: ingress-nginx
namespace: default
spec:
tls:
- hosts:
- app.ourdomain.com
- api.ourdomain.com
secretName: ourdomain-certificate
rules:
- host: app.ourdomain.com
http:
paths:
- backend:
serviceName: frontend
servicePort: 80
path: /
- host: api.ourdomain.com
http:
paths:
- backend:
serviceName: api
servicePort: 8000
path: /
- backend:
serviceName: esg
servicePort: 8000
path: /cron/
- backend:
serviceName: esg-bigquery-migration
servicePort: 8000
path: /cron/big-query/
- backend:
serviceName: esg
servicePort: 8000
path: /task/
- backend:
serviceName: esg-trial
servicePort: 8000
path: /task/connections/update/trial/
- backend:
serviceName: esg-advanced
servicePort: 8000
path: /task/connections/update/advanced/
- backend:
serviceName: esg-professional
servicePort: 8000
path: /task/connections/update/professional/
- backend:
serviceName: esg-enterprise
servicePort: 8000
path: /task/connections/update/enterprise/
From documentation:
Starting in Version 0.22.0, ingress definitions using the annotation
nginx.ingress.kubernetes.io/rewrite-target are not backwards
compatible with previous versions. In Version 0.22.0 and beyond, any
substrings within the request URI that need to be passed to the
rewritten path must explicitly be defined in a capture group.
In some scenarios the exposed URL in the backend service differs from the specified path in the Ingress rule. Without a rewrite any request will return 404. To circumvent this you can set the annotation ingress.kubernetes.io/rewrite-target to the path expected by the service. Please, refer to documentation to learn more about this. Also, you should add following line to your annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1

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 not working on redirect on some path like "/myapp", but only working for "/"

I have a container running on url like http://localhost:8000/ps/app/ui/?pid=201. The container is deployed on kubernetes and exposed to a service as "ps-app-ui:8000"
I want to create an ingress which can be accessible from outside. Ingress template is like:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ps-ingress
spec:
rules:
- http:
paths:
- path: /myapp/
backend:
serviceName: ps-app-ui
servicePort: 8000
The problem is its not working with this ingress. I also tried adding "ingress.kubernetes.io/rewrite-target: /" but had no success. Can anyone help me to get my application accessible via "http://INGRESS-IP/myapp/ps/app/ui/?pid=201"
Will be really grateful.
Ingress version 0.22.0 or higher has changed the way how rewrite-target works.
You'll need to regex-match the path and add it to the rewrite-target.
nginx.ingress.kubernetes.io/rewrite-target: /$2
...
...
rules:
- host: rewrite.bar.com
http:
paths:
- backend:
serviceName: http-svc
servicePort: 80
path: /something(/|$)(.*)
Refer to changelog here.
How to article here
I'm thinking
- path: /myapp/
matches your app at http://myapp/myapp/
So if I have a definition:
- host: app.example.com
http:
paths:
- path: /myapp
This would be http://app.example.com/myapp
if you want to use http://myapp/ps/app/ui/?pid=201 you need to:
make sure that your operating system translates myapp to a IP address where your ingress controller is listening
add the host myapp to the ingress
you can leave the path empty (assuming that your application is handling the complete /ps/app/ui/?pid=201 path)
This results in
rules:
- host: myapp
http:
paths:
- backend:
serviceName: ps-app-ui
servicePort: 8000
This ingress will forward all traffic to the host myapp to your service