Kubernetes入口中基于Traefik路径的路由无法按预期工作

Posted

技术标签:

【中文标题】Kubernetes入口中基于Traefik路径的路由无法按预期工作【英文标题】:Traefik path based routing in kubernetes ingress not working as expected 【发布时间】:2019-06-22 02:13:36 【问题描述】:

我正在尝试在 Kubernetes 中使用 Traefik 入口控制器提供的基于路径的路由机制,但我在 url 重写时遇到了一些问题。

我的[更新]配置如下

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: traefik
    traefik.ingress.kubernetes.io/auth-type: "basic"
    traefik.ingress.kubernetes.io/auth-tls-insecure: "true"
    traefik.ingress.kubernetes.io/frontend-entry-points: "http,https"
    traefik.ingress.kubernetes.io/app-root: "/"
    traefik.ingress.kubernetes.io/rule-type: "PathPrefixStrip"
    traefik.ingress.kubernetes.io/rewrite-target: "/"
  name: webapp-ingress
  namespace: my-company
spec:
  rules:
   - host: local-ubuntu
   - http:
      paths:
      - path: /
        backend:
          serviceName: webapp
          servicePort: 80
      - path: /db
        backend:
          serviceName: db-manager
          servicePort: 8081

当我查看 db-manager (kubernetes) 服务的日志时,流量被路由到正确的服务,但 URL 仍以 /db 为前缀。 我对 PathPrefixStrip 的期望是,流量将在没有 /db 前缀的情况下路由到运行 db-manager 微服务的容器,该容器在后端侦听 / (http://db-manager:8081)。

我错过了什么吗? traefik 支持还是只有 nginx 支持? 提前感谢您的反馈。

[编辑]

更具体地说,我通过下面讨论的当前注释观察以下内容

traefik.ingress.kubernetes.io/rule-type: "PathPrefixStrip" traefik.ingress.kubernetes.io/rewrite-target: "/"

网址:http://local-ubuntu/db[OK] -> 200

然后其他资源正在加载,但指向错误的基本 url

例子:

资源网址为:http://local-ubuntu/public/css/bootstrap.min.css

但这应该是:http://local-ubuntu/db/public/css/bootstrap.min.css (当我手动尝试时有效)

我不确定我在当前配置中缺少什么。

【问题讨论】:

【参考方案1】:

关于未提供的静态内容,文档说明如下:

如果您的后端侦听根路径 (/) 但应该可以在特定前缀上路由,请使用 *Strip 匹配器。例如,PathPrefixStrip: /products 将匹配 /products,但也匹配 /products/shoes 和 /products/shirts。 由于路径在转发之前被剥离,因此您的后端应该在 / 上进行侦听。 如果您的后端正在提供资产(例如,图像或 javascript 文件),那么它很可能必须返回正确构建的相对 URL。 继续这个例子,后端应该返回 /products/shoes/image.png (而不是 Traefik 可能无法与同一后端关联的 /images.png)。 可以查询 X-Forwarded-Prefix 标头(自 Traefik 1.3 起可用)以动态构建此类 URL。

【讨论】:

不幸的是,即使这似乎是正确的方法,我也无法在入口定义中正确测试它。例如 traefik.ingress.kubernetes.io/rule-type: "PathPrefixStrip:/db" 当我查看 traefik ingress pod 的日志时会产生错误。 非常感谢我误解了,通过修改服务器端(微服务后端)我需要在返回具有正确路径的静态文件之前检查 X-Forwarded-Prefix 标头。 【参考方案2】:

非常感谢您在这件事上的帮助。

首先,我必须解决有关 yaml 文件中注释格式的问题。

所有以traefik为前缀的指令都需要双引号

例子:

traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip [不是 正确] traefik.ingress.kubernetes.io/rule-type: "PathPrefixStrip" [正确]

在第一种情况下,没有任何注释反映在入口中。

但我仍然无法正确路由流量。 使用当前配置,仅返回在 / 上提供的资源。 没有加载任何 js、css 或其他资源。 所以我想知道我是否需要使用 traefik.frontend.redirect.regex 指令。

【讨论】:

【参考方案3】:

尝试以下方法之一:

traefik.ingress.kubernetes.io/rule-type: "PathPrefixStrip"

traefik.ingress.kubernetes.io/rewrite-target: "/

它们都实现了相似的结果,但它们不同,并且它们的行为略有不同。

我会详细阅读我们的文档以了解差异:(https://docs.traefik.io/v1.7/configuration/backends/kubernetes/#general-annotations)

关于你的第二期:

资源网址是:local-ubuntu/public/css/bootstrap.min.css

但这应该是:local-ubuntu/db/public/css/bootstrap.min.css(当我尝试过时有效

您从请求中删除了该路径...您的数据库服务永远不会看到数据库前缀...它应该如何知道将它们重新添加?

您需要在 Web 应用程序中设置一个根 URL 来处理剥离的路径。

一旦你这样做了,你甚至可能根本不需要剥离路径,而是保持原样。如果您无法为您的应用程序设置基本 URL,您可能无法使用目录进行路由,而可能必须使用子域。

【讨论】:

【参考方案4】:

仅使用 traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip 波纹管我过去只向我的 k8s pod 发送子路径

apiVersion: networking.k8s.io/v1  
kind: Ingress  
metadata:  
  name: global-ingress  
  namespace: app  
  annotations:  
    kubernetes.io/ingress.class: "traefik"  
    traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip

【讨论】:

以上是关于Kubernetes入口中基于Traefik路径的路由无法按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

traefik Ingress https配置

traefik Ingress https配置

kubernetes 部署 traefik2.5

使用 Traefik 进行 Kubernetes 基本身份验证

kubernetes-traefik(二十一)

Kubernetes中traefik的会话保持和负载均衡策略配置方式