从集群内部调用外部 API

时间:2021-04-07 17:12:36

标签: kubernetes kubernetes-ingress kong

我想从集群内部调用外部 api,所以我遵循了 Kubernetes 文档

如下:

apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: prod
spec:
  type: ExternalName
  externalName: https://api.github.com/

并且我能够得到带有 externalName 的响应:

externalName: httpbin.org

但是当我使用 http 或 https 端点时它会失败。

我知道文档说明了以下内容

Warning:

You may have trouble using ExternalName for some common protocols, including HTTP and HTTPS. If you use ExternalName then the hostname used by clients inside your cluster is different from the name that the ExternalName references.

For protocols that use hostnames this difference may lead to errors or unexpected responses. HTTP requests will have a Host: header that the origin server does not recognize; TLS servers will not be able to provide a certificate matching the hostname that the client connected to.

但我想知道如何从集群内部向外部 API 进行 http/https 调用?

1 个答案:

答案 0 :(得分:0)

但我想知道如何从集群内部向外部 API 进行 http/https 调用?

我看不出有什么理由不使用 ExternalName 从集群调用外部 API。你实际上并不需要那种类型的服务来做到这一点。除非您没有在这里告诉我们某些事情。

现在继续讨论您遇到错误的原因。对于 ExternalName 类型的服务,请求通过 Host: my-service 到达您的目的地,api.github.com 是他从您创建的服务中继承的。如果我们以您提到的 http 为例,一旦尝试访问它,它就会收到带有标头 Host: my-serviceapi.github.com 请求,而他不知道如何处理它,也不会将它路由到哪里。因此,如果您事先想使用 header,为什么不直接使用它?

在这里查看我为展示 ExternalName 注入的 my-service-test 所做的示例(我将服务命名为 [root@cent /]# curl my-service-test -v * About to connect() to my-service-test port 80 (#0) * Trying 183.36.108.201... * Connected to my-service-test (183.36.108.201) port 80 (#0) > GET / HTTP/1.1 > User-Agent: curl/7.29.0 > Host: my-service-test > Accept: */* > < HTTP/1.1 400 Bad Request < Server: nginx < Date: Thu, 08 Apr 2021 07:44:38 GMT < Content-Type: text/html < Content-Length: 166 < Connection: close < X-Proxy-Server: Sparta < <html> <head><title>400 Bad Request</title></head> <body bgcolor="white"> <center><h1>400 Bad Request</h1></center> <hr><center>nginx</center> </body> </html> * Closing connection 0 ):

host

Nginx 收到请求,但 api_gateway.add_usage_plan( id="UsagePlan", name="poc-voice-qa-usage-plan", description="poc usage plan", api_stages=[apigw.UsagePlanPerApiStage(stage=api_gateway.deployment_stage)] ) 标头是否与他期望的不匹配,因此他不怎么处理它。

解决这个问题的方法可能是使用 nginx pod 作为代理,或者使用 Ingress 来尝试在到达所需目标之前重写标头。