Docker容器互联方法--篇二

本文讲的是Docker容器互联方法--篇二,【编者的话】本文为Eddy Mavungu博士于DEIS官方博客中发布的系列文章的第二部分,Eddy博士在本篇系列文章中分享了Docker容器间互联的方法,并且做了演示。Eddy博士是DEIS公司的创始人,同时也是一位高级研究顾问。本文根据他于DEIS官方博客上发布的文章翻译而成。

这篇系列文章的第二部分会看一下如何连接Docker各容器。

我们在第一节谈及了Docker的bridge接口,它可以让我们连接所有在相同Docker宿主机上的容器。特别需要指出的是,我们看了三个基本并且比较早先的网络驱动技术:端口公开(port exposure),端口绑定(port binding)以及链接(linking)。

在本文,我们将来看这些更高级并且最新的基于bridge接口的使用案例。

同时,我们也会看看使用overlay技术来将不同宿主机上的Docker容器连接起来。

用户定义的网络(User-Defined Networks)

Docker公司在2015年11月初发布了Docker 1.9.0,随之而来整合了一些令人兴奋的关于网络方面的新内容。通过这些更新,如果我们现在为了让两个容器间可以相互通信,那么只需要将他们放在同一网络或者子网中。

让我们来证明一次。

首先,来看看我们准备了哪些:

$ sudo docker network ls
NETWORK ID          NAME                DRIVER
362c9d3713cc        bridge              bridge
fbd276b0df0a        singlehost          bridge
591d6ac8b537        none                null
ac7971601441        host                host

现在,让我们来创建网络:

$ sudo docker network create backend

如果起作用了,我们的网络列表上会显示刚才新建立的网络:

$ sudo docker network ls
NETWORK ID          NAME                DRIVER
362c9d3713cc        bridge              bridge
fbd276b0df0a        singlehost          bridge
591d6ac8b537        none                null
ac7971601441        host                host
d97889cef288        backend             bridge

我们可以看到在这里backend已经被bridge驱动创建出来了。这是一个桥接(bridge)网络,就像在前文的第一部分中提到的一样,它也同样适用于所有在该宿主机上的容器。

我们将会用到上一节中创建的client_img和server_img镜像。如果你还没有在你的主机上配置好他们,可以现在查阅第一节并且设置好,这并不会花费太长时间。

什么?你说你已经设置好了?太棒了。

让我们从server_img镜像中运行一个服务器容器并且通过--net选项把它放置于之前配置的backend网络中。

就像下面命令一样:

$ sudo docker run -itd --net=backend --name=server server_img /bin/bash

像之前一样,登录到该容器:

$ sudo docker attach server

如果你看不见shell提示符,按键盘方向键的上箭头。

现在让我们启动在该容器里基于Apache的HTTP服务:

$ /etc/init.d/apache2 start

到这里为止,任何位于backend网络中的容器将可以连接到我们刚才创建的Apache HTTP服务器上。

我们可以通过在另一个终端上开启一个客户端容器并且把它至于backend网络进行测试。

就像这样:

$ sudo docker run -itd --net=backend --name=client client_img /bin/bash

进入容器:

$ sudo docker attach client

同样地,如果你看不见shell提示符,按键盘方向键的上箭头。
接着运行:

$ curl server

你应该可以看见默认的HTML页面。这意味着我们配置的网络是可以正常运行的。

就像在本系列文章的第一节中提及到的一样,Docker负责设置容器名称便于解析,这就是为什么我们可以直接用curl server 这个命令而不用知晓它的IP地址。

我们可以创建多个用户定义的网络,并且可以根据应用程序的拓扑结构把这些容器放在单个或多个网络中。这是非常灵活的,特别是对于那些需要交付微服务(microservices),多租户(multitenancy)及微分段(micro-segmentation)的人员来说是非常有用的。

多主机网络(Multi-Host Networking)

如果我们想要建立一个跨越多台主机的网络该怎么做呢?当然,自从Docker1.9.0之后,你就可以这么做了!

目前为止,我们已经使用了基于本地范围的bridge网络驱动,这意味着桥接网络是在Docker宿主机本地的。Docker现在提供了一个新的全局范围的overlay网络驱动,这意味着overlay的网络可以跨越多台Docker宿主机。并且这些Docker宿主机可以存在于不同的数据中心,甚至不同的云服务提供商中!

为了设置一个overlay网络,以下几点是必须的:

  • 一台内核版本高于3.16的主机
  • 关键的key-value存储(例如 etcdConsul和 Apache ZooKeeper
  • 集群内的主机可以保证连接到以上的key-value存储
  • 每一个集群内的主机都正确配置了基于 Docker Engine的后台实例

让我们来看一个案例吧。

我将会使用multihost-local.sh脚本和Docker Machine这个命令去开启三台虚拟主机。

这个脚本是用于虚拟机的而不是用于容器的。在这之后,我们在这些虚拟机上面运行Docker命令去模拟一个Docker宿主机集群。

在运行过脚本之后,可以看到我现在有的主机清单:

$ docker-machine ls
NAME         ACTIVE   DRIVER       STATE     URL                         SWARM   ERRORS
mhl-consul   -        virtualbox   Running   tcp://192.168.99.100:2376
mhl-demo0    -        virtualbox   Running   tcp://192.168.99.101:2376
mhl-demo1    -        virtualbox   Running   tcp://192.168.99.102:2376

好了,那么让我们倒退回去看下刚才发生了些什么。

这个脚本利用了Docker Machine,这意味着你必须安装它。在本篇文章中,我们安装了0.5.2版本的Docker Machine。你可以参考该版本的发行注释说明来下载并安装它。

该脚本(multihost-local.sh)使用了Docker Machine去部署三台基于VirtualBox的虚拟机并且安装并适当的配置了Docker Engine。

Docker Machine可以与很多主流虚拟化管理程序以及云服务提供商一起协助。它现在支持AWS、Digital Ocean、Google Cloud Platform、IBM Softlayer、Microsoft Azure和Hyper-V、OpenStack、Rachspace、VitrualBox、VMware Fusion、vCloud Air and vSphere。

我们现在有了三个虚拟机:

  • mhl-consul: 运行 Consul
  • mhl-demo0: Docker 集群节点
  • mhl-demo1: Docker 集群节点

这些Docker集群节点是被配置为协调通过VM来运行Consul,我们的key-value仓库。这也就是这些集群所涉及到的。

很酷吧,让我们再快速地往前看一看。

现在,让我们设置一个overlay网络。

首先,我们需要用一个在mhl-demo0这个VM上的终端,像这样:

$ eval $(docker-machine env mhl-demo0)

然后运行:

$ docker network create -d overlay myapp

该命令建立了一个名为myapp的跨越所有集群中主机的overlay网络。由于Docker通过key-value与该集群上的其他主机协调使得该操作变成了可能。

为了确保它正常的工作,我们可以通过终端登录到每一个集群中的VM去列出这些Docker网络。

复制下面所有的eval命令,然后用相对应的主机名去替换mhl-demo0。 

然后运行:

$ docker network ls
NETWORK ID          NAME                DRIVER
7b9e349b2f01        host                    host
1f6a49cf5d40        bridge                  bridge
38e2eba8fbc8        none                   null
385a8bd92085        myapp               overlay

到这里你就看到名为myapp的overlay网络了。

咱们成功啦!

但请记住:我们目前仅仅是创建了一个基于Docker 虚拟机的集群并配置了用于共享的overlay网络。我们实际上并没有创建任何Docker容器。所以让我们接着创建它们并来试一下这个overlay网络。

我们将做以下步骤:

  1. 在mhl-demo0宿主机上运行默认地nginx镜像(这提供给了我们一个预先配置好的Nginx HTTP服务器)
  2. 在mhl-demo1宿主机上运行默认的busybox镜像(它提供给我们一个基本的操作系统并且还包含一个类似于基于GNU的Wget工具)
  3. 将两个容器添加进myapp网络
  4. 测试他们之间的网络连通性

首先,让我们调出在mhl-demo0宿主机上的终端:

$ eval $(docker-machine env mhl-demo0)

然后启动nginx镜像:

$ docker run --name ng1 --net=myapp -d nginx

简而言之,我们现在有以下环境:

  • 一台基于Nginx的HTTP服务器
  • 该服务跑在名为ng1的容器里
  • 它处在myapp网络中
  • 该容器位于mhl-demo0宿主机上

让我们从其他宿主机上的另外一个容器试着去访问该环境,去验证它是可用的。

这一次调出mhl-demo1宿主机上的终端:

$ eval $(docker-machine env mhl-demo1)

然后运行:

$ docker run -it --net=myapp busybox wget -qO- ng1

以上命令其实做了以下几点:

  • 从busybox镜像中创建了一个未命名的容器
  • 将它添加进了myapp网络
  • 运行了wget -qO- ng1命令
  • 并且停止了该容器(我们在这之前是让容器运行的)

在以上的Wget命令中,ng1是我们Nginx的容器名称。Docker可以让我们使用解析到的主机名作为容器名称,甚至该容器是运行在不同的Docker宿主机上。

如果所有操作都是成功的,那么我们应该会看见以下类似的内容:

<!DOCTYPE html>

<html>

<head>

<title>Welcome to nginx!</title>

你看吧!我们现在拥有了一个基于多主机的容器网络。

总结

Docker给予了诸如轻量级且独立地并能隔离的环境这样的优点。然而,要使容器对我们而言有用途,容器之间以及容器与主机网络之间要能互相通信才是至关重要的。

在这一系列文章中,我们探索了一些容器间本地互联和跨多个宿主机互联的方法。同样地,我们也聊了聊该如何在主机网络中去连接多个容器。

原文链接:Connecting Docker Containers, Part Two (翻译:薛开成)

===========================================
译者介绍
薛开成,趋势科技南京研发中心工程工具服务事业部基础架构高级工程师,负责容器仓库实施及落地。

原文发布时间为:2016-03-23

本文作者:绝地魔影

本文来自合作伙伴DockerOne,了解相关信息可以关注DockerOne。

原文标题:Docker容器互联方法--篇二

时间: 2024-09-17 04:18:46

Docker容器互联方法--篇二的相关文章

Docker容器互联方法-篇一

本文讲的是Docker容器互联方法-篇一,[编者的话]本文为Eddy Mavungu博士于DEIS官方博客中发布的系列文章的第一部分,Eddy博士在本篇系列文章中分享了Docker容器间互联的方法,并且做了演示.Eddy博士是DEIS公司的创始人,同时也是一位高级研究顾问.本文根据他于DEIS官方博客上发布的文章翻译而成. Docker容器都是独立的,互相隔离的环境.然而,它们通常只有互相通信时才能发挥作用. 虽然有许多方法可以连接容器们,可是我将并不会试着去将其全部讨论在内.但是在这一系列的方

Docker 容器互联方法

Docker 容器互联方法 Docker容器都是独立的,互相隔离的环境.然而,它们通常只有互相通信时才能发挥作用. 虽然有许多方法可以连接容器们,可是我将并不会试着去将其全部讨论在内.但是在这一系列的方法中,我们将看看那些常用的做法. 虽然看起来是很浅显,但是这对于与Docker成天打交道的朋友来说,理解这些技术及底层的设计理念就显得非常地重要了. 理解这些主题将会: 帮助开发和运维人员探索广泛的容器部署的选择. 让开发和运维人员更自信的着手于微服务microservice架构设计. 让开发和运

Docker 容器互联

Docker容器互联实现容器间通信 首先,大家如果看到有什么不懂的地方,欢迎吐槽!!! 我会在当天或者第二天及时回复,并且改进~~ 容器的连接(linking)系统是除了端口映射以外的另一种可以与容器中应用进行交互的方式.它会在源和接收容器之间创建一个隧道,接收容器可以看到源容器指定的信息. 一.自定义容器命名 连接容器依据系统容器的名称来执行,但自定义命名容器有两个好处 自定义的命名,比较好记.比如一个web应用容器,我们可以起名为web 当要连接其他容器的时候,可以作为一个有用的参考点,比如

Docker容器进入的4种方式(转)

这个文章不错,几种方式及使用范围都讲得清楚. 另外,还有一个文章说了为什么docker中并不合适ssh服务安装的情况. 我现在也是用第四种方式, docker exec -it [docker容器ID] /bin/bash Docker容器进入的4种方式 http://www.cnblogs.com/xhyan/p/6593075.html 为什么不需要在 Docker 容器中运行 sshd http://www.oschina.net/translate/why-you-dont-need-t

详解挂载运行的docker容器中如何挂载文件系统_docker

前言 感觉最近很多人都在问docker相关的问题,关于怎么操作一个已经启动的docker容器的文件系统,首先我发现这非常困难,因为 mnt的命名空间. 为了登录进入一个已经启动的docker容器,我们需要这么做: 使用nsenter来在临时挂载点上挂载整个docker容器的文件系统. 创建一个特定目录的绑定挂载来当作卷来使用. 卸载临时挂载. 好吧,开始实践. 启动一个名为charlie的docker实例: $ docker run --name charlie -ti ubuntu bash

如何运行多进程Docker容器?

一般来说,Docker容器比较适合运行单个进程.例如,项目"使用多个Docker容器运行Kubernetes",Kubernetes的各个组件分别运行在各个容器之中,每个容器只运行单个进程. 然而,很多时候我们需要在Docker容器中运行多个进程.例如,项目"使用单个Docker容器运行Kubernetes",kubernetes的各个组件均运行在同一个容器中,该容器中运行了多个进程.那么,如何运行多进程Docker容器? 一种方法是使用Shell脚本,另一种方法是

使用OpenStack管理Docker容器(二)

本文讲的是使用OpenStack管理Docker容器(二),[编者的话]本文将讲述如何使用OpenStack创建并管理Docker,有3种流行的使用方法,使用的分别是Nova Docker驱动,Heat Docker插件,以及Magnum.这篇文章分成2部分,第一部分,将主要介绍Nova Docker驱动的用法,第二部分,是关于Heat Docker插件和Magnum.这是序列文章的第二部分,即最后一部分. 这篇文章是之前的那篇<如何使用OpenStack管理Docker容器>的后续,在这篇文

DataSnap 2009 系列之二 (方法篇)

(方法篇)     在过去客户端要调用远程服务器的方法需要通过在TLB里添加接口并且在服务器对象中实现,在DataSnap 2009中调用远程服务器的方法是基于delphi的RTTI机制的,想要一个类允许被远程调用需要做以下两点:     1.把该类和DSServerClass连接在一起     注意:DSServerClass必须设置要导出的类 否则会出现SOnGetClassNotSet的异常信息     2.该类必须使用$MethodInfo编译指令生成详细的RTTI信息     所以我们

解决Docker容器时区及时间不同步问题的方法_docker

今天在系统集成测试时由测试人员提交了一个测试bug,原因是提交业务数据时间与实际时间(北京时间)有偏差,导致统计异常.由于我们集成测试是向测试人员直接提供完整的Docker镜像作为测试环境,原因应该是出在容器时间设置上. 拿到交付的docker镜像后,启动后进入容器控制台,使用date命令查看果然时间不正确.再查看宿主机时间是正确,这样肯定是容器启动时未将时区与宿主机保持同步了,由于测试镜像是由dockfile直接构建,因此问题基本了定准在dockerfile文件上了. 打开dockerfile