首页 > 解决方案 > 如何使用 nginx 捕获组附加前缀以重写规则

问题描述

我目前正在尝试重写 kubernetes ingress 中的四个路径。

这三个都完成了,但是静态文件路径有点棘手。

我的前端路径是/$1-> /(.*)web-front-cluster-ip-service

我还需要重写所有/img/$1-> /img/(.*)apollo-api-cluster-ip-service

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: servers-ingress-service
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - http:
        paths:
          - backend:
              serviceName: apollo-api-cluster-ip-service
              servicePort: 4000
            path: /apollo_api/?(.*)
          - backend:
              serviceName: rest-api-cluster-ip-service
              servicePort: 5000
            path: /rest/?(.*)
          - backend:
              serviceName: web-front-cluster-ip-service
              servicePort: 6000
            path: /?(.*)
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: statics-ingress-service
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /img/$1
spec:
  rules:
    - http:
        paths:
        - backend:
            serviceName: apollo-api-cluster-ip-service
            servicePort: 4000
          path: /img/?$(.*)

我当前的设置如上所示,但由于未知原因,我无法到达第二条路线配置的路线。

所以我想要做的是将两条路由组合在一起并提供前缀来捕获匹配的组/img

如果我做

      - backend:
          serviceName: apollo-api-cluster-ip-service
          servicePort: 6000
        path: /?(.*)

apollo-api当我需要任何不以开头的路由被路由到时,它会将所有内容/img路由到web-front

所以我需要像下面这样的东西

      - backend:
          serviceName: apollo-api-cluster-ip-service
          servicePort: 4000
        path: /img?(.*) <- somehow add /img to $(.*) because currently it rewrites `/img/static.png` -> `/static.png` but I need `/img/static.png` -> `/img/static.png`.

任何帮助,将不胜感激。

标签: nginxkuberneteskubernetes-ingress

解决方案


重写目标文档中所述:

!!!注意 从版本 0.22.0 开始,使用注解 nginx.ingress.kubernetes.io/rewrite-target 的入口定义与以前的版本不向后兼容。在版本 0.22.0 及更高版本中,请求 URI 中需要传递到重写路径的任何子字符串都必须在捕获组中明确定义。

!!!注意 捕获的组按时间顺序保存在编号占位符中,格式为 $1、$2 ... $n。这些占位符可以用作 rewrite-target 注释中的参数。

所以我想你的第二个入口应该是这样的:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: statics-ingress-service
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /img/$2
spec:
  rules:
    - http:
        paths:
        - backend:
            serviceName: apollo-api-cluster-ip-service
            servicePort: 4000
          path: /img(/|$)(.*)

在这种情况下$2会反映(.*)


推荐阅读