kubernetes 入口 nginx 重写部分工作 - 有时错误的上下文路径

kubernetes ingress nginx rewrite partially working - sometimes wrong context path

我正在使用 GKE 设置简单的 Kubernetes 集群。我已经将 Java Spring 启动应用程序设置为 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: /
  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

我发现它可能与这个问题密切相关:。提供的解决方案是编写以下 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。

如何解决这个 url-使用入口重写的问题?


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

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

现在一切正常。

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

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

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

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

当然您也可以将这些 header 添加到应用程序的响应中,以便将它们发送到您的浏览器(我相信您期望实现的目标)但浏览器并不关心这些 headers 所以这样做没有意义。

如果你还想自己尝试证明,可以在ingress中加上这个注解object:

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

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

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