Reputation: 8859
I have the following that config that works when I try <NodeIP>:30080
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 3
template:
metadata:
labels:
name: app-node
spec:
containers:
- name: app
image: myregistry.net/repo/app:latest
imagePullPolicy: Always
ports:
- containerPort: 8080
env:
- name: NODE_ENV
value: production
---
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
selector:
name: app-node
ports:
- protocol: TCP
port: 80
targetPort: 8080
nodePort: 30080
type: NodePort
I am trying to use an Ingress:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: nginx-ingress
spec:
rules:
- host: myhost.com
http:
paths:
- path: /app
backend:
serviceName: app-service
servicePort: 80
myhost.com
works with the nginx intro screen, but myhost.com/app
gives 404 Not Found
. Where is the issue in my setup?
UPDATE:
- path: /
backend:
serviceName: app-service
servicePort: 80
If I do root path it works, but how come /app
doesn't?
Upvotes: 31
Views: 59866
Reputation: 80
Other answers are already solving the issue, but there is another way without the annotations part in the yaml file. You have 2 ways to use ingress in Kube: with path or with host.
Imagine we have 2 services: api and dashboard.
With path, you would use myapp.example.fr/api
and myapp.example.fr/dashboard
.
With host, you would use api.myapp.example.fr
and dashboard.myapp.example.fr
The answers above explained how to do with path, here is how you can do with host.
In your ingress you can set the path to /
and your api routes will stay the same:
- path: /
pathType: Prefix
However, this can be a bad solution if you have several services. In this case, you can use multiple hosts:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
ingressClassName: nginx
rules:
- host: api.myapp.example.fr <-- first host
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
- host: dashboard.myapp.example.fr. <-- second host
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: dashboard-service
port:
number: 8501
You can then access your 2 or more services through each dns.
Note that if you use Streamlit you will need to use /
path or add streamlit run dashboard.py --server.baseUrlPath=<dashboard_path_here>
when you run the dashboard.
Also note that you should not forget to deploy the nginx ingress controller (easy to do with helm).
Upvotes: 0
Reputation: 11
I ran into similar problem, but I have set PATHBASE in k8s yml, found out my NET8 Api didn't use the pathbase setting
In Program.cs add this
app.UsePathBase(builder.Configuration["PATHBASE"] ?? "/");
and yml like this
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapi-deployment
spec:
selector:
matchLabels:
app: myapi
template:
metadata:
labels:
metadata:
labels:
app: myapi
spec:
containers:
- name: myapi
image: my.azurecr.io/myapi
env:
- name: "ASPNETCORE_ENVIRONMENT"
value: "PROD"
- name: PATHBASE <------------
value: "/api" <------------
volumeMounts:
- name: azure-fileshare
mountPath: /app/Uploads
Upvotes: 1
Reputation: 199
As specified by brandon-barnett the issue is coming from the path but after reading the link he shared, I realised that a more specific rewrite rule would have to be specified for it to work. In my case
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: rewrite
namespace: default
spec:
ingressClassName: nginx
rules:
- host: rewrite.bar.com
http:
paths:
- path: /something(/|$)(.*)
pathType: Prefix
backend:
service:
name: http-svc
port:
number: 80
The trick is with /$2 at annotation and (/|$)(.*) at the path. So what this rewrite does is that it picks everything that comes after something/ and replaces $2 with it, so:
Upvotes: 11
Reputation: 576
In case it's useful to others:
I had the same thing, and it was nothing to do with Kubernetes Ingress Nginx. It was the Nginx server in my pod running the UI (Vue.JS in my case).
Solution:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
server {
listen 80;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
}
# production stage
FROM nginx:stable-alpine as production-stage
COPY nginx.conf /etc/nginx/
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Ref: https://stackoverflow.com/a/54193517/4059810
Upvotes: 4
Reputation: 1095
Your ingress definition creates rules that proxy traffic from the {path}
to the {backend.serviceName}{path}
. In your case, I believe the reason it's not working is that /app
is proxied to app-service:80/app
but you're intending on serving traffic at the /
root. Try adding this annotation to your ingress resource: nginx.ingress.kubernetes.io/rewrite-target: /
Source: https://github.com/kubernetes/ingress-nginx/tree/master/docs/examples/rewrite
Upvotes: 35