Kubernetes入口:nginx,使用正则表达式匹配精确的URL路径

Kubernetes入口:nginx,使用正则表达式匹配精确的URL路径,nginx,kubernetes,kubernetes-ingress,Nginx,Kubernetes,Kubernetes Ingress,我有几个豆荚,我正试图匹配各自服务的URL 请注意,我需要使用nginx.ingres.kubernetes.io/重写目标来解决此问题,而不是nginx.ingres.kubernetes.io/重写目标 我的入口配置文件如下所示。请注意,/api/tile服务器/没有任何正则表达式模式 apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: ingress-service annotations:

我有几个豆荚,我正试图匹配各自服务的URL

请注意,我需要使用
nginx.ingres.kubernetes.io/重写目标
来解决此问题,而不是nginx.ingres.kubernetes.io/重写目标

我的入口配置文件如下所示。请注意,
/api/tile服务器/
没有任何正则表达式模式

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-service
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/use-regex: "true"
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
  namespace: default
spec:
  tls:
    - hosts:
        - example.com
      secretName: tls-secret
  rules:
    - host: example.com
      http:
        paths:
          - path: /?(.*)
            backend:
              serviceName: client
              servicePort: 80
          - path: /api/auth/?(.*)
            backend:
              serviceName: auth
              servicePort: 8000
          - path: /api/data/?(.*)
            backend:
              serviceName: data
              servicePort: 8001
          - path: /api/tile-server/
            backend:
              serviceName: tile-server
              servicePort: 7800
  • client
    pod是一款内置于nginx docker镜像中的react应用程序,运行良好
  • nginx.conf
    看起来像这样(如果有用的话)
  • auth
    data
    烧瓶API吊舱工作正常吗
  • 磁贴服务器
    也是一个烧瓶盒,但不需要进行任何模式匹配。我需要匹配准确的
    /api/tile服务器/
    URL
我尝试了以下模式,但失败了:

  • /api/tile服务器/
  • /api/tile服务器/?(*)
  • /api/tile服务器(/|$)?(.*)
我可以确认POD/服务在其正确的端口上运行,并且我可以通过节点端口访问它们,但不能通过负载平衡器/域访问它们。
什么样的模式才是与
/api/tile server/
URL完全匹配的正确模式?

从v1beta1移动到v1,并使用路径类型:Exact-

第一个解决方案为tile server创建单独的入口对象,并使用重写目标注释。这将起作用,因为具有相同主机的入口规则由入口控制器合并在一起,并且单独的入口对象允许每个对象使用不同的注释:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: tile-ingress-service
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rewrite-target: "/$2"
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
  namespace: default
spec:
  tls:
    - hosts:
        - example.com
      secretName: tls-secret
  rules:
    - host: example.com
      http:
        paths:
          - path: /api/tile-server(/|$)(.*)
            backend:
              serviceName: tile-server
              servicePort: 7800
第二种解决方案-重写当前入口以使用重写路径。一些正则表达式的更改是必要的

请注意非捕获组表示法:
(?:)
。这允许跳过这些组的编号,因为我需要与第一个组相关的所有内容才能使其工作,因为
重写目标:“/$1”

以下是重写的工作原理:

  • 验证服务(同样适用于数据服务)
  • 磁贴服务器服务:
  • 客户服务
请注意,以下路径将转发到客户端服务(其中xxx是任何字母数字字符串):


如果您希望将它们添加到其他/匹配服务,请在路径中的
(?:/|$)
之后添加

我们的kubernetes版本是1.18。v1仅在1.19+版本中可用。我们还有其他依赖于1.18版的服务。目前无法升级群集。还有其他解决方案吗?刚刚测试过,Inges本身就可以在我的集群上运行。您使用的是什么nginx入口?在尝试访问时,您看到的实际错误是什么?在这种情况下,“失败”对你意味着什么?到目前为止,我猜测tile服务器工作不正常,与ingress无关,但我需要更多信息来确认这一点。我使用EKS和AWS提供的ingress nginx,此处使用:。应用程序(磁贴服务器)返回404错误。点击example.com/api/auth将显示auth pod的根。点击example.com/api/tile-server/也不一样。磁贴服务器正在工作,因为我可以通过NodePort访问它(pod)。Tile服务器在其默认端口0.0.0.0:7800处运行,该端口是目标端口“我需要使用X来解决此问题,而不是X”-您的意思是什么?您是否需要使用它?您是否检查了nginx控制器的日志中的错误?我想我知道的足够多了。我会尽力给你写一个答案。至少有两种解决方案,我会尝试向你们解释。这很有效!另一个解决方案是使用子域,例如,并将流量路由到同一个负载平衡器,即,在我们的例子中,用于AWS NLB
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: tile-ingress-service
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rewrite-target: "/$2"
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
  namespace: default
spec:
  tls:
    - hosts:
        - example.com
      secretName: tls-secret
  rules:
    - host: example.com
      http:
        paths:
          - path: /api/tile-server(/|$)(.*)
            backend:
              serviceName: tile-server
              servicePort: 7800
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-service
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rewrite-target: "/$1"
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
  namespace: default
spec:
  tls:
    - hosts:
        - example.com
      secretName: tls-secret
  rules:
    - host: example.com
      http:
        paths:
          - path: /(.*)
            backend:
              serviceName: client
              servicePort: 80
          - path: /(api/auth(?:/|$).*)
            backend:
              serviceName: auth
              servicePort: 8000
          - path: /(api/data(?:/|$).*)
            backend:
              serviceName: data
              servicePort: 8001
          - path: /api/tile-server(?:/|$)(.*)
            backend:
              serviceName: tile-server
              servicePort: 7800
    /api/auth      --->  /api/auth
    /api/auth/     --->  /api/auth/
    /api/auth/xxx  --->  /api/auth/xxx
    /api/tile-server      --->  /
    /api/tile-server/     --->  /
    /api/tile-server/xxx  --->  /xxx
    /xxx  --->  /xxx
    /api/authxxx
    /api/dataxxx
    /api/tile-serverxxx