Docker默认的网络环境下,单台主机上的Docker容器可以通过docker0网桥直接通信,而不同主机上的Docker容器之间只能通过在主机上做端口映射进行通信。这种端口映射方式对很多集群应用来说极不方便。如果能让Docker容器之间直接使用自己的IP地址进行通信,会解决很多问题。按实现原理可分别直接路由方式、桥接方式(如pipework)、Overlay隧道方式(如flannel、ovs+gre)等。
 
docker0网关修改:
首先删除旧的网络
$ sudo ip link set dev docker0 down
$ sudo brctl delbr docker0
修改 /etc/docker/daemon.json,改变默认docker0网关
{
"bip": "192.188.0.1/16”,
}
查看
$ ifconfig docker0
docker0 Link encap:Ethernet HWaddr 02:42:38:60:08:25
inet addr:192.188.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
或者手动创建一个新的网桥bridge0
$ sudo brctl addbr bridge0
$ sudo ip addr add 192.188.0.1/16 dev bridge0
$ sudo ip link set dev bridge0 up
$ ip addr show bridge0
4: bridge0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state UP group default
link/ether 66:38:d0:0d:76:18 brd ff:ff:ff:ff:ff:ff
inet 192.188.0.1/16 scope global bridge0
valid_lft forever preferred_lft forever
在 Docker 配置文件/etc/docker/daemon.json 中添加如下内容,即可将Docker默认桥接到 创建的网桥上。
{
"bridge": "bridge0",
}
 
直接路由
通过在Docker主机上添加静态路由实现跨宿主机通信:
Pipework
Pipework是一个简单易用的Docker容器网络配置工具。由200多行shell脚本实现。通过使用ip、brctl、ovs-vsctl等命令来为Docker容器配置自定义的网桥、网卡、路由等。
  • 使用新建的br0网桥代替缺省的docker0网桥
  • br0网桥与缺省的docker0网桥的区别:br0和主机eth0之间是veth pair
如图,不同容器之间的通信可以借助pipework这个工具给docker容器新建虚拟网卡并绑定IP桥接到br0
 
Flannel(Flannel + UDP 或者 Flannel + VxLAN)
Flannel实现的容器的跨主机通信通过如下过程实现:
  • 每个主机上安装并运行etcd(或其它分布式健值存储数据库)和flannel;
  • 在etcd中规划配置所有主机的docker0子网范围;Flannel为每个主机自动分配独立的subnet,用户只需要指定一个大的IP池。不同subnet之间的路由信息也由Flannel自动生成和配置。
  • 每个主机上的flanneld根据etcd中的配置,为本主机的docker0分配子网,保证所有主机上的docker0网段不重复,并将结果(即本主机上的docker0子网信息和本主机IP的对应关系)存入etcd库中,这样etcd库中就保存了所有主机上的docker子网信息和本主机IP的对应关系(相当于通过etcd服务维护了一张节点间的路由表);
  • 当需要与其他主机上的容器进行通信时,查找etcd数据库,找到目的容器的子网所对应的outip(目的宿主机的IP);
  • 将原始数据包封装在VXLAN或UDP数据包中,IP层以outip为目的IP进行封装;
  • 由于目的IP是宿主机IP,因此路由是可达的:数据从源容器发出后,经由所在主机的docker0虚拟网卡转发到flannel0虚拟网卡(P2P虚拟网卡),flanneld服务监听在flannel0网卡的另一端,它将原本是数据内容封装后根据自己的路由表投递给目的节点的flanneld服务。
  • VXLAN或UDP数据包到达目的宿主机解封装,解出原始数据包,最终到达目的容器。
PS:Flannel网络有两种模式:上述是一种overlay覆盖网络,而host-gw模式将主机作为网关,依赖于纯三层的ip转发;
缺点:不同Flannel网络中的容器可以直接通信,Flannel没有提供网络隔离。与外网通信需要通过bridge网络。
 
Weave
Weave网络也是一种overlay覆盖网络;
Weave自己负责在主机间交换网络配置信息,不需要etcd或consul这些数据库;
Weave默认配置下所有容器使用10.32.0.0/12的subnet,如果此地址空间与现有IP冲突,则可以通过--ipalloc-range分配特定的subnet。
Weave网络默认配置下所有容器在一个大的subnet中,可以自由通信。如果要实现网络隔离,需要为容器指定不同的subnet或IP;若要与外网通信,则需要将主机加入到weave网络,并把主机当作网关。
 
Calico
Calico是一个纯三层的方案,为虚机及容器提供多主机间通信,没有使用重叠网络(如flannel)驱动,采用虚拟路由代替虚拟交换,每一台虚拟路由器通过BGP协议传播可达信息(路由)到其他虚拟或物理路由器。
Calico通过IP Pool可以为每个主机定制自己的subnet。
Calico默认配置下只允许同一网络中的容器之间通信,但通过其强大的Policy能够实现几乎任意场景的访问控制。
calico包括如下重要组件:
  • Felix:Calico agent,运行在每台workload节点。主要负责路由配置以及ACLS规则的配置以及下发,确保endpoint的连通状态。
  • etcd:分布式键值存储,主要负责网络元数据一致性,确保Calico网络状态的准确性,可以与kubernetes共用;
  • BGP Client:主要负责把Felix写入kernel的路由信息分发到当前Calico网络,确保workload间的通信的有效性;
  • BGP Route Reflector:大规模部署时使用,摒弃所有节点互联的mesh模式,通过一个或者多个BGPRoute Reflector来完成集中式的路由分发。
如下图所示,描述了从源容器经过源宿主机,经过数据中心的路由,然后到达目的宿主机最后分配到目的容器的过程。
整个过程中始终都是根据iptables规则进行路由转发,并没有进行封包、解包的过程。而flannel在进行路由转发的基础上进行了封包解包的操作,浪费了CPU的计算资源。
下图是从网上找到的各个开源网络组件的性能对比。可以看出无论是带宽还是网络延迟,calico和主机的性能是差不多的。

Docker-Docker容器跨主机通信的更多相关文章

  1. Docker 网络管理及容器跨主机通信

    1.网络模式 docker支持四种网络模式,使用--net选项指定: host,--net=host,如果指定此模式,容器将不会获得一个独立的network namespace,而是和宿主机共用一个. ...

  2. overlay实现容器跨主机通信

    本节内容: Docker容器跨主机通信方案 环境信息 升级内核 安装docker 防火墙设置和开启内核转发 安装启动consul 启动Docker 创建overlay network 创建容器 测试容 ...

  3. Docker容器跨主机通信

    默认情况下Docker容器需要跨主机通信两个主机节点都需要在同一个网段下,这时只要两个Docker容器的宿主机能相互通信并且该容器使用net网络模式,改实现方式为网桥模式通信: 除此之外我们还可以通过 ...

  4. Docker:macvlan实现容器跨主机通信 [十四]

    一.什么是macvlan 1.macvlan 本身是 linux kernel 模块,其功能是允许在同一个物理网卡上配置多个 MAC 地址, 2.即多个 interface,每个 interface ...

  5. Docker容器跨主机通信之:直接路由方式

    一.Docker网络基本原理 直观上看,要实现网络通信,机器需要至少一个网络接口(物理接口或虚拟接口)与外界相通,并可以收发数据包:此外,如果不同子网之间要进行通信,需要额外的路由机制. Docker ...

  6. Docker容器跨主机通信--overlay网络

    一.Docker主机间容器通信的解决方案 Docker网络驱动 Overlay: 基于VXLAN封装实现Docker原生Overlay网络 Macvlan: Docker主机网卡接口逻辑上分为多个子接 ...

  7. Docker容器跨主机通信之:OVS+GRE

    一.概述 由于docker自身还未支持跨主机容器通信,需要借助docker网络开源解决方案 OVS OpenVSwich即开放式虚拟交换机实现,简称OVS,OVS在云计算领域应用广泛,值得我们去学习使 ...

  8. centos7下安装docker(15.5容器跨主机网络--flanneld)

    flannel是由CoreOS研究的一种覆盖网络(overlay network)网络工具,目的是帮助每一个host主机有一个完整的子网: 功能是:让集群中不同节点的主机创建的容器都有一个唯一的虚拟I ...

  9. 【06】循序渐进学 docker:跨主机通信

    写在前面的话 目前解决容器跨主机通信的方案有很多种,这里给出的只是其中的一种,而且还不是最好的方案,不过归根结底,大同小异.在学习 docker swarm 之前,大家可以先看看这种. 啥是 over ...

随机推荐

  1. Spring结合Quartz实现多任务定时调用(转载)

    Quartz框架提供了丰富的任务调度支持,比如,在 何时执行何种任务,它是一个开源的由OpenSymphony维护的项目,开发者能够在Java EE,或单独的Java SE应用中使用它.无论是简单的任 ...

  2. 形形色色的下拉菜单 (css3)

    http://www.iteye.com/news/25339

  3. Android(java)学习笔记264:Android下的属性动画高级用法(Property Animation)

    1. 大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法,当然也是最常用的一些用法,这些用法足以覆盖我们平时大多情况下的动画需求了.但是,正如上篇文章当中所说到的,属性动画对补间动画 ...

  4. npm常用命令解析

    npm是什么 NPM的全称是Node Package Manager,是随同NodeJS一起安装的包管理和分发工具,它很方便让JavaScript开发者下载.安装.上传以及管理已经安装的包. npm ...

  5. Java Hibernate 之连接池详解

    Hibernate支持第三方的连接池,官方推荐的连接池是C3P0,Proxool,以及DBCP.在配置连接池时需要注意的有三点: 一.Apche的DBCP在Hibernate2中受支持,但在Hiber ...

  6. 8051_asm.uew

    /L20"8051 Assembly" AASM_LANG Line Comment = ; Nocase String Chars = ' File Extensions = S ...

  7. html5(三)

    body{ text-align:center;} #mainbox { display:block; width:500px; margin:50px auto; padding:15px; tex ...

  8. (转)Ext.onReady详解

    (转自)http://hi.baidu.com/kakarot_java/blog/item/8c34e57360472c148601b013.html 我们知道,只有在Ext框架全部加载完后才能在客 ...

  9. python3 的 round 函数的 练习

    python3 的 round 函数感觉很别扭,其运算结果与习惯不相符.特记录下来: 代码 ''' python 3的 round 函数 是"四舍六入五成双"的 https://w ...

  10. seek()方法的使用

    seek()方法用于移动文件读取指针到指定位置. file.seek()方法标准格式是:file.seek(offset,whence) offset:开始的偏移量,也就是代表需要移动偏移的字节数 w ...