nginx - 如果服务使用新的相对 url `Location` 标头响应,Kubernetes Ingress Nginx 控制器不会保留`path`
问题描述
path
TL;如果底层服务重定向到相对 URL ,DR Kubernetes Ingress Nginx 控制器不会保留
我有以下入口配置:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: release-name-test-tool
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: "kub.internal.company.com"
http:
paths:
- path: /api/test-tool(/|$)(.*)
pathType: Prefix
backend:
service:
name: test-tool-service
port:
name: http
后面test-tool-service
是一个通过 OAuth2 协议授权的 Spring Boot 应用程序。作为第一步,应用程序重定向到http://server:port/oauth2/authorization/test-tool
.
但在 K8S 部署path
中,响应的location
标头中缺少部分,我在重定向后收到404
(因为没有 Ingress 规则kub.internal.company.com/oauth2(/|$)(.*)
)
实际:
cache-control: no-cache, no-store, max-age=0, must-revalidate
content-length: 0
date: Wed, 11 Aug 2021 13:04:24 GMT
expires: 0
location: https://kub.internal.company.com/oauth2/authorization/test-tool
pragma: no-cache
strict-transport-security: max-age=15724800; includeSubDomains
x-content-type-options: nosniff
x-xss-protection: 1; mode=block
预期:
location: https://kub.internal.company.com/api/test-tool/oauth2/authorization/test-tool
因此,location
响应中的标头不包含path
来自 Ingress 配置。
部署在裸机 + Nginxproxy_pass
配置上的相同服务运行良好。
PS:我在 GitHub https://github.com/kubernetes/ingress-nginx/issues/5076中发现了一个类似的问题,但没有答案。
解决方案
我找到了适合我的两步解决方案:
- 应用端。Spring Boot 有一个在前端代理服务器后面运行的配置。我们需要将X-Forwarded- * 标头的处理设置为
FRAMEWORK
(默认为NONE
)。Location
Spring Boot 会根据 header 值自动更新header:
server.forward-headers-strategy=FRAMEWORK
- Nginx 方面。在我的 K8S 设置中,并未设置所有必需的 X-Forwarded- * 标头。在我的情况下
X-Forwarded-Prefix
没有配置。幸运的是,有一个 Nginx-Ingress 配置 - https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#x-forwarded-prefix-header:
ingress:
annotations:
nginx.ingress.kubernetes.io/x-forwarded-prefix: /api/test-tool
一切如何协同工作:
- 请求
/api/test-tool/hello
被代理到/hello
。Nginx 也设置了X-Forwarded-Prefix : /api/test-tool
- Spring Boot 应用程序使用标头处理请求
/name
并进行重定向Location
:Location : /oauth2/authorization/test-tool
- 由于我们设置了
X-Forwarded-Prefix
Spring Boot 的处理,因此将代理路径添加到Location
:Location : /api/test-tool/oauth2/authorization/test-tool
- 响应被代理回客户端的浏览器,我们实现了我们想要的,浏览器被重定向到正确的授权服务器。
推荐阅读
- c# - 在 C# 中找不到用于 Google API 身份验证的 toChannelCredentials()
- intellij-idea - 继续在插入符号热键下选择行
- c++ - 如果我不使用指针有什么区别?
- c# - Console 类方法的区别
- react-native - 如何修复 react-native-navigation 中的 redux 身份验证?
- javascript - 从 Google 电子表格中读取和写入日期
- continuous-integration - 如何在 30 天后删除 GitLab-CI 作业
- inno-setup - 如何在 Inno Setup 中使用 UTC
- ios - 使用 UICollectionViewController 重新排序的嵌套控制器
- swift - Firebase观察重复数据?