如何跨主机链接Docker服务?


115

Docker 允许来自多个容器的服务器通过链接和服务发现相互连接。但是,从我可以看到的服务发现是本地主机。我想实现一个使用托管在不同计算机上的其他服务的服务。

有多种方法可以解决Docker中的此问题,例如CoreOS的jumpers,本质上可代理另一台计算机的主机本地服务,以及用于管理Docker部署的大量github项目,这些项目似乎已尝试支持此用例。 。

考虑到发展的步伐,很难遵循当前的最佳实践。因此,我的问题本质上是:

  1. Docker之间跨主机链接的当前主要方法是(如果有)
  2. 是否有计划直接在Docker系统中支持此功能?

Answers:


58

更新资料

Docker最近宣布了一种名为Swarm的新工具,用于Docker编排。

Swarm允许您“加入”多个docker守护程序:首先创建一个swarm,在一台机器上启动swarm管理器,并让docker daemon使用swarm的标识符“加入”该swarm管理器。泊坞窗客户端连接到群管理器,就像它是常规泊坞窗服务器一样。

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

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

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

在测试中,我觉得Swarm尚不能很好地处理固定位置的卷(或者至少链接它们的过程不是很直观),因此要牢记这一点。

Swarm现在处于测试阶段。


直到最近,“ 大使模式”还是唯一的Docker本地方法,用于远程主机服务发现。该模式仍然可以使用,并且不需要普通Docker的任何魔术,因为该模式由一个或多个充当代理的其他容器组成。

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

  • 在两台主机上连接Docker网络桥时,存在轻量级和各种解决方案,但通常存在一些警告
  • 基于DNS的发现,例如使用Skydock和SkyDNS
  • Docker管理工具,例如Shipyard和Docker Orchestration工具。有关更多列表,请参见此问题:如何在生产中扩展Docker容器

2
因此,基本上仍然没有办法将不涉及大使模式的容器跨主机链接或绕过docker直接与lxc对话?
user3012759 2014年

@ user3012759大使模式是唯一建立的本机方式,但是Swarm(在alpha中)是通过替换Docker调度程序而工作的另一种本机方式。回复晚了非常抱歉。
lyschoening 2014年

SkyDock 尚不支持(迄今:03/2015)多主机支持Registrator(可以与SkyDNS一起使用的简单项目)可以,但是配置更加手动(服务必须将端口映射到主机端口)。
turtlemonvh

6
我对群集的粗略调查表明,它专注于群集管理,而不是主机间连接。这个缺点显然是由码头工人自己的演示说明youtube.com/watch?v=M4PFY6RZQHQ&t=3m37s
布鲁诺Bronosky

1
@lyschoening Docker宣布了本机多主机网络,您可能想更新答案
Thomasleveil 2015年

15

更新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,请参见此处的演示

更新

使用相同的方法,openvswitch主机在docker中进行通信有一个不错的主旨

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

还有一个转播


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

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

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

因此,您可以安全地使用解决方案,并等到Docker实现后,再以一种更简单的方式来实现。


2
最近,libswarm中没有太多活动。我想知道码头工人团队是否朝着另一个方向发展?
拉曼2014年

12

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

这里有趣的是

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

这会导致有趣的情况,例如

  • 在WAN上创建虚拟网络,没有Docker容器会知道或关心它们位于哪个实际网络中
  • 将您的容器移动到其他物理Docker主机,Weave将相应地检测对等端

例如,有一个示例指南,说明如何在笔记本电脑和一些云(EC2)主机上跨每个主机创建两个命令的多节点Cassandra群集。我使用AWS CloudFormation启动了CoreOS集群,在/ home / core中的每一个上都编织了编织,再加上我的笔记本电脑无聊的Docker VM,并在不到一个小时的时间内建立了集群。我的笔记本电脑装有防火墙,但Weave似乎还可以,它只是连接到其EC2对等设备。


据我了解,编织是一种容器内部工作以实现服务连接的网络覆盖,而swarm是一种群集技术,可扩展docker CLI进行基础架构编排。红外连接需要在集群外部(例如使用常规交换机)完成,而服务编排需要在编织外部(例如使用Mesos / Kubernetes)进行。这与您对它如何工作的想法相符吗?
亨里克

这是我的看法:docker compose与容器链接和编排有关,docker swarm与在许多docker主机上运行docker有关,socketplane(现在由docker拥有)和weave都是覆盖网络。套接字平面基于openvswitch,它通常用于VM中的覆盖(例如,openstack);另一方面,编织仅适用于docker。在所有这些中,Mesos / Kubernetes / Lattice替代了docker swarm,其用户体验和可伸缩性级别与docker CLI有所不同。
斯图尔特·查尔顿2015年

7

更新资料

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


使用Docker 1.9版本,您将建立多主机网络。它们还提供了一个示例脚本,可轻松配置工作集群。

您将需要一个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

文档中提供了更多详细信息。


6

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


1
确实,这是一个非常好的解决方案。我也遇到过它。我担心的是,该文章仅在昨天发布,并且需要Docker补丁。(鉴于它是最近发布的,我会稍等一下,看看他们是否将该补丁合并到了Docker中)。
lyschoening 2014年

Docker处于早期开发阶段,可能并非所有需求都还很明确,而且定义的需求并未全部实现。因此打补丁是必要的。
paweloque 2014年

2
这是无答案的。复制链接文章中的答案。那就是SO标准。
布鲁诺·布罗诺斯基

6

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

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

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


您将如何进行服务检测?假设我在一台计算机上有Redis,另一台计算机上有客户端应用程序,那么客户端应用程序将如何获得Redis服务的IP?
lyschoening 2014年

您将以相同的方式在单个主机上进行操作:为自己提供新启动的服务的IP /端口,或者使用键/值存储(例如etcd)或使用服务可以查询的DNS。我喜欢使用DNS,因为许多现有服务都可以使用它而无需进行修改。
2014年

1

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

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


1

似乎docker swarm 1.14可让您执行以下操作:

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

  • 将服务分配给机器使用 --constraint 'node.hostname == <host>'

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.