替代Docker Compose实现容器双向联通的三种方法

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 本文讲的是替代Docker Compose实现容器双向联通的三种方法,【编者的话】目前容器的双联是一个难点,必须手动配置。这篇文章介绍了实现双联的三种方法,对想玩容器的开发者来说有一定的帮助作用。
本文讲的是替代Docker Compose实现容器双向联通的三种方法 【编者的话】目前容器的双联是一个难点,必须手动配置。这篇文章介绍了实现双联的三种方法,对想玩容器的开发者来说有一定的帮助作用。

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

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

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

问题

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

事实上,这是 Docker 的一个历史问题,Docker 的网络系统曾有一些问题,而这正是一个典型体现。社区建议使用  ambassador pattern  作为解决这个问题的方法,但是这个解决方法增加了你应用的开销,毕竟这只是一个变通方法,不是一个 docker 化的解决方式。

因为我在自己的应用开发中面临这个问题,所以我寻找了一些基于 Docker 平台和 Docker 工具的方法,下面是我尝试成功的三种解决方法。

解决方案1:使用新的 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 并收到回复。这是发布在<service_name>.<network_name>下的服务。
通过这种方法,你无需将自己的应用与 Docker Compose 链接,你只需创建一个网络并且在这个网络上发布服务。换句话说,我们将 docker-compose.yml 的连接替换为一个网络。
虽然这个功能还在试验中(在本文写作时),但我认为这种灵活的方式就是运行多容器应用的未来,所以,建议你遵循 Docker 发展的方向。

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

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

解决方案3:使用外部 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 容器做同样的操作(不管你的其他容器是什么)。
现在容器在<container_name>.<container_name>.docker下相互可见。这就是 redis 容器和 web 容器中的服务在 web.docker 下通信的方法。

总结:

Docker 技术发展迅速,已经得到了社区的大量支持,并且还在持续扩大中。当解决你面对的问题时,首先调查一下 Docker 领域的新工具,确保跟随主流研发方向。在这篇文章中,我发布了3种可行的解决方法来解决 Docker Compose 的双向链接问题,其中的两个依赖于不久就会应用的新的网络系统。如果你的应用不那么复杂,你可以试试 DNS 容器的解决方案。

你还有其他的解决方案?希望你能传到这里来。

原文链接:Three Solutions to Bi-directional Linking Problem in Docker Compose(翻译:邵长钰)

原文发布时间为: 2015-12-29 
本文作者:chyshao
本文来自云栖社区合作伙伴DockerOne,了解相关信息可以关注DockerOne。
原文标题:替代Docker Compose实现容器双向联通的三种方法
目录
相关文章
|
20天前
|
Docker 容器
进入Docker容器中
进入Docker容器中
33 2
|
24天前
|
存储 机器学习/深度学习 中间件
快速上手 Elasticsearch:Docker Compose 部署详解
本文介绍了如何使用Docker Compose快速搭建Elasticsearch学习环境。Elasticsearch是一款用于实时搜索和分析的分布式中间件,适用于多种场景,如搜索、日志分析、机器学习等。首先,创建docker网络,拉取最新版8.12.2镜像。接着,编写docker-compose.yml文件,配置单节点集群,设置端口映射、内存限制及数据卷挂载。然后,创建并配置数据卷目录,允许远程访问和跨域。最后,启动服务并验证,通过浏览器访问确认服务运行正常。本文为初学者提供了一个简便的Elasticsearch部署方法。
140 4
快速上手 Elasticsearch:Docker Compose 部署详解
|
29天前
|
关系型数据库 MySQL Java
Docker Compose详细教程(从入门到放弃)
Docker Compose详细教程(从入门到放弃)
124 0
|
9天前
|
Linux Docker 容器
docker 容器常用命令
docker 容器常用命令
11 0
|
17天前
|
Kubernetes 网络协议 Docker
Docker 容器的DNS
Docker 容器的DNS
23 1
|
20天前
|
关系型数据库 MySQL Nacos
【深入浅出Nacos原理及调优】「实战开发专题」采用Docker容器进行部署和搭建Nacos服务以及“坑点”
【深入浅出Nacos原理及调优】「实战开发专题」采用Docker容器进行部署和搭建Nacos服务以及“坑点”
45 1
|
24天前
|
监控 数据可视化 虚拟化
Docker容器常用命令笔记分享
Docker容器常用命令笔记分享
50 2
|
1月前
|
消息中间件 Linux 开发工具
rabbitmq使用docker容器挂载宿主机配置文件时无法访问控制台
rabbitmq使用docker容器挂载宿主机配置文件时无法访问控制台
|
1月前
|
JavaScript Shell Docker
|
1月前
|
Java Go 开发者
Docker容器技术简介及其与Go语言的结合点
【2月更文挑战第23天】本文首先概述了Docker容器技术的核心概念和优势,接着探讨了Go语言与Docker容器技术的结合点。通过阐述Docker的轻量级、可移植性和版本控制等特性,以及Go语言在容器化应用中的优势,本文旨在说明两者结合能够实现更高效、灵活的应用开发和部署。