Kubernetes Ingress 非根路径 404 Not Found
Kubernetes Ingress non-root path 404 Not Found
我有以下配置,当我尝试 <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
我正在尝试使用 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
使用 nginx 介绍屏幕,但 myhost.com/app
给出 404 Not Found
。我的设置哪里出了问题?
更新:
- path: /
backend:
serviceName: app-service
servicePort: 80
如果我使用根路径它可以工作,但为什么 /app
不行?
您的入口定义创建了代理流量从 {path}
到 {backend.serviceName}{path}
的规则。在您的情况下,我认为它不起作用的原因是 /app
被代理到 app-service:80/app
但您打算在 /
根目录提供流量。尝试将此注释添加到您的入口资源:nginx.ingress.kubernetes.io/rewrite-target: /
来源:https://github.com/kubernetes/ingress-nginx/tree/master/docs/examples/rewrite
如 brandon-barnett 所述,问题出在路径上,但在阅读了他分享的 link 之后,布兰登对你大加赞赏,我意识到必须指定一个更具体的重写规则让它工作。就我而言
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
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
诀窍是在注释处使用 /$2 并在路径处使用 (/|$)(.*)。那么这个重写做了什么,它选择了 something/ 之后的所有内容并用它替换 $2,所以:
- rewrite.bar.com/something 重写为 http-svc:80/
- rewrite.bar.com/something/ 重写为 http-svc:80/
- rewrite.bar.com/something/new 重写为 http-svc:80/new
- rewrite.bar.com/something/new/old 重写为 http-svc:80/new/old
如果它对其他人有用:
我也是一样的,跟Kubernetes Ingress Nginx没关系。这是我 pod 运行 UI 中的 Nginx 服务器(在我的例子中是 Vue.JS)。
解决方案:
- 将 nginx.conf 文件添加到我的 UI 应用程序。
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;
}
}
}
- 将此行添加到我的 Vue.js 应用程序的 Dockerfile 中,以将 nginx.conf 复制到您的容器中。
# 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;"]
参考:
我有以下配置,当我尝试 <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
我正在尝试使用 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
使用 nginx 介绍屏幕,但 myhost.com/app
给出 404 Not Found
。我的设置哪里出了问题?
更新:
- path: /
backend:
serviceName: app-service
servicePort: 80
如果我使用根路径它可以工作,但为什么 /app
不行?
您的入口定义创建了代理流量从 {path}
到 {backend.serviceName}{path}
的规则。在您的情况下,我认为它不起作用的原因是 /app
被代理到 app-service:80/app
但您打算在 /
根目录提供流量。尝试将此注释添加到您的入口资源:nginx.ingress.kubernetes.io/rewrite-target: /
来源:https://github.com/kubernetes/ingress-nginx/tree/master/docs/examples/rewrite
如 brandon-barnett 所述,问题出在路径上,但在阅读了他分享的 link 之后,布兰登对你大加赞赏,我意识到必须指定一个更具体的重写规则让它工作。就我而言
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
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
诀窍是在注释处使用 /$2 并在路径处使用 (/|$)(.*)。那么这个重写做了什么,它选择了 something/ 之后的所有内容并用它替换 $2,所以:
- rewrite.bar.com/something 重写为 http-svc:80/
- rewrite.bar.com/something/ 重写为 http-svc:80/
- rewrite.bar.com/something/new 重写为 http-svc:80/new
- rewrite.bar.com/something/new/old 重写为 http-svc:80/new/old
如果它对其他人有用:
我也是一样的,跟Kubernetes Ingress Nginx没关系。这是我 pod 运行 UI 中的 Nginx 服务器(在我的例子中是 Vue.JS)。
解决方案:
- 将 nginx.conf 文件添加到我的 UI 应用程序。
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; } } }
- 将此行添加到我的 Vue.js 应用程序的 Dockerfile 中,以将 nginx.conf 复制到您的容器中。
# 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;"]
参考: