DockOne技术分享(四十三):基于OVS的Docker多主机互联设计和实践

H3CSE · · 1636 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。


【编者的话】多主机的网络直连需求源于ACS的金融云业务场景。 在此场景下,Docker容器运行在阿里云的ECS VM之中, Docker传统的网络解决方案采用NAT的方式实现容器间互联,不同宿主机的容器之间无法感知到真实ip地址,因此无法满足如配置中心这样的架构。而ECS又不支持给VM独立增加IP,从而迫使我们在短期内只能一个VM跑一个Docker的方案,势必会造成资源的浪费。OVS的直连方案隔离了宿主机和Docker容器的网络平面,提供了VM运行多Docker容器的能力,结合上ACS的容器编排能力,能大大提高资源的利用率,降低成本。

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。
001.jpg

Flannel则提供了多种封装协议,UDP,Vxlan,基于亚马逊VPCaws-vpc、gce、Socketplane 采用的是Openvswitch Vxlan。基于Openvswitch Vxlan的封装在性能上有明显的优势。网上有一组性能对比图可以参考下:
002.jpg

从数据来看,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,然后把容器挂载到负载均衡设备,对外提供服务。

根据以上的设计要点,我们的设计如下:
003.jpg

主要设计点的方案是:
  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插件容器
004.jpg

然后创建一个Vxlan网络
005.jpg

查看下网络
006.jpg

创建两个容器
docker run –d –net=vxlan111.0 –ipam-driver=vxlan Ubuntu 
docker run –d –net=vxlan111.0 –ipam-driver=vxlan Ubuntu 

查看IP地址
007.jpg

008.jpg

测试网络联通:
009.jpg

测试外网:
010.jpg

子网内互通:
  • 可以在创建是时候指定多个Subnet/Gateway,以建立多子网的Vxlan 网络
  • 也可以在后续创建新的Vxlan网络,VxlanID 相同的Vxlan网络内,容器互通
    011.jpg


那么这个Vxlan网络和之前的Vxlan网络是互通的。

因此ACS 的Vxlan网络是一个支持自定义网络规划的网络,这在金融云,阿里云经典VM,或者是测试集群资源的规划上将大有裨益。

4 性能

最后提供一组性能数据,这是两个跨主机的容器在物理机的测试结果:带宽113MB/s,物理机是117MB/s,可以看出带宽基本无损耗。
012.jpg

Q&A

Q:我见你是一台主机创建了一个Vxlan,如果有上万台机器,岂不是要创建上万个Vxlan?

A:创建网络是通过Swarm管理的,因此只需创建一次。
Q:这个对网络硬件有要求么?

A:没有具体的要求,倒是相应的内核版本要编译OVS的Kernel模块。
Q:有没有试过Docker自带的Overlay网络,和OVS有什么区别?

A:Docker自带的Overlway网络,通过Serf提供的邻居节点发现功能,如实的广播ARP,而我们OVS网络,ARP都被代理了。另外Overlay需要更高的内核支持,应该是3.19,OVS没有这个限制。另外我们还提供多租户内网络地址复用。
Q:我以前OVS和Docker容器重启后,容器的IP变化了怎么办?

A:在Vxlan网络里面,在容器的生命周期内,IP不变。
Q:为什么不直接使用大二层,就像之前的IaaS,2个主机的容器在Vlan里面可以互通?

A: 关于Vlan,我们也有自己的Vlan网络插件。Vlan和Vxlan场景不同,Vxlan的优势是可以节省IP地址资源。
========================================================
以上内容根据2016年1月19日晚微信群分享内容整理。分享人毛小云(蚂蚁金服),目前就职于蚂蚁金服基础技术部,从事Docker网络插件相关开发、研究和维护工作。DockOne每周都会组织定向的技术分享,欢迎感兴趣的同学加微信:liyingjiesz,进群参与,您有想听的话题可以给我们留言。

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1636 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传