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系统中支持这一功能?
答案 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群集。第三方解决方案包括:
答案 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
<强>更新强>
使用相同的方法,在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容器。
这里有趣的是
这导致了像
这样的有趣场景例如,关于如何在笔记本电脑和一些云(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>'