weave实现docker跨主机通讯_weave docker - CSDN
精华内容
参与话题
  • 使用weave实现跨主机docker容器互联

    千次阅读 2017-05-15 11:03:18
    关于weave的原理不做细致的说明,如果想了解...In this post,使用阿里云3台ECS服务器进行weave搭建,并测试搭建weave后,跨主机docker容器的连通性。 场景: 10.162.204.252 node1 10.171.31.181 node2 10.171.1

    关于weave的原理不做细致的说明,如果想了解weave可以登陆官网:https://www.weave.works/

     

    In this post,使用阿里云3台ECS服务器进行weave搭建,并测试搭建weave后,跨主机docker容器的连通性。

    场景:
    10.162.204.252 node1
    10.171.31.181 node2
    10.171.19.139 node3

    一、在所有需要跨主机互通的docker宿主机安装weave。
    1.在node1上安装weave,并启动weave。
    wget -O /usr/bin/weave https://raw.githubusercontent.com/zettio/weave/master/weave
    chmod +x /usr/bin/weave
    weave launch

    *注释:在阿里云ECS执行weave launch启动会报错,请在启动的时候加--ipalloc-range 172.16.0.0/12,由于默认ip地址为10段。

    2.在node2上安装weave,并启动weave,并连接node1,如果有多个,可以在连接的时候指定多个。
    wget -O /usr/bin/weave https://raw.githubusercontent.com/zettio/weave/master/weave
    chmod +x /usr/bin/weave
    weave launch 10.162.204.252 --ipalloc-range 172.16.0.0/12

    3.在node3上安装weave,并启动weave,并连接node1,如果有多个,可以在连接的时候指定多个。
    wget -O /usr/bin/weave https://raw.githubusercontent.com/zettio/weave/master/weave
    chmod +x /usr/bin/weave
    weave launch 10.162.204.252 10.171.31.181 --ipalloc-range 172.16.0.0/12


    二、在所有需要跨主机互通的docker宿主机启动docker测试容器。
    1.在node1上,启动一个测试容器,centos或者ubuntu都可以。
    weave run 192.168.4.1/24 -it --name node1 ubuntu /bin/bash

    2.在node2上,启动一个测试容器,centos或者ubuntu都可以。
    weave run 192.168.4.2/24 -it --name node2 centos /bin/bash

    3.在node1上,启动一个测试容器,centos或者ubuntu都可以。
    weave run 192.168.4.3/24 -it --name node3 centos /bin/bash

    三、测试容器的互通性。
    1.登陆node1上启动的测试容器,测试与node2和node3上docker容器的连通性。


    2.登陆node2上启动的测试容器,测试与node1和node3上docker容器的连通性。

    3.登陆node3上启动的测试容器,测试与node1和node2上docker容器的连通性。

     

    到此,如果没有出现任何问题,跨主机的docker容器已经能够互联。

    展开全文
  • Weave实现跨主机容器互联

    Docker的原生网络支持非常有限,且没有跨主机的集群网络方案。目前实现Docker网络的开源方案有Weave、Kubernetes、Flannel、Pipework以及SocketPlane等,其中Weave被评价为目前最靠谱的,那么这里就对Weave的基本原理及使用方法做个总结。


    简介

    Weave是由Zett.io公司开发的,它能够创建一个虚拟网络,用于连接部署在多台主机上的Docker容器,这样容器就像被接入了同一个网络交换机,那些使用网络的应用程序不必去配置端口映射和链接等信息。外部设备能够访问Weave网络上的应用程序容器所提供的服务,同时已有的内部系统也能够暴露到应用程序容器上。Weave能够穿透防火墙并运行在部分连接的网络上,另外,Weave的通信支持加密,所以用户可以从一个不受信任的网络连接到主机。

    这里写图片描述

    这里写图片描述


    安装与启动

    直接从github下载二进制文件安装。

    # sudo wget -O /usr/local/bin/weave https://raw.githubusercontent.com/zettio/weave/master/weave
    # sudo chmod a+x /usr/local/bin/weave
    

    启动weave路由器,这个路由器其实也是以容器的形式运行的。

    # weave launch
    Unable to find image 'zettio/weave' locally
    ......
    

    此时会发现有两个网桥,一个是Docker默认生成的,另一个是Weave生成的。
    这里写图片描述

    这里写图片描述
    接下来就可以运行应用容器,使用weave提供的网络功能了。


    简单使用

    准备
    1. host1: 10.0.2.6
    2. host2: 10.0.2.8
    3. host1上的应用容器1: 192.168.0.2/24 host1上的应用容器2: 192.168.1.2/24
    4. host2上的应用容器1: 192.168.0.3/24
    两台机上均安装Docker及Weave,并均启动好Weave路由容器。

    在两台机上均启动一个应用容器。可以直接使用weave run命令,也可以先使用docker run启动好容器,然后使用weave attach命令给容器绑定IP地址。

    # weave run 192.168.0.2/24 -itd ubuntu bash
    

    或者

    # docker run -itd ubuntu bash
    # weave attach 192.168.0.2/24 $ID
    

    此时发现两个容器之间是不通的,需要使用weave connect命令在两台weave的路由器之间建立连接。

    # weave connect 10.0.2.8
    

    会发现,此时位于两台不同主机上的容器之间可以相互ping通了。但是处于不同子网的两个容器是不能互联的,这样我们就可以使用不同子网进行容器间的网络隔离了。

    我们会发现,如果不使用Docker的原生网络,在容器内部是不能访问宿主机以及外部网络的。此时我们可以使用weave expose 192.168.0.1/24来给weave网桥添加IP,以实现容器与宿主机网络连通。但是,此时在容器内部依然不能访问外部网络。
    我们可以同时使用Docker的原生网络和weave网络来实现容器互联及容器访问外网和端口映射。使用外部网络及端口映射的时候就使用docker0网桥,需要容器互联的时候就使用weave网桥。每个容器分配两个网卡。


    其他特性

    • 应用隔离:不同子网容器之间默认隔离的,即便它们位于同一台物理机上也相互不通(使用-icc=false关闭容器互通);不同物理机之间的容器默认也是隔离的
    • 安全性:可以通过weave launch -password wEaVe设置一个密码用于weave peers之间加密通信
    • 查看weave路由状态:weave ps

    问题

    1. 容器重启问题
      如果使用weave,则就不能再使用docker自带的auto-restart feature(如docker run –restart=always redis),因为weave是在docker之外为容器配置的网络,容器重启的时候docker本身不会做这些事情。因而,还需额外的工具来管理容器的状态(比如systemd, upstart等),这些工具要调用weave命令(weave run/start/attach)来启动容器。



    参考文档
    1. http://www.cnblogs.com/feisky/p/4093717.html
    2. http://www.51gocloud.com/?p=1260
    3. http://debugo.com/docker-weave/

    展开全文
  • docker容器网络通信原理分析

    万次阅读 2016-04-27 10:00:20
    而容器的网络通信又可以分为两大方面:单主机容器上的相互通信,和跨主机的容器相互通信。而本文将分别针对这两方面,对容器的通信原理进行简单的分析,帮助大家更好地使用dockerdocker主机容器通信基于对...

    docker容器网络通信原理分析

    原作者 冯建建@天云软件
    转载请注明


    概述

    自从docker容器出现以来,容器的网络通信就一直是大家关注的焦点,也是生产环境的迫切需求。而容器的网络通信又可以分为两大方面:单主机容器上的相互通信,和跨主机的容器相互通信。而本文将分别针对这两方面,对容器的通信原理进行简单的分析,帮助大家更好地使用docker。

    docker单主机容器通信

    基于对net namespace的控制,docker可以为在容器创建隔离的网络环境,在隔离的网络环境下,容器具有完全独立的网络栈,与宿主机隔离,也可以使容器共享主机或者其他容器的网络命名空间,基本可以满足开发者在各种场景下的需要。按docker官方的说法,docker容器的网络有五种模式:

    • bridge:docker默认的网络模式,为容器创建独立的网络命名空间,容器具有独立的网卡等所有单独的网络栈,是最常用的使用方式。
    • host:直接使用容器宿主机的网络命名空间。
    • none:为容器创建独立网络命名空间,但不为它做任何网络配置,容器中只有lo,用户可以在此基础上,对容器网络做任意定制。
    • 其他容器:与host模式类似,只是容器将与指定的容器共享网络命名空间。
    • 用户自定义:docker 1.9版本以后新增的特性,允许容器使用第三方的网络实现或者创建单独的bridge网络,提供网络隔离能力。

    这些网络模式在相互网络通信方面的对比如下所示:

    模式 是否支持多主机 南北向通信机制 东西向通信机制
    bridge 宿主机端口绑定 通过Linux bridge
    host 按宿主机网络通信 按宿主机网络通信
    none 无法通信 只能用link通信
    其他容器 宿主机端口绑定 通过link通信
    用户自定义 按网络实现而定 按网络实现而定 按网络实现而定

    南北向通信指容器与宿主机外界的访问机制,东西向流量指同一宿主机上,与其他容器相互访问的机制。

    host模式

    由于容器和宿主机共享同一个网络命名空间,换言之,容器的IP地址即为宿主机的IP地址。所以容器可以和宿主机一样,使用宿主机的任意网卡,实现和外界的通信。其网络模型可以参照下图:
    host模式

    采用host模式的容器,可以直接使用宿主机的IP地址与外界进行通信,若宿主机具有公有IP,那么容器也拥有这个公有IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行NAT转换,而且由于容器通信时,不再需要通过linuxbridge等方式转发或者数据包的拆封,性能上有很大优势。当然,这种模式有优势,也就有劣势,主要包括以下几个方面:

    • 最明显的就是容器不再拥有隔离、独立的网络栈。容器会与宿主机竞争网络栈的使用,并且容器的崩溃就可能导致宿主机崩溃,在生产环境中,这种问题可能是不被允许的。
    • 容器内部将不再拥有所有的端口资源,因为一些端口已经被宿主机服务、bridge模式的容器端口绑定等其他服务占用掉了。

    bridge模式

    bridge模式是docker默认的,也是开发者最常使用的网络模式。在这种模式下,docker为容器创建独立的网络栈,保证容器内的进程使用独立的网络环境,实现容器之间、容器与宿主机之间的网络栈隔离。同时,通过宿主机上的docker0网桥,容器可以与宿主机乃至外界进行网络通信。其网络模型可以参考下图:
    bridge模式

    从上面的网络模型可以看出,容器从原理上是可以与宿主机乃至外界的其他机器通信的。同一宿主机上,容器之间都是连接掉docker0这个网桥上的,它可以作为虚拟交换机使容器可以相互通信。然而,由于宿主机的IP地址与容器veth pair的 IP地址均不在同一个网段,故仅仅依靠veth pair和namespace的技术,还不足以使宿主机以外的网络主动发现容器的存在。为了使外界可以方位容器中的进程,docker采用了端口绑定的方式,也就是通过iptables的NAT,将宿主机上的端口端口流量转发到容器内的端口上。

    举一个简单的例子,使用下面的命令创建容器,并将宿主机的3306端口绑定到容器的3306端口:
    docker run -tid --name db -p 3306:3306 mysql

    在宿主机上,可以通过iptables -t nat -L -n,查到一条DNAT规则:

    DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:3306 to:172.17.0.5:3306

    上面的172.17.0.5即为bridge模式下,创建的容器IP。

    很明显,bridge模式的容器与外界通信时,必定会占用宿主机上的端口,从而与宿主机竞争端口资源,对宿主机端口的管理会是一个比较大的问题。同时,由于容器与外界通信是基于三层上iptables NAT,性能和效率上的损耗是可以预见的。

    none模式

    在这种模式下,容器有独立的网络栈,但不包含任何网络配置,只具有lo这个loopback网卡用于进程通信。也就是说,none模式为容器做了最少的网络设置,但是俗话说得好“少即是多”,在没有网络配置的情况下,通过第三方工具或者手工的方式,开发这任意定制容器的网络,提供了最高的灵活性

    其他容器模式

    其他网络模式是docker中一种较为特别的网络的模式。在这个模式下的容器,会使用其他容器的网络命名空间,其网络隔离性会处于bridge桥接模式与host模式之间。当容器共享其他容器的网络命名空间,则在这两个容器之间不存在网络隔离,而她们又与宿主机以及除此之外其他的容器存在网络隔离。其网络模型可以参考下图:
    container模式

    在这种模式下的容器可以通过localhost来同一网络命名空间下的其他容器,传输效率较高。而且这种模式还节约了一定数量的网络资源,但它并没有改变容器与外界通信的方式。在一些特殊的场景中非常有用,例如,kubernetes的pod,kubernetes为pod创建一个基础设施容器,同一pod下的其他容器都以其他容器模式共享这个基础设施容器的网络命名空间,相互之间以localhost访问,构成一个统一的整体。

    用户定义网络模式

    在用户定义网络模式下,开发者可以使用任何docker支持的第三方网络driver来定制容器的网络。并且,docker 1.9以上的版本默认自带了bridge和overlay两种类型的自定义网络driver。可以用于集成calico、weave、openvswitch等第三方厂商的网络实现。
    除了docker自带的bridge driver,其他的几种driver都可以实现容器的跨主机通信。而基于bdrige driver的网络,docker会自动为其创建iptables规则,保证与其他网络之间、与docker0之间的网络隔离。
    例如,使用下面的命令创建一个基于bridge driver的自定义网络:

    docker network create bri1

    则docker会自动生成如下的iptables规则,保证不同网络上的容器无法互相通信。

    -A DOCKER-ISOLATION -i br-8dba6df70456 -o docker0 -j DROP
    -A DOCKER-ISOLATION -i docker0 -o br-8dba6df70456 -j DROP

    除此之外,bridge driver的所有行为都和默认的bridge模式完全一致。而overlay及其他driver,则可以实现容器的跨主机通信。

    docker跨主机容器通信

    早期大家的跨主机通信方案主要有以下几种:

    • 容器使用host模式:容器直接使用宿主机的网络,这样天生就可以支持跨主机通信。虽然可以解决跨主机通信问题,但这种方式应用场景很有限,容易出现端口冲突,也无法做到隔离网络环境,一个容器崩溃很可能引起整个宿主机的崩溃。

    • 端口绑定:通过绑定容器端口到宿主机端口,跨主机通信时,使用主机IP+端口的方式访问容器中的服务。显而易见,这种方式仅能支持网络栈的四层及以上的应用,并且容器与宿主机紧耦合,很难灵活的处理,可扩展性不佳。

    • docker外定制容器网络:在容器通过docker创建完成后,然后再通过修改容器的网络命名空间来定义容器网络。典型的就是很久以前的pipework,容器以none模式创建,pipework通过进入容器的网络命名空间为容器重新配置网络,这样容器网络可以是静态IP、vxlan网络等各种方式,非常灵活,容器启动的一段时间内会没有IP,明显无法在大规模场景下使用,只能在实验室中测试使用。

    • 第三方SDN定义容器网络:使用Open vSwitch或Flannel等第三方SDN工具,为容器构建可以跨主机通信的网络环境。这些方案一般要求各个主机上的docker0网桥的cidr不同,以避免出现IP冲突的问题,限制了容器在宿主机上的可获取IP范围。并且在容器需要对集群外提供服务时,需要比较复杂的配置,对部署实施人员的网络技能要求比较高。

    上面这些方案有各种各样的缺陷,同时也因为跨主机通信的迫切需求,docker 1.9版本时,官方提出了基于vxlan的overlay网络实现,原生支持容器的跨主机通信。同时,还支持通过libnetwork的plugin机制扩展各种第三方实现,从而以不同的方式实现跨主机通信。就目前社区比较流行的方案来说,跨主机通信的基本实现方案有以下几种:

    • 基于隧道的overlay网络:按隧道类型来说,不同的公司或者组织有不同的实现方案。docker原生的overlay网络就是基于vxlan隧道实现的。ovn则需要通过geneve或者stt隧道来实现的。flannel最新版本也开始默认基于vxlan实现overlay网络。

    • 基于包封装的overlay网络:基于UDP封装等数据包包装方式,在docker集群上实现跨主机网络。典型实现方案有weaveflannel的早期版本。

    • 基于三层实现SDN网络:基于三层协议和路由,直接在三层上实现跨主机网络,并且通过iptables实现网络的安全隔离。典型的方案为Project Calico。同时对不支持三层路由的环境,Project Calico还提供了基于IPIP封装的跨主机网络实现。

    下面,本从网络通信模型的角度,对这些方案的通信原理做一个简单的比较,从中可以窥见各种方案在性能上的本质差别。

    docker容器的CNM模型

    首先,科普下docker容器的CNM网络模型,calico、weave等第三方实现都是基于CNM模型与docker集成的。CNM网络模型的结构如下图所示:
    docker-cnm-model

    在上面的图中:

    • Sandbox代表容器的网络命名空间,包含了容器的完整网络栈,不同的容器之间可以完全隔离。在宿主机上,就表现为独立的网络命名空间。
    • Endpoint代表容器接入网络的端点,可以形象地认为一个Endpoint对容器来说,就是一张物理网卡。
    • Network代表一组可以直接相互通信的Endpoint集合,可以基于LinuxBridge或者VLAN实现。在宿主机上,每个网络都是一个独立的网络命名空间,宿主机上同一网络的的容器,都通过veth pair链接到这个网络命名空间上。

    docker原生overlay的网络通信模型

    docker官方文档的示例中,overlay网络是在swarm集群中配置的,但实际上,overlay网络可以独立于swarm集群实现,只需要满足以下前提条件即可。

    • 有consul或者etcd,zookeeper的集群key-value存储服务

    • 组成集群的所有主机的主机名不允许重复,因为docker守护进程与consul通信时,以主机名相互区分

    • 所有主机都可以访问集群key-value的服务端口,按具体类型需要打开进行配置。例如docker daemon启动时增加参数
      --cluster-store=etcd://<ETCD-IP>:4001 -
      -cluster-advertise=eth0:2376

    • overlay网络依赖宿主机三层网络的组播实现,需要在所有宿主机的防火墙上打开下列端口

    协议 端口 说明
    udp 4789 容器之间流量的vxlan端口
    tcp/udp 7946 docker守护进程的控制端口

    + 宿主机内核版本3.10以上(1.9版本时,要求3.16以上)

    满足以上条件后,就可以通过docker network命令来创建跨主机的overlay网络了,例如:
    docker network create -d overlay overlaynet
    在集群的不同主机上,使用overlaynet这个网络创建容器,形成如下图所示的网络拓扑:
    docker-overlay-network

    由于容器和overlay的网络的网络命名空间文件不再操作系统默认的/var/run/netns下,只能手动通过软连接的方式查看。
    ln -s /var/run/docker/netns /var/run/netns
    这样就可以通过ip netns查看到容器和网络的网络命名空间了。

    容器的网络命名空间名称可以通过docker inspect -f '{{.NetworkSettings.SandboxKey}}' <容器ID>方式查看到。网络的网络命名空间则是通过docker network ls查看到的网络短ID。

    有时候网络的网络命名空间名称前面会带上1-2-等序号,有时候不带。但不影响网络的通信和操作。

    从这个通信过程中来看,跨主机通信过程中的步骤如下:
    1. 容器的网络命名空间与overlay网络的网络命名空间通过一对veth pair连接起来,当容器对外通信时,veth pair起到网线的作用,将流量发送到overlay网络的网络命名空间中。
    2. 容器的veth pair对端eth2与vxlan设备通过br0这个Linux bridge桥接在一起,br0在同一宿主机上起到虚拟机交换机的作用,如果目标地址在同一宿主机上,则直接通信,如果不再则通过设置在vxlan1这个vxlan设备进行跨主机通信。
    3. vxlan1设备上会在创建时,由docker daemon为其分配vxlan隧道ID,起到网络隔离的作用。
    4. docker主机集群通过key/value存储共享数据,在7946端口上,相互之间通过gossip协议学习各个宿主机上运行了哪些容器。守护进程根据这些数据来在vxlan1设备上生成静态MAC转发表。
    5. 根据静态MAC转发表的设置,通过UDP端口4789,将流量转发到对端宿主机的网卡上。
    6. 根据流量包中的vxlan隧道ID,将流量转发到对端宿主机的overlay网络的网络命名空间中。
    7. 对端宿主机的overlay网络的网络命名空间中br0网桥,起到虚拟交换机的作用,将流量根据MAC地址转发到对应容器内部。

    虽然上面的网络通信模型可以实现容器的跨主机通信,但还是有一些缺陷,造成实际使用上的不便,例如:

    • 由于vxlan网络与宿主机网络默认不再同一网络环境下,为了解决宿主机与容器的通信问题,docker为overlay网络中的容器额外增加了网卡eth1作为宿主机与容器通信的通道。这样在使用容器服务时,就必须根据访问性质的不同,选择不同的网卡地址,造成使用上的不便。
    • 容器对外暴露服务仍然只能使用端口绑定的方式,外界无法简单地直接使用容器IP访问容器服务。
    • 从上面的通信过程中来看,原生的overlay网络通信必须依赖docker守护进程及key/value存储来实现网络通信,约束较多,容器在启动后的一段时间内可能无法跨主机通信,这对一些比较敏感的应用来说是不可靠的。

    weave网络通信模型

    weave通过在docker集群的每个主机上启动虚拟的路由器,将主机作为路由器,形成互联互通的网络拓扑,在此基础上,实现容器的跨主机通信。其主机网络拓扑参见下图:
    weave主机拓扑

    如上图所示,在每一个部署Docker的主机(可能是物理机也可能是虚拟机)上都部署有一个W(即weave router,它本身也可以以一个容器的形式部署)。weave网络是由这些weave routers组成的对等端点(peer)构成,并且可以通过weave命令行定制网络拓扑。

    每个部署了weave router的主机之间都会建立TCP和UDP两个连接,保证weave router之间控制面流量和数据面流量的通过。控制面由weave routers之间建立的TCP连接构成,通过它进行握手和拓扑关系信息的交换通信。控制面的通信可以被配置为加密通信。而数据面由weave routers之间建立的UDP连接构成,这些连接大部分都会加密。这些连接都是全双工的,并且可以穿越防火墙。
    当容器通过weave进行跨主机通信时,其网络通信模型可以参考下图:
    docker weave网络拓扑

    从上面的网络模型图中可以看出,对每一个weave网络中的容器,weave都会创建一个网桥,并且在网桥和每个容器之间创建一个veth pair,一端作为容器网卡加入到容器的网络命名空间中,并为容器网卡配置ip和相应的掩码,一端连接在网桥上,最终通过宿主机上weave router将流量转发到对端主机上。其基本过程如下:

    1. 容器流量通过veth pair到达宿主机上weave router网桥上。
    2. weave router在混杂模式下使用pcap在网桥上截获网络数据包,并排除由内核直接通过网桥转发的数据流量,例如本子网内部、本地容器之间的数据以及宿主机和本地容器之间的流量。捕获的包通过UDP转发到所其他主机的weave router端。
    3. 在接收端,weave router通过pcap将包注入到网桥上的接口,通过网桥的上的veth pair,将流量分发到容器的网卡上。

    weave默认基于UDP承载容器之间的数据包,并且可以完全自定义整个集群的网络拓扑,但从性能和使用角度来看,还是有比较大的缺陷的:

    • weave自定义容器数据包的封包解包方式,不够通用,传输效率比较低,性能上的损失也比较大。
    • 集群配置比较负载,需要通过weave命令行来手工构建网络拓扑,在大规模集群的情况下,加重了管理员的负担。

    calico网络通信模型

    calico是纯三层的SDN 实现,它基于BPG 协议和Linux自身的路由转发机制,不依赖特殊硬件,容器通信也不依赖iptables NAT或Tunnel 等技术。能够方便的部署在物理服务器、虚拟机(如 OpenStack)或者容器环境下。同时calico自带的基于iptables的ACL管理组件非常灵活,能够满足比较复杂的安全隔离需求。

    在主机网络拓扑的组织上,calico的理念与weave类似,都是在主机上启动虚拟机路由器,将每个主机作为路由器使用,组成互联互通的网络拓扑。当安装了calico的主机组成集群后,其拓扑如下图所示:
    calico主机拓扑

    每个主机上都部署了calico/node作为虚拟路由器,并且可以通过calico将宿主机组织成任意的拓扑集群。当集群中的容器需要与外界通信时,就可以通过BGP协议将网关物理路由器加入到集群中,使外界可以直接访问容器IP,而不需要做任何NAT之类的复杂操作。

    当容器通过calico进行跨主机通信时,其网络通信模型如下图所示:
    calico容器通信

    从上图可以看出,当容器创建时,calico为容器生成veth pair,一端作为容器网卡加入到容器的网络命名空间,并设置IP和掩码,一端直接暴露在宿主机上,并通过设置路由规则,将容器IP暴露到宿主机的通信路由上。于此同时,calico为每个主机分配了一段子网作为容器可分配的IP范围,这样就可以根据子网的CIDR为每个主机生成比较固定的路由规则。

    当容器需要跨主机通信时,主要经过下面的简单步骤:

    1. 容器流量通过veth pair到达宿主机的网络命名空间上。
    2. 根据容器要访问的IP所在的子网CIDR和主机上的路由规则,找到下一跳要到达的宿主机IP。
    3. 流量到达下一跳的宿主机后,根据当前宿主机上的路由规则,直接到达对端容器的veth pair插在宿主机的一端,最终进入容器。

    从上面的通信过程来看,跨主机通信时,整个通信路径完全没有使用NAT或者UDP封装,性能上的损耗确实比较低。但正式由于calico的通信机制是完全基于三层的,这种机制也带来了一些缺陷,例如:

    • calico目前只支持TCP、UDP、ICMP、ICMPv6协议,如果使用其他四层协议(例如NetBIOS协议),建议使用weave、原生overlay等其他overlay网络实现。
    • 基于三层实现通信,在二层上没有任何加密包装,因此只能在私有的可靠网络上使用。
    • 流量隔离基于iptables实现,并且从etcd中获取需要生成的隔离规则,有一些性能上的隐患。
    展开全文
  • 在同一宿主机下的Docker的容器之间是默认互相联通的。通过docker inspect id或name可以查看到ip地址。...但我们发现这些ip又处于同一网段中而且默认是127.0.0.X,这就是Docker容器默认跨主机之间的链接方法的第一种:网

    在同一宿主机下的Docker的容器之间是默认互相联通的。通过docker inspect id或name可以查看到ip地址。在不通的容器中来执行ping是可以ping通的。

    但我们通过观察发现,每一个启动容器的ip地址不是固定的,所以如果我们通过ip地址来实现互连明显是不靠谱的。但我们发现这些ip又处于同一网段中而且默认是127.0.0.X,这就是Docker容器默认跨主机之间的链接方法的第一种:网桥实现

    在docker宿主机上运行ifconfig命令可以看的存在一个docker0的网桥。Docker容器通过docker0 网桥实现同一主机间中,容器的ip地址分配和访问,所以,如果希望Docker跨主机访问,最简单的方式就是将不同主机的docker0 设置为同一网段。

    整体网络拓扑结构就是这样:

    这里写图片描述

    但是通过这种桥接,所有网卡都要在一个网段下,所以要对每个Docker守护进程对ip的分配做出限制:

    下面,我们就来实现这个结构:

    两台Ubuntu 的 ip:

    Host1 : 10.211.55.3 网卡:eth0

    Host2 :10.211.55.5 网卡 eth1

    网关:10.211.55.1

    对容器ip的划分:

    Host1: 10.211.55.64/26

      地址范围: 10.211.55.65~10.211.55.126

    Host2: 10.211.55.128/26

      地址范围: 10.211.55.129~10.211.55.190

    需要的操作:

    以下,以Host1 为例,Host2 上操作相似,只是网卡名字不一样,我在这里,没有我们不使用默认的docker0 网桥,而是自己新建一个网桥:

    apt-get install bridge-utils 
    1. 分别在Docker主机上建立虚拟网桥:

         Host1: $ sudo brctl addbr br0

    2. 为网桥分配一个同网段ip

        Host1: $ sudo ifconfig br0 10.211.55.10 netmask 255.255.255.0

        Host2: $ sudo ifconfig br0 10.211.55.20 netmask 255.255.255.0

    3. 桥接本地网卡:

        Host1: $ sudo brctl addif br0 eth0

    这里,我们就准备好了网桥设置

    下面我们来修改Docker的配置,使用我们新建的网桥代替docker0:

    1. 修改 /etc/default/docker文件

        $sudo vim /etc/default/docker

    2. 添加守护进程的启动选项:

        Host1: DOCKER_OPTS=” -b=br0 –fixed-cidr=‘10.211.55.64/26‘ “

        Host2: DOCKER_OPTS=” -b=br1 –fixed-cidr=‘10.211.55.128/26‘ “
        
        这里,-b 用来指定容器连接的网桥名字

           –fixed-cidr用来限定为容器分配的IP地址范围

    3. 保存文件并重启Docker服务

        $ sudo service docker restart
        
      下面,就可以来验证:

    1.分别在两个Host上启动一个容器

      $ docker run -it ubuntu /bin/bash
      
    2.在容器中运行ping命令查看连接情况 发现是互通的。

    Docker跨主机容器链接方法二:Open vSwitch
    简称OVS是一个虚拟交换软件.目的是让大规模网络自动化可以通过编程扩展。

    先看一下实现这种方式的连接所具备的条件:
    1.双网卡,Host-Only & NAT
    2.安装Open vSwitch: apt-get install openvswitch-switch

    操作步骤:

    • 1.在虚拟机中建立ovs网桥
    • 2.添加gre连接
    • 3.配置docker容器虚拟网桥
    • 4.为虚拟网桥添加ovs接口
    • 5.添加不同Docker容器网段路由

    具体执行的一些命令如下:
    针对10.211.55.3设置

    sudo ovs-vsctl show  #ovs状态
    sudo ovs-vsctl add-br obr0  #增加ovs网桥名为obr0
    sudo ovs-vsctl add-port obr0 gre0  # 增加gre接口名为obr0
    sudo ovs-vsctl set interface gre0 type=gre
    options:remote_ip=10.211.55.5 
     #设置接口指定链接类型为gre 并指定远程链接的ip
    sudo ovs-vsctl show  
       #接下来设计本机docker网桥
    sudo brctl addbr br0  
    sudo ifconfig br0 10.211.55.1 netmask 255.255.255.0  
    sudo brctl addif br0 obr0#为本机网桥设置ovs网桥链接  
    sudo brctl show  
       #最后设置为docker网桥br0
       #这样本机就可以链接10.211.55.5
    

    对于10.211.55.5要联通10.221.55.3只需要对其设置路由表即可:

    route  
    sudo ip route add 10.211.55.0/24 via 10.211.55.5 dev eth0  

    Docker跨主机容器链接方法三:weave

    建立一个虚拟的网络,用于将运行在不同主机的Docker容器连接起来.
    要实现这种方式所需要的条件如下:
    双网卡,Host-Only & NAT
    host1:10.0.2.6
    host2:10.0.2.8
    host1上应用容器1:192.168.0.2/24
    host2上应用容器1:192.168.0.3/24
    两台机器上均安装Docker以及weave,并均启动好weave路由容器
    在两台机器上均启动一个应用容器.可以直接使用weave run命令,也可以先使用docker run启动好容器,然后使用weave attach命令给容器绑定IP地址

    安装好weava之后,便执行绑定:
    在10.0.2.6之中:

    weava launch 10.0.2.8
    #配置docker处于192.168.0.2/24的网段中
    c2=$(weava run 192.168.0.2/24 -ti ubuntu /bin/bash)
    docker attach $c2

    按如上的方法做了后所以主机内的容器通常是全部可以链接成功的,但一般情况下这样很不安全:

    我们会使用在/etc/default/docker中配置-icc=false (拒绝容器的所有链接)以及–iptables=true (启动宿主机防火墙规则)而对于需要互连的则使用–link来制定。–link 容器名称:自己定义的别名

    展开全文
  • 使用Weave实现Docker多宿主机互联

    千次阅读 2017-05-12 14:43:38
    前提:  之前有关项目的容器都是运行在单台主机上的由于后期扩展增多需要在多台宿主机上运行不同的分布式应用,所以需要docker的多宿主机互联技术 实现方法: ...Docker 1.9 Overlay Network实现跨
  • 十、Docker网络以及宿主机通信

    千次阅读 2017-12-04 18:06:37
    讲在前面: 1.目前实现的是单机部署,如何...2.docker单机通信是docker0桥接eth0,那么跨主机如何使得不同的eth0之间以及docker0之间实现通信呢? 这就是这儿要学习的地方了。再给自己科普一下基础的网络原理 二层
  • 1.跨主机网络解决方案 docker原生的overlay和macvlan 第三方的flannel、weave、calico 众多网络方案是如何与docker集成在一起的? libnetwork docker容器网络库 CNM (Container Network Model)这个模型对容器 2....
  • Docker应用的可视化监控管理

    万次阅读 2016-06-24 06:49:57
    本文介绍一个开源项目Weave Scope,项目地址是https://github.com/weaveworks/scope。Weave Scope这个项目会自动生成容器之间的关系图,方便理解容器之间的关系,也方便监控容器化和微服务化的应用。
  • 上一篇文章Docker原生网络和实现原理中,我们讨论了Docker原生网络实现原理,在Docker原生网络模型在保证端口映射、链接正确的情况下,可实现同一宿主机上容器间的通信和宿主机之间的通信。也在前期文章Openstack ...
  • docker 网络方案--分析

    千次阅读 2017-06-21 09:07:10
    关于SDN和容器 作为近年来比较热的一个概念,众所周知SDN是Software Defined Network的缩写,即软件定义网络。但不同的人对SDN有不同的理解。...Docker自己的网络方案比较简单,就是每个宿主机上会跑一个非常纯
  • Docker的网络配置

    万次阅读 2019-08-20 23:08:35
    一.基本网络配置–docker...Docker在启动时会开启一个虚拟网桥设备docker0,默认的地址为172.17.0.1/16,容器启动后都会被桥接到docker0上,并自动分配到一个ip地址 实验: 1.查看docker的网络有哪些(发现有三种...
  • 11月4日,Docker发布了1.9版本,实现了原本实验性的Networking组件的支持。用户可以在Swarm中使用它或者将其作为Compose 工具。创建虚拟网络并将其连接到容器上,可...Docker 容器实现跨主机通讯主要通过几种方式:自
  • 关于docker容器网络的一些理解

    万次阅读 2020-03-18 11:15:37
    打开微信扫一扫,关注微信公众号【数据与算法联盟】 转载请注明出处:http://blog.csdn.net/gamer_gyt 博主微博:...2:使用 Docker 容器网络 3:Docker 1.9的新网络特性,以及Overlay
  • 魅族大数据上云之路

    千次阅读 2016-05-16 18:05:36
    在开始之前我们默认今天参与直播的各位同学对Hadoop相关技术和docker都有一定的了解,另外以下提到Hadoop是泛指目前魅族大数据使用的Hadoop生态圈技术,资源除特别说明则泛指存储资源、计算资源和网络资源的总和。
  • 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本...docker支持四种网络模式,使用--net选项指定: host,--net=host,如果指定此模式,容器将不会获得一个独立的network name
  • Docker提供了创建这些网络的默认网络驱动程序,你可以创建一个新的Bridge网络,Overlay或Macvlan网络。你还可以创建一个网络插件或远程网络进行完整的自定义和控制。 你可以根据需要创建任意数量的网络,并且可以在...
  • Docker在1.9版本中引入了一整套的自定义网络命令和跨主机网络支持。这是libnetwork项目从Docker的主仓库抽离之后的一次重大变化。不论你是否已经注意到了,Docker的网络新特性即将对用户的习惯产生十分明显的改变。 ...
  • 我们可能只在一个宿主机上创建多个容器,可能需要N个宿主机,每个宿主机上又包含M个容器,我们需要N*M个容器组成一个大的容器集群网络,那么如何宿主机进行容器的网络连接是需要我们关注的,当然,现在也有非常多...
  • Docker搭建Swarm集群

    千次阅读 2017-06-16 18:32:20
    非常好的文章,整个复制过来了,觉得好请点链接,原文更精彩! ... Docker 集群环境实现的新方式 ...通过 Docker Swarm 和 Consul 配置集群并实现主机Docker 容器的互通 谷 铁柏 2016
  • 稍后添加详细说明 1.搭建实验环境 2.演示跨主机的容器之间的通信
1 2 3 4 5 ... 14
收藏数 268
精华内容 107
关键字:

weave实现docker跨主机通讯