【问题标题】:kubernetes ingress nginx rewrite partially working - sometimes wrong context pathkubernetes 入口 nginx 重写部分工作 - 有时错误的上下文路径
【发布时间】:2020-01-20 23:21:27
【问题描述】:

我正在使用 GKE 设置简单的 Kubernetes 集群。我已将 Java Spring boot 应用程序设置为 Kubernetes 部署和服务(类型为 Load Balancer,暴露在端口 80 上)。当使用服务的外部 IP 直接访问时,此应用运行良好。

我还安装了nginx-ingress for GKE 并提供了以下 Ingress 资源:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/enable-rewrite-log: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$1
  name: rewrite
  namespace: default
spec:
  rules:
  - host: "myhost.ddns.net"
    http:
      paths:
      - backend:
          serviceName: app-java
          servicePort: 80
        path: /app-java/?(.*)

从现在开始,有趣的事情发生了:

问题 1:如果我访问位于 http://myhost.ddns.net/app-java 的站点 - 我只获得 HTML 文件,所有其他资源都有 404(从 http://myhost.ddns.net/foo.js 下载尝试而不是 http://myhost.ddns.net/app-java/foo.js

问题 2:如果我访问位于 http://myhost.ddns.net/app-java/ 的站点 - 我会同时获得 HTML 文件以及所有脚本和图像。但是,当我深入挖掘时,通过 POST 发送表单内容失败。它的HTML代码是:

<form action="/select" method="post">

尝试访问http://myhost.ddns.net/select 而不是http://myhost.ddns.net/app-java/select

我发现它可能与这个问题密切相关:Thymeleaf template (in Spring boot application) behind reverse proxy not forming url's correctly。提供的解决方案是编写以下 nginx 反向代理配置:

location /app-java {
    proxy_pass http://10.0.0.0:80;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host $host:$server_port;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Prefix /app-java;
}

但是,我不知道如何将其转换为入口资源 yaml。

如何使用 ingress 解决这个 url 重写问题?


编辑:在 @HelloWorld 的提示之后,我重新组织了应用程序以在 /app-java 上下文路径上提供内容(使用 Spring Boot 2 属性 server.servlet.context-path=/app-java)。之后,我将rewrite-target 更改为:

nginx.ingress.kubernetes.io/rewrite-target: /app-java/$1

现在它工作正常。

【问题讨论】:

    标签: url-rewriting kubernetes-ingress nginx-ingress


    【解决方案1】:

    我看到您正在尝试让您的浏览器为所有正在运行的路径添加前缀。

    我相信您一定误解了X-Forwarded-Prefix 的概念以及Thymeleaf template (in Spring boot application) behind reverse proxy not forming url's correctly 中描述的任何内容,其中社区成员描述了如何将此标头传递给您的应用程序。如果你想尝试一下,看看它是如何工作的,你可以通过简单地将这个注解添加到你的入口对象来实现:

    nginx.ingress.kubernetes.io/x-forwarded-prefix: "/app-java"
    

    但请注意,这并不能解决您的问题。

    当然,您也可以将这些标头添加到应用程序的响应中,以便将它们发送到您的浏览器(我相信您希望实现),但浏览器并不关心这些标头,因此没有必要这样做它。

    如果你还想自己尝试并证明,可以在 ingress 对象中加入这个注解:

    nginx.ingress.kubernetes.io/configuration-snippet: |
        more_set_headers "X-Forwarded-Prefix: /app-java";
    

    据我所知,解决此问题的唯一方法是修改您的应用程序代码,使其以正确的路径响应。

    您会发现许多应用程序使用可自定义的基本路径,可以通过 env 变量、配置文件或 cli 参数进行配置。

    【讨论】:

    • 非常感谢您的回答!我可以让我的应用程序在/app-java 上下文路径上运行。但是,我需要禁用 URL 重写,但保持映射路径到正确的后端。我会尝试这样做并发布我的解决方案!
    • 感谢您的帮助,它现在正在工作:)。我已编辑问题以包含修复。
    猜你喜欢
    • 2021-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    • 2020-12-30
    • 1970-01-01
    • 1970-01-01
    • 2019-01-16
    相关资源
    最近更新 更多