【问题标题】:How to link Docker services across hosts?如何跨主机链接 Docker 服务?
【发布时间】:2014-02-12 13:05:45
【问题描述】:

码头工人allows servers from multiple containers to connect to each other via links and service discovery。但是,据我所知,此服务发现是主机本地的。我想实现一个使用不同机器上托管的其他服务的服务。

在 Docker 中有几种解决这个问题的方法,例如CoreOS's jumpers,本质上代理到另一台机器的主机本地服务,以及一大堆似乎试图管理 Docker 部署的 github 项目支持这个用例。

考虑到发展速度,很难遵循当前的最佳做法。因此,我的问题本质上是:

  1. 目前在 Docker 中跨主机链接的主要方法是什么(如果有),以及
  2. 是否有计划直接在 Docker 系统中支持此功能?

【问题讨论】:

    标签: docker


    【解决方案1】:

    更新

    Docker 最近 announced 有一个名为 Swarm 的新工具,用于 Docker 编排。

    Swarm 允许您“加入”多个 docker 守护进程:您首先创建一个 swarm,在一台机器上启动一个 swarm 管理器,然后让 docker 守护程序使用 swarm 的标识符“加入”该 swarm 管理器。 docker 客户端连接到 swarm 管理器,就好像它是一个普通的 docker 服务器一样。

    当一个容器以 Swarm 启动时,它会自动分配给一个满足任何已定义约束的空闲节点。以下示例摘自博文:

    $ docker run -d -P -e constraint:storage=ssd mysql
    

    支持的约束之一是"node",它允许您将容器固定到特定的主机名。 swarm 还解析节点之间的链接。

    在我的测试中,我得到的印象是 Swarm 还不能很好地处理固定位置的卷(或者至少链接它们的过程不是很直观),所以这是要记住的事情。

    Swarm 现在处于测试阶段。


    直到最近,Ambassador Pattern 还是唯一的 Docker 原生方法来发现远程主机服务。这种模式仍然可以使用,并且除了普通的 Docker 之外不需要任何魔法,因为该模式由一个或多个充当代理的附加容器组成。

    此外,还有一些第三方扩展可以使 Docker 具备集群功能。第三方解决方案包括:

    • 在两台主机上连接 Docker 网桥,存在轻量级和各种解决方案,但通常有一些注意事项
    • 基于 DNS 的发现,例如skydock 和 SkyDNS
    • Shipyard等Docker管理工具,以及Docker编排工具。有关详细列表,请参阅此问题:How to scale Docker containers in production

    【讨论】:

    • 那么基本上还是没有办法链接容器跨主机不涉及大使模式或者绕过docker直接和lxc对话?
    • @user3012759 大使模式是唯一已建立的原生方式,但 Swarm(在 alpha 中)是另一种通过替换 Docker 调度程序来工作的原生方式。抱歉回复晚了。
    • SkyDock does not (yet: 03/2015) include multi-host supportRegistrator(一个可以使用 SkyDNS 的简单项目)可以,但配置更加手动(服务必须将端口映射到主机端口)。
    • 我对 swarm 的粗略调查表明它专注于集群管理而不是主机间连接。这个缺点在 Docker 自己的 demo youtube.com/watch?v=M4PFY6RZQHQ&t=3m37s 中明确说明
    • @lyschoening Docker 宣布 native multi host networking 你可能想更新你的答案
    【解决方案2】:

    更新 3

    Libswarm 已重命名为 swarm,现在是一个单独的应用程序。

    这里是作为起点的 github 页面演示:

    # create a cluster
    $ swarm create
    6856663cdefdec325839a4b7e1de38e8
    
    # on each of your nodes, start the swarm agent
    #  <node_ip> doesn't have to be public (eg. 192.168.0.X),
    #  as long as the other nodes can reach it, it is fine.
    $ swarm join --token=6856663cdefdec325839a4b7e1de38e8 --addr=<node_ip:2375>
    
    # start the manager on any machine or your laptop
    $ swarm manage --token=6856663cdefdec325839a4b7e1de38e8 --addr=<swarm_ip:swarm_port>
    
    # use the regular docker cli
    $ docker -H <swarm_ip:swarm_port> info
    $ docker -H <swarm_ip:swarm_port> run ... 
    $ docker -H <swarm_ip:swarm_port> ps 
    $ docker -H <swarm_ip:swarm_port> logs ...
    ...
    
    # list nodes in your cluster
    $ swarm list --token=6856663cdefdec325839a4b7e1de38e8
    http://<node_ip:2375>
    

    更新 2

    现在官方的做法是使用libswarm看demohere

    更新

    有一个nice gist 用于在 docker 中使用相同的方法进行 openvswitch 主机通信。

    为了实现服务发现,有一种基于 DNS 的有趣方法,称为 skydock

    还有一个screencast


    这也是一篇不错的文章,使用了相同的拼图,但还在顶部添加了 vlan:

    http://fbevmware.blogspot.it/2013/12/coupling-docker-and-open-vswitch.html

    修补与解决方案的稳健性无关。 Docker 实际上只是 Linux Containers 上的一种 DSL,这些文章中的两种解决方案都只是绕过了一些 Docker 自动设置,直接回退到 Linux Containers。

    因此,您可以安全地使用这些解决方案,并等待 Docker 实施后能够以更简单的方式实现它。

    【讨论】:

    • 最近在 libswarm 中没有太多活动。不知道 docker 团队是不是在往另一个方向发展?
    【解决方案3】:

    Weave 是一种新的 Docker 虚拟网络技术,它充当 TCP/UDP 上的虚拟以太网交换机 - 您只需要一个在您的主机上运行 Weave 的 Docker 容器。

    这里有趣的是

    • 在虚拟网络中使用静态 IP/主机名代替链接
    • 主机不需要完全连接,根据可用的对等方形成网格,数据包将被多跳路由到它们需要去的地方

    这会导致一些有趣的场景,例如

    • 在 WAN 上创建一个虚拟网络,任何 Docker 容器都不知道或关心它们所在的实际网络
    • 将您的容器移动到不同的物理 docker 主机,Weave 将相应地检测对等方

    例如,有一个example guide 介绍了如何在您的笔记本电脑和一些云 (EC2) 主机上创建一个多节点 Cassandra 集群,每个主机有两个命令。我使用 AWS CloudFormation 启动了一个 CoreOS 集群,在 /home/core 中的每个集群上安装了 weave,以及我的笔记本电脑 vagrant docker VM,并在不到一个小时的时间内建立了一个集群。我的笔记本电脑有防火墙,但 Weave 似乎没问题,它只是连接到它的 EC2 对等体。

    【讨论】:

    • 据我了解,weave 是一种网络覆盖,它在内部容器中工作以实现服务连接,而 swarm 是一种集群技术,可扩展 docker CLI 以进行基础架构编排。基础设施连接需要在 swarm 之外完成(例如使用常规交换机)和在 weave 之外进行服务编排(例如使用 Mesos/Kubernetes)。这是否符合您对其工作原理的想法?
    • 我是这样看的:docker compose 是关于容器链接和编排的,docker swarm 是关于在许多 docker 主机上运行 docker,socketplane(现在由 docker 拥有)和 weave 都是覆盖网络。 Socketplane 基于 openvswitch,通常用于 VM 中的覆盖(例如 openstack);另一方面,Weave 是 docker-only。在所有这些中,Mesos/Kubernetes/Lattice 是 docker swarm 的替代品,其用户体验和可扩展性水平与 docker CLI 有所不同。
    【解决方案4】:

    更新

    Docker 1.12 包含所谓的 swarm 模式,还添加了 service 抽象。对于每个用例,它们可能还不够成熟,但我建议您对它们进行观察。 swarm 模式至少有助于多主机设置,但这并不一定会使链接更容易。 Docker 内部的 DNS 服务器(从 1.11 开始)应该可以帮助您访问容器名称,如果它们是众所周知的 - 这意味着在 Swarm 上下文中生成的名称不会那么容易解决。


    使用 Docker 1.9 版本,您将在 multi host networking 中构建。他们还提供了一个example script 来轻松配置工作集群。

    您需要一个 K/V 存储(例如 Consul),它允许在每个主机上的不同 Docker 引擎之间共享状态。每个 Docker 引擎都需要配置该 K/V 存储,然后您可以使用 Swarm 连接您的主机。

    然后你像这样创建一个新的覆盖网络:

    $ docker network create --driver overlay my-network
    

    现在可以使用网络名称作为运行参数来运行容器:

    $ docker run -itd --net=my-network busybox
    

    它们也可以在已经运行时连接到网络:

    $ docker network connect my-network my-container
    

    更多详情请见documentation

    【讨论】:

      【解决方案5】:

      以下文章很好地描述了如何在多个主机上连接 docker 容器:http://goldmann.pl/blog/2014/01/21/connecting-docker-containers-on-multiple-hosts/

      【讨论】:

      • 这确实是一个非常好的解决方案;我也遇到过。我担心的是这篇文章是昨天才发布的,它需要一个 Docker 补丁。 (考虑到它最近发布的时间,我会稍等片刻,看看他们是否将该补丁合并到 Docker 中)。
      • Docker 处于早期开发阶段,可能还不是所有需求都清楚,定义的需求也没有全部实现。因此需要修补。
      • 这是一个非答案。复制链接文章中的答案。这就是 SO 标准。
      【解决方案6】:

      可以使用 Open vSwitch 或 Tinc 将多个 Docker 子网桥接在一起。我准备了 Gists 来展示如何做到这一点:

      我看到使用此解决方案而不是 --link 选项和大使模式的优势是我发现它更加透明:不需要额外的容器,更重要的是,不需要在主机上公开端口。实际上,我认为--link 选项是在 Docker 获得有关多主机(或多守护程序)设置的更好故事之前的临时破解。

      注意:我知道还有另一个答案指向我的第一个 Gist,但我没有足够的业力来编辑或评论该答案。

      【讨论】:

      • 如何进行服务检测?假设我一台机器上有Redis,另一台机器有客户端应用,客户端应用如何获取Redis服务的IP?
      • 与在单个主机上执行此操作的方式相同:为自己提供新启动的服务的 IP/端口,或使用键/值存储(例如 etcd)或使用服务可以的 DNS询问。我喜欢使用 DNS,因为许多现有服务无需修改即可使用它。
      【解决方案7】:

      如上所述,Weave 绝对是跨主机链接 Docker 容器的可行解决方案。根据我自己的经验,设置它相当简单。它现在还有DNS service,您可以通过其 DNS 名称来寻址容器。

      另一方面,CoreOS 的 Flannel 和 Juniper 的 Opencontrail 用于跨主机连接容器。

      【讨论】:

        【解决方案8】:

        似乎 docker swarm 1.14 允许您:

        • 使用--hostname标签将主机名分配给容器,但我无法使其工作,容器无法通过分配的主机名相互ping通。

        • 使用--constraint 'node.hostname == &lt;host&gt;'将服务分配给机器

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-03-06
          • 1970-01-01
          • 2015-01-07
          • 2021-08-06
          • 1970-01-01
          • 2010-09-27
          • 2016-03-13
          相关资源
          最近更新 更多