• 1
  • 2
  • 3
  • 4
  • 5
阿里云应用开发 首 页  »  帮助中心  »  云服务器  »  阿里云应用开发
替代Docker Compose实现容器双向联通的三种解决方法
发布日期:2016-7-8 17:7:9

  Docker是目前最热门的技术平台之一,他在产生后很短的时间内就获得了社会的广泛关注。简单的说,他使得开发者和系统管理员能用一种简易的方法去部署分布式应用。Docker的生态系统十分庞大,有很多的工具协同工作,如最常用的工具之一:Docker Compose。他使你可在单个文件中定义并运行多容器应用,然后通过一个命令执行。

  

  一个 docker-compose.yml 文件看起来是这样的:

  

  links 选项使容器能在一个运行中创建的内部网络中通讯,且在运行终止后销毁。在上面的例子中,当这个应用启动的时候,将在 web 容器中的 /etc/hosts 文件中建立一个别名为“redis”的入口,这使web容器能接通 redis 容器的服务。

  问题

  到目前为止,这个工具使你能通过一个命令运行多容器服务应用。但若你的容器间有复杂的连通,这就有可能会导致问题甚至应用无法运行。这里复杂的意思是多于一个的容器通过links选项共用另一个容器的服务。举例来说,在上面的应用中,web容器想使用 redis 容器中的服务,若在 redis 容器中添加“links:-web”且通过 docker-compose 来运行他,你会看到如下信息:

  

  事实上,这是 Docker 的一个历史问题,Docker 的网络系统曾有一些问题,而这正是一个典型体现。社区建议使用 ambassador pattern 作为解决这个问题的方法,但此解决方法增加了你应用的开销,毕竟这只是一个变通方法,不是一个 docker 化的解决方式。由于我在自己的应用开发中面临这个问题,因此我寻找了一些基于 Docker 平台和 Docker 工具的方法,下面是我尝试成功的三种解决方法。

  解决方案1:使用外部 DNS 容器

  一个经典的解决方法(我觉得是临时方法)是在你的 docker-compose.yml 文件中添加一个额外的容器。添加如下的容器到你的文件中。

  dnsdock:

  image: tonistiigi/dnsdock

  volumes:

  - /var/run/docker.sock:/run/docker.sock

  ports:

  - 172.17.42.1:53:53/udp

  并且,在每个容器中你需要做如下的操作:

  告诉容器 DNS 服务在什么位置:

  dns: 172.17.42.1

  命名每个容器使其对于服务发现可见

  environment:

  - DNSDOCK_NAME=web

  - DNSDOCK_IMAGE=web

  使用环境变量来完成这个命名。对 redis 容器做同样的操作(不管你的其他容器是什么)。

  现在容器在..docker下相互可见。这就是 redis 容器和 web 容器中的服务在 web.docker 下通信的方法。

  解决方案2:使用新的 Docker 网络接口

  Docker 在DockerCon 2015上宣布了很多新的特性和工具,其中一个进步就是新的网络系统。新的网络类型使我能够采用一个简单的方法来实现一个有复杂通讯的多容器应用。

  使用下面的方法使在同一个私有网络中的两个容器相互可见。

  创建一个网络

  docker network create mynetwork

  通过列举所有的网络,确保这个网络成功创建。

  docker network ls

  把容器连接到你的网络上

  打开一个终端,执行以下命令来运行一个容器:

  docker run -it --publish-service web.mynetwork web

  打开另一个终端并且运行另一个容器:

  docker run -it --publish-service redis.mynetwork redis

  容器相互可见

  现在,你可从第一个终端 ping redis.mynetwork 并且收到回复。同样,从第二个终端,你可以 ping web.mynetwork 并收到回复。这是发布在.下的服务。通过这种方法,你无需将自己的应用与 Docker Compose 链接,你只需要创建一个网络并且在这个网络上发布服务。换句话说,我们将 docker-compose.yml 的连接替换为一个网络。虽然这个功能还在试验中(在本文写作时),但是我认为这种灵活的方式就是运行多容器应用的未来,所以建议你遵循 Docker 发展的方向。

  解决方案3:在多主机网络中使用 Docker Swarm 和 Compose

  在多主机网络中使用 Swarm 和 Compose 也是一个实验性的功能。这个解决方案比前一个需要做更多的工作,但若你有很多容器需连接并且你打算让他们运行在集群中,这是最好的解决方法。关于解决的详细流程,请参照 GitHub 里的原始功能介绍。首先,在多主机网络中安装 Swarm,然后你可在去掉 links 选项后立即运行一个组合应用。为何?因为从这个使用 Swarm 集群的多主机网络上启动的每一个容器都默认使用“overlay:multihost”网络,这意味着他们可通过容器名相互访问。

  因为这是实验性功能,所以请在 GitHub 给作者反馈。