【问题标题】:Connect to host A from docker running on host B从主机 B 上运行的 docker 连接到主机 A
【发布时间】:2018-11-04 19:38:44
【问题描述】:

我开发分布式系统并考虑以下情况: 我的应用程序在主机 A 上运行的 docker 中工作,我想从物理主机 B 上运行的其他服务调用 api(没有 docker)。我可以调用 IP 或 DNS 地址吗?

与上述问题有关的其他情况: 我使用 docker-compose 在本地开发分布式系统,并在那里定义服务:ServiceA、ServiceB 等。如果 ServiceA 必须在端口 8080 上调用 ServiceB,我调用 http://ServiceB:8080/ 并且它工作正常。在生产中,每个服务都应该在具有不同 IP 的不同主机上工作。那么我将在不同的主机上运行每个服务并通过http://<IP_of_ServiceB>:8080而不是使用服务名称从ServiceA调用ServiceB是一种好方法吗?

【问题讨论】:

    标签: docker docker-compose


    【解决方案1】:

    您可能会发现一个有用的基础架构是服务注册表,它知道哪些主机正在运行哪些服务。这些通常提供 DNS 服务,因此您可以通过其“主机名”引用服务并将其路由到运行该服务的实际主机(或主机)。这里的想法是您通过(可能是人为的)主机名来引用 Docker 和非 Docker 服务,并且基础设施层将其路由到正确的主机。除了 Kubernetes 选项,这些不需要特殊的网络设置,只需指向正确的 DNS 服务器。

    我之前用过的三个具体例子:

    • 在 AWS 上(如果您已经在使用/付费),您可以设置一个指向每个节点的 load balancer,并进行健康检查;如果一个节点恰好服务于(例如)端口 9123,那么负载均衡器的端口 80 将路由到那里。然后您可以设置一个指向负载均衡器的DNS name。对于每个服务,在您关心的任意数量的节点上的特定已知端口上启动它,并为每个服务创建一个负载均衡器和 DNS 名称。 (您还可以创建作为外部服务主机别名的 DNS CNAME 记录。)这恰好是 ECS 的标准设置,但与该服务无关;事实上,如果您可以提供自己的负载均衡器和名称服务器,那么您可以在任何地方使用这种方法。

    • Hashicorp 的Consul 旨在(除其他外)作为服务注册表。在我过去使用的模式中,您将在每个节点上安装一个 Consul 代理,并在每个节点上安装一组健康检查,以查找每个已知服务。将 Docker 容器配置为指向 Consul DNS 服务器。 servicename.service.consul 之类的主机名将解析为运行服务的主机的 IP 地址,然后您可以使用服务的端口引用http://servicename.service.consul:9123/ 之类的 URL。 (我相信您可以覆盖其definition 中的服务地址以将其指向外部服务器。)

    • Kubernetes 中,有一个标准的Service 对象提供负载平衡和DNS。您可以将服务配置为侦听某个端口并路由到某些 Pod 集上的某个其他端口(这些 Pod 又运行 Docker 容器)。您可以使用servicename.default.svc.cluster.local 之类的主机名,但其中大部分也会出现在您的默认DNS 搜索路径中,因此http://servicename/ 通常是一个不错的URL。 (您可以配置一个 ExternalName 服务,它只是一个指向集群外部的 DNS 记录。)

    【讨论】:

      【解决方案2】:

      第一个问题,是的,只要确保端口是公开的并且可以从其他主机访问。

      第二个问题,你仍然可以这样做(在一个环境中写下主机 B 的 ip 左右)。或者,您可能需要考虑使用 docker swarm 来部署您的生产堆栈。结合overlay网络,让你的2台主机像一个一样,你可以像http://ServiceB:3000/一样继续通话

      version: '3'
      services:
        serviceA:
          image: serviceA
          ports:
            - "8080:8080"
          networks: 
            - swarm-net
      
        serviceB:
          image: serviceB
          networks: 
            - swarm-net
          ports:
            - "3000:3000"
      
      networks:
        swarm-net:
          driver: overlay
      

      【讨论】:

      • 好的,但是我应该选择什么驱动程序来为其他主机公开我的应用程序(在 docker 中运行)?驱动主机是个好选择?
      • @user 驱动是什么意思?
      • 您在docker-compose.yml 文件中的network 部分中使用的驱动程序。
      • machine-ip:8080/machine-ip:3000 仍然可以访问您的应用程序,因为您已指定要映射到主机上的该端口的端口。这是用于容器与外部世界之间的连接。对于 swarm 内部的连接,overlay 网络允许你使用http://ServiceB:3000/
      猜你喜欢
      • 2016-02-21
      • 1970-01-01
      • 1970-01-01
      • 2021-09-24
      • 1970-01-01
      • 1970-01-01
      • 2019-04-26
      • 2020-04-24
      相关资源
      最近更新 更多