Kubernates-HTTPS 重定向后,ExternalName Service 将方法从 POST 重写为 GET

Kubernates-HTTPS 重定向后,ExternalName Service 将方法从 POST 重写为 GET

想象一下这样的场景:

  • API 网关
  • 后端服务

部署在 Kuberantes 集群上。此外,我们还有:

  • 外部经过验证的服务(想象一下来自我们基础设施的外部 Web 应用程序)。

后端需要访问外部服务,但首先需要通过登录端点获取身份验证令牌。

问题 1:此端点返回如下内容:

"eyJhbGciOiJS..." 

基本上就是一个字符串。不幸的是,后端服务需要这样的结构:

{
  "token": "eyJhbGciOiJS..."
}

现在,为了实现这一点,我想调用我的 API 网关并尝试重写响应。为此,我首先在集群上创建一个 ExternalName Service:

apiVersion: v1
kind: Service
metadata:
  name: <service-name>
  namespace: <namespace>
spec:
  type: ExternalName
  externalName: <external-service-host>

还有一个指向 API 网关的入口,它将重定向到 ExternalName 服务:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: <ingress-name>
  namespace: <namespace>
  annotations:
    kubernetes.io/tls-acme: 'true'
    cert-manager.io/cluster-issuer: letsencrypt-production
spec:
  ingressClassName: nginx
  tls:
    - secretName: <tls-secret-name>
      hosts:
        - <host>
  rules:
    - host: <host>
      http:
        paths:
          - path: /
            pathType: ImplementationSpecific
            backend:
              service:
                name: <api-gateway-service-name>
                port:
                  number: <api-gateway-service-port>

到目前为止一切正常。错误发生在最后一步,即当 ExternalService 发送实际请求时。我尝试通过 Insomnia 登录,结果弹出以下内容:

{
    "message": "The method is not allowed for the requested URL."
}

以下是时间线:

[...]
> POST /auth/login HTTP/2
> Host: <host>/auth/login
> content-type: application/json
> user-agent: insomnia/2023.5.8
> accept: */*
> content-length: 66
[...]
< HTTP/2 301 
< date: Fri, 27 Oct 2023 15:45:58 GMT
< content-type: text/html
< location: <external-service>/auth/login
< vary: Origin
< access-control-allow-origin: *
< access-control-allow-methods: GET,POST,PUT,DELETE,PATCH,HEAD,OPTIONS,CONNECT,TRACE
< access-control-max-age: 5
< access-control-expose-headers: **
< access-control-allow-credentials: true
< strict-transport-security: max-age=15724800; includeSubDomains
[...]
* Connection #105 to host <host> left intact
* Issue another request to this URL: '<external-service>/auth/login'
* Switch from POST to GET <------ NOT GOOD
[...]
> GET /auth/login HTTP/2
> Host: <external-service>
> content-type: application/json
> user-agent: insomnia/2023.5.8
> accept: */*
[...]

如你所见,当它尝试从 HTTP 重定向到 HTTPS 协议时,它突然决定从 POST 请求切换到 GET 请求。当然,它会导致 405(方法不允许),这使其变得毫无用处。

所以,我在这里想知道是否有任何方法可以使用 ExternalName Service,而无需首先尝试使用 HTTP 连接,但使用 HTTPS 以跳过方法重写。

PS 我还尝试将后端服务与 API 网关连接起来,以确保 Insomnia 和软件本身都会出现同样的问题。正如您所想象的,这种情况确实发生了。

相关内容