将Spring Cloud Gateway路由迁移至Kubernetes Ingress的重写规则问题
解决Kubernetes Ingress单个路由重写的问题
你遇到的核心问题是全局设置的rewrite-target会作用于所有路径规则,导致每个路由都使用同一个重写逻辑,和Spring Cloud Gateway的路由级重写不匹配。下面是两种符合你需求的解决方案:
方案一:调整路径正则与全局Rewrite Target
这种方法通过精准的正则捕获组,让全局rewrite-target自动适配不同路由的重写需求,完全匹配你原来的Spring Cloud Gateway规则:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: routing-ingress annotations: nginx.ingress.kubernetes.io/use-regex: "true" # 全局重写目标,使用捕获组$1,对应每个路径中括号内的部分 nginx.ingress.kubernetes.io/rewrite-target: "$1" spec: rules: - http: paths: # 匹配/portal/api/clover/**,捕获/portal后的/api/clover/xxx部分 - path: /portal(/api/clover/.*) pathType: ImplementationSpecific backend: service: name: clover-service port: number: 9500 # 匹配/portal/auth/**,捕获/portal后的/auth/xxx部分 - path: /portal(/auth/.*) pathType: ImplementationSpecific backend: service: name: auth-service port: number: 8900 # 匹配所有其他请求,捕获完整路径(包括/portal/xxx或/xxx) - path: /(.*) pathType: ImplementationSpecific backend: service: name: frontend-service port: number: 3000
工作原理:
- 当请求
/portal/api/clover/abc时,匹配第一个路径规则,捕获组$1为/api/clover/abc,重写后转发到clover-service:9500/api/clover/abc - 当请求
/portal/auth/login时,匹配第二个路径规则,捕获组$1为/auth/login,重写后转发到auth-service:8900/auth/login - 当请求
/portal/home或/about时,匹配第三个路径规则,捕获组$1为完整请求路径,直接转发到frontend-service:3000,路径保持不变
方案二:使用Configuration Snippet添加路由级重写
如果你更倾向于为每个路由单独定义重写逻辑(和Spring Cloud Gateway的配置风格更接近),可以使用configuration-snippet添加Nginx原生的rewrite规则:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: routing-ingress annotations: nginx.ingress.kubernetes.io/use-regex: "true" # 为特定路径添加单独的rewrite规则 nginx.ingress.kubernetes.io/configuration-snippet: | rewrite ^/portal/api/clover/(.*)$ /api/clover/$1 break; rewrite ^/portal/auth/(.*)$ /auth/$1 break; spec: rules: - http: paths: - path: /portal/api/clover/(.*) pathType: ImplementationSpecific backend: service: name: clover-service port: number: 9500 - path: /portal/auth/(.*) pathType: ImplementationSpecific backend: service: name: auth-service port: number: 8900 - path: /(.*) pathType: ImplementationSpecific backend: service: name: frontend-service port: number: 3000
工作原理:
configuration-snippet中的rewrite规则会直接注入到Nginx的配置中,仅对匹配对应路径的请求生效- 前两个路由的请求会被单独重写,第三个路由的请求直接转发,路径保持不变
关键注意事项
- 路径顺序:一定要把更具体的路径规则(比如
/portal/api/clover/**)放在通用规则(比如/(.*))前面,Ingress会按配置顺序匹配第一个符合的路径 - API版本:
extensions/v1beta1已经被废弃,推荐使用networking.k8s.io/v1,对应的backend字段格式也需要调整(使用service.name和service.port.number) - 正则开关:必须添加
nginx.ingress.kubernetes.io/use-regex: "true",否则路径会被当作前缀或精确匹配,正则捕获组不会生效
内容的提问来源于stack exchange,提问作者codejunkie




