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 参数进行配置。
我正在使用 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
。
我发现它可能与这个问题密切相关:
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 参数进行配置。