【问题标题】:Kubernetes Multiple Path RewritesKubernetes 多路径重写
【发布时间】:2022-01-22 04:34:50
【问题描述】:

好吧,这个问题的各种排列已经被问到了,我觉得问得很糟糕;我把毛巾扔了进去,很好奇是否有人能指出我正确的方向(或指出我错在哪里)。我继续尝试了一些来自文档的examples,但无济于事(见下文)。

我正在尝试使用 Ingress 控制器将流量路由到 Kubernetes 下的适当位置。

服务器设置

我有一个服务器 myserver.com 和三个服务运行在:

myserver.com/services/

myserver.com/services/service_1/

myserver.com/services/service_2/

请注意,我没有(故意)对myserver.com/ 做任何事情。

三个位置中的每一个都在运行一个 web 应用程序。比如myserver.com/services/service_2需要在myserver.com/services/service_2/static/css加载css文件等等……

Kubernetes 入口

为了管理网络,我使用了一个 Kubernetes Ingress 控制器,我在下面定义了它。 CORS 注释与 super 无关,但我已将它们包括在内以消除任何混淆。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myServices
  namespace: myServices
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-origin: '$http_origin'
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/use-regex: "true"

spec:
  ingressClassName: nginx
  tls:
  - hosts:
      - myserver.com
  rules:
  - host: myserver.com
    http:
      paths:
      - path: /services
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80
      - path: /services/service_1(/|$)
        pathType: Prefix
        backend:
          service:
            name: web-service-1
            port:
              number: 80
      - path: /services/service_2(/|$)
        pathType: Prefix
        backend:
          service:
            name: web-service-2
            port:
              number: 80

目标

我注意到做一些有用的事情是提供一些路径示例。从下面的示例中看起来路径并没有那么复杂。我认为这就是我所追求的。请注意,我希望每个服务都能够解析其 css 和图像文件。

myserver.com/services -> myserver.com/services
myserver.com/services/xxx/xxx -> myserver.com/services/xxx/xxx
myserver.com/services/service_1 -> myserver.com/services/service_1
myserver.com/services/service_1/xxx/xxx -> myserver.com/services/service_1/xxx/xxx
myserver.com/services/service_2/xxx/xxx -> myserver.com/services/service_2/xxx/xxx


尝试

我知道这个问题与nginx.ingress.kubernetes.io/rewrite-target 规则及其与我定义的路径的交互有很大关系。

我知道我不想要nginx.ingress.kubernetes.io/rewrite-target: $1,因为访问myserver.com/services 时会得到500 分

我知道我不想要nginx.ingress.kubernetes.io/rewrite-target: $1/$2,因为当我访问myserver.com/services/service_1 时,我实际上得到了页面上呈现的myserver.com/services 的部分内容。

SO 尝试 1

我还尝试从this 问题复制已接受的解决方案。

在这个尝试中我设置了

nginx.ingress.kubernetes.io/rewrite-target: "/$1" 和服务路径之一

- path: /(services/service_1(?:/|$).*)

当我访问 myserver.com/services/service_1/xyz 时,来自 myserver.com/services/service_1 的 HTML 被渲染。

结论性思考

路径重写和路径规则有些地方不太对劲。有什么建议吗?

【问题讨论】:

  • 我对这个问题很感兴趣,所以我将a complete example configuration 放在一起,但我无法重现该问题。路径规则似乎按设计工作。如果您部署相同的示例,它是否有效?如果是这样,您能否提供一个类似的示例来重现您的问题?
  • 您使用的是哪个 Kubernetes 版本?
  • @larsks 哇,我真的很感激。我用你的路径替换了我的路径,但是当我访问 myserver.com/services/service_2/should-404 之类的东西时,它会将我重定向到 myserver.com/services/service_2 的索引页面而不是 404ing。我在服务中看到了这种行为。 @Mikola S。我正在使用 Kubernetes 1.23.1
  • 感谢您的信息。 Larsks 的解决方案看起来不错 - 正如我测试的那样,它正在将正确的路径重定向到 web-service-2 中的 pod - 请检查 web-service-2 (kubectl logs {pod-name}) 中的 pod 日志并检查直接重定向的路径到吊舱?

标签: nginx kubernetes


【解决方案1】:

您在最近的评论中报告的问题已通过查看 nginx-ingress 文档中的 rewrite example 得到解决。

rewrite-target 注释配置入口,以便将匹配的路径重写为该值。由于您已指定静态值 /,因此任何符合您的入口规则的内容都将被重写为 /,这正是您所看到的行为。

解决方案是捕获我们关心的路径部分,然后在rewrite-target注解中使用它。例如:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myservices
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-origin: '$http_origin'
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/ssl-redirect: "false"

spec:
  ingressClassName: nginx
  rules:
  - host: myserver.com
    http:
      paths:
      - path: /services/service_1(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: webservice-service1
            port:
              number: 80
      - path: /services/service_2(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: webservice-service2
            port:
              number: 80
      - path: /services(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: webservice
            port:
              number: 80

在这里,我们修改了匹配表达式,使它们看起来像:

      - path: /services/service_1(/|$)(.*)

第二个捕获组(.*) 捕获路径之后的所有内容 字面上匹配的部分。然后我们使用该捕获组 ($2, 因为它是第二组)在rewrite-target注解中:

    nginx.ingress.kubernetes.io/rewrite-target: /$2

有了这个配置,请求/services/service_2 结果:

This is service2.

但是对/services/service_2/foo/bar 的请求会导致:

<html><head><title>404 Not Found</title></head><body>
<h1>Not Found</h1>
The URL you requested (/foo/bar) was not found.
<hr>
</body></html>

查看后端服务器日志,我们看到:

10.42.0.32 - - [21/Jan/2022:20:33:23 +0000] "GET / HTTP/1.1" 200 211 "" "curl/7.79.1"
10.42.0.32 - - [21/Jan/2022:20:33:45 +0000] "GET /foo/bar HTTP/1.1" 404 311 "" "curl/7.79.1"

我已更新 my example repository 以匹配此配置。

【讨论】:

    猜你喜欢
    • 2019-05-03
    • 1970-01-01
    • 2021-10-25
    • 1970-01-01
    • 2021-10-23
    • 2021-12-17
    • 2021-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多