以下内容根据演讲PPT以及现场分享整理而成。
主要内容提纲
一、docker网络分析
二、docker网络插件开发
三、蚂蚁金服的网络插件实践
一、docker网络分析
主要介绍三种docker网络,Bridge网络、docker原生的Overlay网络以及Weave网络,在这里主要分享一下这些网络的架构或者说是结构。
docker Bridge网络
Bridge网络可能是大家最熟悉的网络,如下图所示,HostA和HostB是两个宿主机,docker运行起来就将在宿主机上创建docker0的网桥作为容器的开关。
在网桥建立完成之后,同一个宿主机上的不同容器之间就可以通过网桥的转发功能进行通信,但是位于不同宿主机器上的容器无法直接进行通信,他们可以通过iptables SNAT/DNAT和容器外网络进行通信。Bridge网络结构比较简单,但是缺点是不同宿主机之间的容器其实并不在一个共同的网络中,不同宿主机之间的容器无法进行直接的通信。
docker Overlay网络
对于应用而言,如果要部署在docker中,基本上都需要面对跨主机互联的问题,docker提供了原生的Overlay网络,对docker具有良好的支持性。
这里简单提一下VXLAN协议,下图中的Inner Enthernet Frame是由容器发出的报文,在经过报文一层层封装以后,最后以UDP的方式发送出去。
在Overlay网络中,每个容器会有两张网卡,其中一张网卡用于与外部网络进行通信,向外部网络传输的数据会经由eth1网卡,并通过docker_gwbridge发送出去。如果是不同宿主机之间的容器想要通信的话,数据将会通过eth0发送出去。每个overlay网络有独立namespace和br0网桥,在节点组件集群进行通讯时,采用的使用gossip协议来管理节点成员关系、并且通过广播L3Miss处理二层ARP的交互。而不同网桥上的VXLAN设备的作用就是帮助不同宿主机的容器通过VXLAN隧道直接通信。
docker Weave网络
Weave网络的易用性比较高,所以更容易上手,而且目前而言,Weave网络的产品系也是比较完善的。Weave网络有两种实现方式,一种是用户动态的封装实现,另外一种是内核态的封装实现,这里主要介绍内核态的封装实现。
在下图中Weave Router中有这样的一个插件,这个插件主要实现了两个功能,一个是帮助与其他的宿主机建立gossip协议的链接,从而建立集群的拓扑关系。另外一点就是帮助跨宿主机的容器通过datapath和VXLAN隧道进行通信。
小结
这三种网路有一些共同点,首先需求是共同的,都要满足容器的跨主机通信的需求,同时ARP的广播会增加网络负担,阿里云自己的产品上这一点就被解决了,这三种网络使用的Gossip协议的运维复杂度,而且无法适应多种docker网络环境,难以满足高性能的网络业务。
二、docker网络插件架构和开发
在介绍阿里云的插件构建之前,先给简单大家介绍docker网络插件架构和开发通用的CNM模型。如下图所示,这里有三个docker容器,这里主要有三个概念Sandbox、Endpoint和Network。Sandbox可以理解为docker内部运行的namespace,也就是隔离的网络配置环境;Endpoint其实是虚拟的网卡,它隶属于某一个network的通讯端口,多个Endpoint也可以在一个Sandbox中共存;而NetWork就是所有接在节点里面的Endpoint,也就是一个唯一的、可识别的endpoint组。在同一个Network中的endpoint可以相互通讯,而且你可以创建一个Frontend和Backendnetwork,然后这两个network是完全隔离的。
在理解这三个概念之后,我们看一下这些概念是如何在流程中串联起来的。docker在启动起来时会起到Controller这样的角色,当创建Network的时候,就会调用newController函数,之后再调用newSandbox创建namespace,之后还会调用newEndpoint,使得插件自己处理如何去创建Endpoint,最后将调用join的方法,建立Sandbox和Endpoint的关系,这时候就相当于容器中有了网卡。
目前docker已经提供了开发“利器”,也就是docker官方提供的开发框架。大家在开发时只需要导入几个包,当容器运行起来,整个插件的服务也就开始运行了,后面需要实现的就是几个接口了。也就是相当于大家不用从零开始造轮子了。
docker和plugin是如何通信有三种方式:.sock/.spec/.json。一般大家使用的都是sock的方式。目前蚂蚁金服使用的都是容器的方式,这样的方式既可以很方便地对它进行升级,也可以很方便地进行管理。
三、蚂蚁金服网络插件
VLAN Driver
VLAN Driver其实是最接近于现有物理网络的驱动插件。在这样的方案中,宿主机的管控流量和容器的流量被隔离在两个不同的VLAN中,采用了Ovs bridge,并且将容器接入到这个Ovs bridge中。为了避免ARP广播风暴并且缓解交换机PPS的巨大压力,采用了ARP带回的策略和大二层的策略,也避免了容器MAC地址表象对于交换机的影响。目前在大部分的企业都选择了VLAN的方式,因为它最适配现有物理网络,对业务影响最小。
SRIOV Driver
SRIOV Driver本质上也是VLAN网络,但是目前没有采用Ovs。因为有一些像DB这样的业务对于网络的延迟有更高的要求,才产生了SRIOV Driver。具体的做法就是将VF虚化出来,直接塞到容器里面去,沿用现实场景中的Bonding模式,使用双活的Bonding模式使得PF和VF两边都可以结合起来。
VPC Driver
业务上云会有两种选择,一个是经典的云环境,另外就是VPC的环境。如果大家使用的是VPC环境,就可以采用我们的这种VPC Driver。其主要实现方式就是阿里云提供了自定义路由的方式,可以自定义VRouter上的路由,也就是自定义数据到达VRouter之后下一跳的路径,如果是利用专线就可以实现和用户中心的Docker互联。VPC Driver非常适用于在阿里云的VPC上使用docker。
VXLAN Driver
VXLAN Driver适用于在阿里云经典云环境上面进行构建应用的场景。这个方案是比较完善的,它将SLB,以及对内和对外的因素都考虑进去了。VXLAN Driver具有独立的IPAM,支持Subnet,进行了MACNAT和ARP带回,所以在容器里面看到的所有容器的MAC地址都是一样的。比较适用于在阿里云经典VM中运行多docker。
Smart Nic Driver
之前提到的方式都是在Linux内核中完成的,所以消耗的是Linux主机的能力,在千兆网络环境下大家可能觉得不是问题,但是在万兆网络中,就会感觉到无法发挥出万兆网络真正的能力。由于没有SRIOV网络隔离,容器之间网络的影响还是比较大的,另外在各种业务整合的时候,需要做流量管控的时候又将是性能消耗点。
高性能网络其实要做的就是类似一张智能网卡,用网卡对于协议报文进行加解封装,然后将协议报文直接送到容器里面,宿主机性能没有任何消耗,而且这样对于智能网卡功能的扩展也非常容易,也不会影响宿主机。实现了无论网卡如何,保证容器底层的网络最优。