基于路径的路由无法与 Kubernetes 中的 Traefik Ingress 正确匹配

时间:2021-05-22 20:34:06

标签: kubernetes-ingress traefik-ingress

我有一个应用程序的 kubernetes 入口,我在其中使用基于路径的路由。 集群在 Google Cloud Kubernetes Engine 上运行,我的入口控制器是 Traefik v2.4。

我的一些链接是:

我想要的逻辑是让任何与路径匹配的 /* 进入前端,并将任何匹配的 /api/auth/* 路由到身份服务器。

但是,只路由精确路径,https://www.kwetter.org/ 有效,https://www.kwetter.org/profile 无效。 其他服务也一样,https://www.kwetter.org/api/auth 有效,https://www.kwetter.org/api/auth/users 无效。

我的入口看起来像这样:

kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
  name: traefik-ingress
  annotations:
    networking.gke.io/managed-certificates: kwetter-certificate
    traefik.ingress.kubernetes.io/router.entrypoints: web,websecure
spec:
  rules:
  - host: kwetter.org
    http:
      paths:
      - path: /
        backend:
          serviceName: kwetter-web-app
          servicePort: 80
      - path: /api/auth
        pathType: Prefix
        backend:
          serviceName: kwetter-identity-server
          servicePort: 80
  - host: www.kwetter.org
    http:
      paths:
      - path: /
        backend:
          serviceName: kwetter-web-app
          servicePort: 80
      - path: /api/auth
        pathType: Prefix
        backend:
          serviceName: kwetter-identity-server
          servicePort: 80

页面为前端加载正常,但静态文件返回 404,带有 traefik 消息“响应 404(后端未找到),路径的服务规则不存在”。完整的 url 是 https://kwetter.org/static/js/2.2217857e.chunk.js 并且带有 pathType: Prefix,这应该与“/”路径匹配。

enter image description here

谁能告诉我哪里出错了?

编辑解决方案: 我尝试了基于重写目标的解决方案,该解决方案与我的 API 控制器在它们所达到的服务上发生冲突。

最终我只是想在路径上放一颗星:

  • 路径:/*
  • 路径:/api/auth/*

这解决了整个路由问题,甚至不知道这是可能的。

1 个答案:

答案 0 :(得分:1)

<块引用>

我想要的逻辑是让任何与路径匹配的 /* 进入前端,并将任何匹配的 /api/auth/* 路由到身份服务器。

您需要在 .yaml 文件中使用正则表达式和 rewrite-target 注释。查看示例 Ingress .yaml 文件:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  name: rewrite
  namespace: default
spec:
  rules:
  - host: rewrite.bar.com
    http:
      paths:
      - backend:
          serviceName: http-svc
          servicePort: 80
        path: /something(/|$)(.*)

在此入口定义中,(.*) 捕获的任何字符都将分配给占位符 $2,然后将其用作 rewrite-target 注释中的参数。

例如,上面的入口定义将导致以下重写:

  • rewrite.bar.com/something 重写为 rewrite.bar.com/
  • rewrite.bar.com/something/ 重写为 rewrite.bar.com/
  • rewrite.bar.com/something/new 重写为 rewrite.bar.com/new

您可以找到有关 rewrite-target 注释 here 的更多信息。


您可以在 traefik documentation 中找到类似的提示。

# Replace path with regex
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: test-replacepathregex
spec:
  replacePathRegex:
    regex: ^/foo/(.*)
    replacement: /bar/$1

但在这种情况下,您可能会注意到 yaml 的一些差异。如果你想为traefik创建正则表达式,你可以测试解决方案here