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. Nginx实现JWT验证-基于OpenResty实现

    介绍 权限认证是接口开发中不可避免的问题,权限认证包括两个方面 接口需要知道调用的用户是谁 接口需要知道该用户是否有权限调用 第1个问题偏向于架构,第2个问题更偏向于业务,因此考虑在架构层解决第1个问 ...

  2. phpbasic

    <!DOCTYPE html> <html> <body> <?php // 这是 PHP 单行注释 /* 这是 PHP 多行 注释 */ ?> < ...

  3. Logback配置文件这么写,还愁不会整理日志?

    摘要: 1.日志输出到文件并根据LEVEL级别将日志分类保存到不同文件 2.通过异步输出日志减少磁盘IO提高性能 3.异步输出日志的原理 1.配置文件logback-spring.xml Spring ...

  4. 没有学历如何从事Java开发?

    学历成了当今社会一个衡量一个人能力的标准,未来只会越来越深入,也有的人说不要总是把学历挂嘴边,学历并不能代表能力,确实学历不能代表能力,但是学历是能代表一个的人学习深度,也是在职场上必备的一个敲门砖. ...

  5. Python os.fdopen() 方法

    概述 os.fdopen() 方法用于通过文件描述符 fd 创建一个文件对象,并返回这个文件对象.高佣联盟 www.cgewang.com Unix, Windows上可用. 语法 fdopen()方 ...

  6. Golang SQL连接池梳理

    目录 一.如何理解数据库连接 二.连接池的工作原理 三.database/sql包结构 四.三个重要的结构体 4.1.DB 4.2.driverConn 4.3.Conn 五.流程梳理 5.1.先获取 ...

  7. 利用WxJava实现PC网站集成微信登录功能

    原文地址:https://mp.weixin.qq.com/s/rT0xL9uAdHdZck_F8nyncg 来源:微信公众号:java碎碎念 1. 微信开放平台操作步骤 微信开放平台地址:https ...

  8. tp3.2 新增邮件类

    1.新建方法   调用发送邮件,我的目录在/admin下 2.新增邮件方法 类的发送配置功能 文件地址: 网站根目录\项目目录\Admin\Common\ 文件 名   :function.php   ...

  9. 图数据库HugeGraph源码解读 (1) —— 入门介绍

    HugeGraph介绍 以下引自官方文档: HugeGraph是一款易用.高效.通用的开源图数据库系统(Graph Database,GitHub项目地址), 实现了Apache TinkerPop3 ...

  10. Flutter 打包程序 build android apk

    Step-1 Java 路径 找到java路径, 可使用[flutter doctor -v] Step-2: 进入目录 找到路径后 C:\Program Files\Java\jre1.8.0_23 ...