In k8s, I deploy an app running with clusterIP(port:5270). Then I want to set up an ingress-nginx to forward the request to this app. here is the configure:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: k8s-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /core
pathType: Prefix
backend:
service:
name: core-service
port:
number: 5270
My service is a NestJS application, and this is my request to this service :
192.168.10.131/core/api/myorder/get-order-by-id?id=1
"myorder" is one of the module I have, and I add a global prefix by using app.setGlobalPrefix('api');
in the main.ts
When enter the request path, I will get :
{"statusCode":404,"message":"ENOENT: no such file or directory, stat '/app/client/index.html'"}
It seems that the ingress can send the request to the pods, but it will look for "/app/client/index.html" which is not expected. It should access the myorder module. there is a client folder under the /app.
If I use the Nodeport
to access the service instead of the ingress, everything is fine.
Here is the change I have since I got your guy's solution:
I deployed a simple nest app, a very simple one:
It is only has a getHalleo function. Here is the main.js:
Here is the yaml for deploying at k8s:
apiVersion: apps/v1
kind: Deployment
metadata:
name: k8-ingress-test1
labels:
app: k8-ingress-test
spec:
replicas: 1
selector:
matchLabels:
app: k8-ingress-test
template:
metadata:
labels:
app: k8-ingress-test
spec:
containers:
- name: k8-ingress-test
image: 192.168.10.145:8080/k8s-ingress-test
imagePullPolicy: Always
ports:
- containerPort: 3146
---
apiVersion: v1
kind: Service
metadata:
name: k8-ingress-test-service
spec:
selector:
app: k8-ingress-test
ports:
- protocol: TCP
port: 3146
targetPort: 3146
Here is my new ingress-nginx:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: k8s-ingress
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /hello
pathType: Prefix
backend:
service:
name: k8-ingress-test-service
port:
number: 3146
I deleted "nginx.ingress.kubernetes.io/rewrite-target: /". Here is my access URL:
192.168.10.131/hello
Based on my understanding, it should catch "/hello" and send "/hello" to the test app. since there is no 'hello' module in the app, I get the following :
{"statusCode":404,"message":"Cannot GET /hello","error":"Not Found"}
so, this is the reason why we have :
nginx.ingress.kubernetes.io/rewrite-target: /
this will edit the request from "/hello" to "/". In another word, it would send "/" to the test app instead of "/hello". so I can hit the getHello function.
For the 192.168.10.131/core/api/myorder/get-order-by-id?id=1
, I can not do nginx.ingress.kubernetes.io/rewrite-target: /
because it would rewrite the request to /
which is wrong.
So, is there any way that I can catch the request including core
, and delete the core
part then send the /api/myorder/get-order-by-id?id=1
to the port 5270(and it also can catch "hello" then delete it then send "/" to the port 3146)?
Thanks
CodePudding user response:
I think you might have some mis-understanding between the nginx ingress's rewrite-target
annotation and your NestJS application's redirection
.
With the following annotation:
nginx.ingress.kubernetes.io/rewrite-target: /
your request path /core/api/myorder/get-order-by-id?id=1
will rewrite to /
, not /api/myorder/get-order-by-id?id=1
.
Check the docs for more info: ingress-nginx annotations/#rewrite and examples.
Not familiar with NestJS, I guess your application doesnot return correctly to root path /
.
What you probably need is Redirection
in a NestJS application. NestJS Controllers Redirection
CodePudding user response:
I solved the problem:
I add this to my yaml :
nginx.ingress.kubernetes.io/rewrite-target: /$2
and here is my path
- path: /hello(/|$)(.*)
so, we can have the following rewrite
/hello writes to /
/hello/ rewrites to /
/hello/new rewrites to /new
similar to the core