首页 > 解决方案 > 如果服务使用新的相对 url `Location` 标头响应,Kubernetes Ingress Nginx 控制器不会保留`path`

问题描述

pathTL;如果底层服务重定向到相对 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中发现了一个类似的问题,但没有答案。

标签: nginxkubernetesspring-security-oauth2nginx-ingress

解决方案


我找到了适合我的两步解决方案:

  • 应用端。Spring Boot 有一个在前端代理服务器后面运行的配置。我们需要将X-Forwarded- * 标头的处理设置为FRAMEWORK(默认为NONE)。LocationSpring Boot 会根据 header 值自动更新header:
server.forward-headers-strategy=FRAMEWORK
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并进行重定向LocationLocation : /oauth2/authorization/test-tool
  • 由于我们设置了X-Forwarded-PrefixSpring Boot 的处理,因此将代理路径添加到LocationLocation : /api/test-tool/oauth2/authorization/test-tool
  • 响应被代理回客户端的浏览器,我们实现了我们想要的,浏览器被重定向到正确的授权服务器。

推荐阅读