【问题标题】:Calling external API from inside a cluster从集群内部调用外部 API
【发布时间】:2021-04-07 17:12:36
【问题描述】:

我想从集群内部调用一个外部 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 调用?

【问题讨论】:

    标签: kubernetes kubernetes-ingress kong


    【解决方案1】:

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

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

    现在继续讨论您遇到错误的原因。使用ExternalName 类型的服务,请求与Host: my-service 一起到达您的目的地,他继承自您创建的服务。如果我们以api.github.com 为例,正如您曾经提到的那样,尝试到达它会收到带有标头Host: my-servicehttp 请求,但他不使用它做什么,也不会将它路由到哪里。所以,如果您预先想使用api.github.com,为什么不直接联系它呢?

    在这里查看我制作的示例,以显示ExternalName 注入的header(我将服务命名为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 
    

    Nginx 收到了请求,但 host 标头与他的预期不匹配,因此他没有处理它。

    解决方法可能是使用 nginx pod 作为代理,或者使用 ingress 尝试在头部到达所需目标之前重写头部。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-24
      • 1970-01-01
      • 1970-01-01
      • 2019-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-30
      相关资源
      最近更新 更多