You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同主机不同路径Ingress配置问题:/path2/login访问404排查

Nginx Ingress路径重写导致的404问题分析

问题现象

  • dev.app.com/login:无论直接访问还是从根路径重定向过来,均能正常转发至path1svc并返回正确内容。
  • dev.app.com/path2/login:仅从dev.app.com/path2重定向过来时可用;直接在浏览器输入该URL或跳转后刷新页面,会触发Nginx 404 Not Found错误。

当前Ingress配置

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-fe
  annotations:
    nginx.ingress.kubernetes.io/use-regex: 'true'
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  tls:
    - hosts:
        - dev.app.com
      secretName: tls-secret-con
  rules:
    - host: dev.app.com
      http:
        paths:
          - path: /(.*)
            pathType: ImplementationSpecific
            backend:
              service:
                name: path1svc
                port:
                  number: 80
          - path: /path2(/|$)(.*)
            pathType: ImplementationSpecific
            backend:
              service:
                name: path2svc
                port:
                  number: 80

问题原因分析

  1. 路径匹配顺序错误
    Nginx Ingress的正则路径匹配是从上到下按定义顺序执行,第一个匹配的规则会被优先使用。配置中第一个路径/(.*)是贪婪匹配,会捕获所有以/开头的请求(包括/path2/login),导致第二个针对/path2的规则永远不会被触发。直接访问或刷新/path2/login时,请求会被转发到path1svc,而该服务没有对应资源,因此返回404。

  2. 重定向场景的特殊逻辑
    当访问/path2时,请求会被第二个路径规则匹配(符合/path2(/|$)(.*)的正则),转发到path2svc。path2svc返回重定向到/path2/login后,前端可能在客户端完成路由跳转(未发起新的后端请求),因此暂时可用;但刷新页面时会发起新的HTTP请求,此时又会被第一个路径规则捕获,触发404。

  3. Rewrite-Target捕获组错误
    第二个路径规则的正则/path2(/|$)(.*)定义了两个捕获组:

  • 第一个捕获组:(/|$)(匹配斜杠或路径结束)
  • 第二个捕获组:(.*)(匹配后续内容)
    但全局配置的rewrite-target: /$1只会使用第一个捕获组,导致转发到path2svc的路径错误(比如/path2/login会被重写成/而非/login),即使规则被触发也无法正确访问后端资源。

解决方案

修正后的Ingress配置

调整路径顺序(将具体路径放在前面),并为/path2路径单独指定正确的rewrite规则:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-fe
  annotations:
    nginx.ingress.kubernetes.io/use-regex: 'true'
    # 全局rewrite-target保留给默认路径
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  tls:
    - hosts:
        - dev.app.com
      secretName: tls-secret-con
  rules:
    - host: dev.app.com
      http:
        paths:
          - path: /path2(/|$)(.*)
            pathType: ImplementationSpecific
            backend:
              service:
                name: path2svc
                port:
                  number: 80
            # 为该路径单独指定rewrite-target,使用第二个捕获组
            annotations:
              nginx.ingress.kubernetes.io/rewrite-target: /$2
          - path: /(.*)
            pathType: ImplementationSpecific
            backend:
              service:
                name: path1svc
                port:
                  number: 80

简化替代方案

如果不需要匹配/path2和/path2/两种格式,可以拆分路径规则,避免复杂正则:

paths:
  - path: /path2/(.*)
    pathType: ImplementationSpecific
    backend:
      service:
        name: path2svc
        port:
          number: 80
  - path: /path2
    pathType: ImplementationSpecific
    backend:
      service:
        name: path2svc
        port:
          number: 80
  - path: /(.*)
    pathType: ImplementationSpecific
    backend:
      service:
        name: path1svc
        port:
          number: 80

内容的提问来源于stack exchange,提问作者gospecomid12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 19:20:30