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)。

解决方案:

  1. 将 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;
             }
         }
     }
    
  2. 将此行添加到我的 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;"]
    

参考: