基于OVS的Docker多主机互联设计和实践
来自: http://dockone.io/article/982
【编者的话】大家好,我是蚂蚁金服基础技术部的毛小云。在蚂蚁主站和金融云业务,我们利用Docker的优势来提高资源利用率,降低运维的复杂性,最终降低蚂蚁基础服务的成本。在Docker的网络方案上,基于Docker1.9之后的插件机制,我们研发了多种网络插件,本文主要分享其中一个网络插件,基于OVS的Docker多主机互联设计和实践, 内部我们称之为Vxlan网络。
1. Docker主机网络互联的概述
如果要实现多主机的容器网络通信,Docker,原生的网络模型可以采用Port Mapping的方式,本质上是对两个有互访需求的container用iptables实现了SNAT/DNAT。但这并不能算真正意义的直连互访,因为两个容器内可见的IP地址并非是容器本身的IP地址,而是容器所在宿主机的地址。那么对于一些Java的应用,如配置中心,则无法正常工作。(假设配置中心的服务器和客户端分别在两个容器内,客户端将会采用容器的自身地址去服务器注册,而这个地址对其他人来说是不可见的)
围绕多主机的Docker 容器互访,开源社区衍生出许多项目,有Weave,Flannel, Sockerplane,Opencontrail,Docker的1.9版本之后,Libnetwork也提供了原生的Overlay网络。这些解决方案其实就是在原有宿主机网络平面上再封装一个容器的网络平面,也称为Overlay网络。这里的封装封装,又可以分成两类。这些封装大致分成两类,用户态封装(如Weave)或内核态封装(如Sockplane)
Weave把容器报文嗅探到用户态空间,封装在UDP报文,然后在远端主机解封并注入容器网络。贴一张比较早的Weave实现原理,现在Weave也有基于OVS的Fastpath。
Flannel则提供了多种封装协议,UDP,Vxlan,基于亚马逊VPCaws-vpc,gce,
Socketplane 采用的是Openvswitch Vxlan。基于Openvswitch Vxlan的封装在性能上有明显的优势。网上有一组性能对比图可以参考下:
从数据来看,Weave的用户态封装的方式无论在带宽和延迟上都有很大的损耗,而采用Openvswitch Vxlan的方式,基本无损耗
2 OVS多主机互联的设计和实现要点
本节主要介绍下如何去设计Overlay网络。
1)ARP,首要要解决的是arp的问题
在经典的物理网络中,当一个主机A访问另外一个主机B的时候,A发出的第一包就是ARP Request的广播包,物理交换机会广播这个ARP Request,如果双方同属一个Subnet,那么B会直接回复ARP Reply给A,后续AB就可以进行正常的IP通信。如果AB处于不同的Subnet,网关会回复A的ARP 请求
那么在容器网络该如何处理呢?一般来说ARP的处理有两种模式:
第一种:如实的把报文广播出去,如Weave。Weave建立一套能够在Weave节点之间互相学习的网络拓扑的机制,从而能够实现无论是在网络稳态(即所有节点都能知道了整个网络拓扑),或是部分网络(网络拓扑还在学习过程中)都能正确的广播这些包。基本也是采用Spintree来避免广播环路,而真正实现广播报文的发生。而RFC 提到是利用基础交换机的IP组播功能,毕竟如果通过主机把广播转化为单播是比较效率低下的。
第二种:考虑SDN的方案,SND控制器有全局的网络拓扑信息,或者采用SDN的交换机。SDN控制器的要实现的功能是ARP 代理。
2)第二个要解决的问题是,容器访问其他网络如公网的需求
一般的采用Nat的方式,使得容器具有其宿主机的网络访问能力,如果宿主机能访问外网,那么容器也可以。
3)第三个要考虑的问题是,容器对外提供服务。这里的解决方法是类似Docker 提供Port Mapping,然后把容器挂载到负载均衡设备,对外提供服务。
根据以上的设计要点,我们的设计如下:
主要设计点的方案是:
1) 通过OVS代理ARP
2) Antrouter组件和ZK扮演SDN Controller的角色
3) NAT/Portmapping的方式解决公网和外网服务的功能
另外,根据Docker的插件机制,以及基于易用性的设计,我们还提供了以下优化:
1) OVS和网络插件都以容器的方式运行
2) 增加了Docker 指定IP启动容器的Patch
3) 把IPAM Driver 集成到 Vxlan 网络插件内部,使得Vxlan网络之间的IP地址完全独立
3,实践展示
这里假定我们已经有一个Swarm集群。前面提到插件以容器的方式提供服务,所以先启动OVS和 Vxlan插件容器
然后创建一个Vxlan网络
查看下网络
创建两个容器
docker run –d –net=vxlan111.0 –ipam-driver=vxlan Ubuntu
docker run –d –net=vxlan111.0 –ipam-driver=vxlan Ubuntu
查看ip地址
测试网络联通:
测试外网
子网内互通:
* 可以在创建是时候指定多个Subnet/Gateway,以建立多子网的Vxlan 网络
* 也可以在后续创建新的Vxlan网络,VxlanID 相同的Vxlan网络内,容器互通
那么这个Vxlan网络和之前的Vxlan网络是互通的。
因此ACS 的Vxlan网络是一个支持自定义网络规划的网络,这在金融云,阿里云经典VM,或者是测试集群资源的规划上将大有裨益。
4,性能
最后提供一组性能数据,这是两个跨主机的容器在物理机的测试结果:带宽113MB/s,
物理机是117MB/s,可以看出带宽基本无损耗。
Q&A
Q1:我见你是一台主机创建了一个Vxlan,如果有上万台机器,岂不是要创建上万个Vxlan?
A1:创建网络是通过Swarm管理的,因此只需创建一次
Q2:这个对网络硬件有要求么?
A2:没有具体的要求,倒是相应的内核版本要编译OVS的Kernel模块
Q3:有没有试过Docker自带的Overlay网络,和OVS有什么区别?
A3:Docker自带的Overlway网络,通过Serf提供的邻居节点发现功能,如实的广播ARP,而我们OVS网络,ARP都被代理了。另外Overlay需要更高的内核支持,应该是3.19,OVS没有这个限制。另外我们还提供多租户内网络地址复用。
Q4:我以前OVS和Docker容器重启后,容器的IP变化了怎么办?
A4:在Vxlan网络里面,在容器的生命周期内,IP不变
Q5: 为什么不直接使用大二层,就像之前的IaaS,2个主机的容器在Vlan里面可以互通?
A5: 关于Vvlan,我们也有自己的Vlan网络插件。Vlan和Vxlan场景不同,Vxlan的优势是可以节省IP地址资源。