Docker-Docker容器跨主机通信
时间:2019-09-09
本文章向大家介绍Docker-Docker容器跨主机通信,主要包括Docker-Docker容器跨主机通信使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
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和主机的性能是差不多的。
原文地址:https://www.cnblogs.com/yangyuliufeng/p/11494354.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 动手写简单的嵌入式操作系统一
- LeetCode 92 | 大公司常考的面试题,翻转链表当中指定部分
- 快速学习-Apollo从入门到精通
- dotnet 使用 SourceLink 将 NuGet 链接源代码到 GitHub 等仓库
- 嵌入式linux之go语言开发(八)存储模块的封装(一)
- QGIS制图中面积小的区域不显示注记
- linux 编译 c或cpp 文件为动态库 so 文件(最简单直观的模板)
- 满眼只有React和Vue,却对前端数据层几乎一无所知
- 嵌入式linux之go语言开发(八)存储模块的封装(二)
- 招商银行校招题二
- 小程序工程化系列(一):文件依赖分析
- ucgui在windows上的移植,及为go语言打造简易跨平台GUI的想法
- React setState 是异步执行还是同步执行?
- sm2,sm3,sm4国密算法的纯c语言版本,使用于任何嵌入式平台
- sm2国密算法的纯c语言版本,使用于单片机平台(静态内存分配)