如何跨主机链接Docker服务?

时间:2014-01-22 12:53:23

标签: docker

Docker 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系统中支持这一功能?

8 个答案:

答案 0 :(得分:58)

<强>更新

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 目前处于测试阶段。


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

此外,还有一些第三方扩展可以支持Docker群集。第三方解决方案包括:

  • 在两台主机上连接Docker网桥,存在轻量级和各种解决方案,但通常会有一些警告
  • 基于DNS的发现,例如使用skydock和SkyDNS
  • Docker管理工具,例如Shipyard和Docker业务流程工具。有关详尽列表,请参阅此问题:How to scale Docker containers in production

答案 1 :(得分: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查看演示here

<强>更新

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

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

还有screencast


这也是一篇很好的文章,使用相同的拼图,但在顶部添加了vlans:

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

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

所以你可以安全地使用这些解决方案,等待Docker实现它后能够以更简单的方式完成它。

答案 2 :(得分:11)

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

这里有趣的是

  • 而不是链接,在虚拟网络中使用静态IP /主机名
  • 主机不需要完全连接,根据可用的对等体形成网状网,数据包将以多跳方式路由到需要的位置

这导致了像

这样的有趣场景
  • 在WAN上创建虚拟网络,没有任何Docker容器会知道或关心他们所处的实际网络
  • 将容器移动到不同的物理docker主机,Weave会相应地检测到对等

例如,关于如何在笔记本电脑和一些云(EC2)主机上创建多节点Cassandra集群(每个主机有两个命令),有一个example guide。我推出了一个带有AWS CloudFormation的CoreOS集群,在每个/ home / core中安装了weave,再加上我的笔记本电脑流浪汉docker VM,并在一小时内完成了一个集群。我的笔记本电脑是防火墙,但Weave似乎没关系,它只是连接到它的EC2同行。

答案 3 :(得分:7)

<强>更新

Docker 1.12包含所谓的swarm模式,并且还添加了service抽象。对于每个用例,它们可能还不够成熟,但我建议你对它们进行观察。群集模式至少有助于多主机设置,这不一定使链接更容易。 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中提供了更多详细信息。

答案 4 :(得分:6)

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

答案 5 :(得分:6)

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

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

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

答案 6 :(得分:1)

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

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

答案 7 :(得分:1)

似乎像docker swarm 1.14允许你:

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

  • 使用--constraint 'node.hostname == <host>'

  • 将服务分配给计算机