从总线式以太网到SDN交换机OpenVSwitch

本文结合自己的经历梳理一下SDN交换机的脉络。

史前

注定爆发的,必有缘由。

以太网已经发展了30~40多年,我们必须从头说起。

经理应该除外,经理不必关注这些。

总线式以太网

最开始的以太网是总线以太网,所有的站点主机均连接在一条总线上,通过网桥可以连接两根总线:
在这里插入图片描述
此时以太网的所有操作均在站点主机侧完成。总线式以太网唯一的智能操作就是传输仲裁,这个是通过CSMA/CD在主机网卡来完成。

总线以太网的特征在于: 中间没有盒子! 此时专门的网络厂商非常少,因为它们发挥的作用非常有限,对于广域传输,嫁接在传统的通信网即可,网络厂商几乎生产不了任何除了网桥之外有用的设备!

关于以太网的理论细节,参见:
http://www.javashuo.com/article/p-ciijmlij-ka.html
http://www.javashuo.com/article/p-dtslwblz-bm.html
http://www.javashuo.com/article/p-zsudjuiz-dg.html

交换式以太网

随着站点主机的增加,传输仲裁方式必须改变,CSMA/CD的分布式仲裁变得不再适用,取而代之的是集中式仲裁,交换式以太网取代总线以太网。

以太网交换机出现了。

随着TCP/IP成为事实上的标准,IP路由器也开始遍地开花,网络上从此布满了越来越多的盒子。

在某种现实意义上,这意味着 “计算机”“网络” 开始分道扬镳了。

计算机领域在几乎同期被Intel的x86架构迅速统一了底层硬件平台,逐渐走上了纯软件化的可编程路线。程序员属于这个阵营。

网络领域则正好相反,各个专门生产网络盒子的厂商寒武纪大爆发,走向了专门的定制硬件和定制协议路线,程序员探究网络设备内幕的路子也被设备厂商封死。网络工程师属于这个阵营。

从此,程序员和网工交集甚少。

各个厂商的路由器,交换机各有各的风格,操作接口不一致,甚至出现了很多私有协议,如此一来,互操作便不再可能,这些盒子相当于一个个的黑盒子。用户必须选择或者拒绝某个厂商的整个解决方案,而不是某一款产品。

这个阶段催生了一类巨无霸公司以及一类专业的职业:

  • 公司:Cisco,Juniper,H3C,华wei(不让提这名字就不提)等。为了占领解决方案市场,斗争激烈。
  • 职业:CCIE,CCNP,HCSE等认证工程师。每一类设备就需要一类专门的操作员。

这几乎和计算机软件领域隔行如隔山,软件企业的程序员不需要知道什么是BGP,而网络设备厂商的工程师也不必学习Java。

对于我自己而言,我是被迫夹在二者中间。


以交换机为例,虽然很多厂商都生产交换机,但这些交换机在逻辑上其实都是很简单的。这些交换机无非也就是实现以下的功能:

  • 按照ingress port/source MAC学习生产Port/MAC映射表。
  • 按照Port/MAC映射表进行自转发。
  • 实现STP协议。
  • 可选实现其它802.3族标准。
  • 可选实现ACL,防火墙等。

说白了,所谓的交换机就是一台转发数据包的机器,最简单的交换机当然就是以太网交换机,它的转发策略就是 “根据Port/MAC映射表就行转发” , 事实上,后面我们可以看到,所谓的三层交换机,路由器,SDN交换机它们和以太网交换机都没有本质的区别,都是数据包转发设备,它们的区别仅仅在于 “流表” 不同,对于以太网交换机而言,它的流表就是Port/MAC映射表。

如果厂商们提供的交换机一致,便无法区分它们,于是厂商的方略便是:

  • 采用更好更贵的硬件提高性能。
  • 采用私有协议制造门槛。

好吧,Cisco最爱干这事。

软网桥:Linux bridge

Linux的出现让事情开始发生变化。

Linux正是Linus为了在自有的x86机器上运行一个系统而被迫开发的,所以我们对比现在的结论,事实上SDN最终也几乎x86化,在1990年就埋下了种子。

当然,除了Intel网卡,不能忽略Netronome,Mellanox。Intel网卡的优势就是可以集成自家的芯片,又可以到主机CPU用DPDK来offload。

我对Linux bridge是再熟悉不过了,2010年我面试一家公司的时候就被问到了Linux bridge,当时回答的还算可以,然而在当时也只是纸上谈兵。

机缘巧合,我在2012年开始接手一个摊子铺的很大的网关产品。既然也是一个部署在网络上的盒子,这意味着我们要做和网络设备厂商一样的事,但是由于我们只做软件,所以我们不能像那些巨无霸设备厂商一样做板卡和系统的定制开发。

我们能做的只是修改Linux内核协议栈,并且 “用软件实现一个满足需求的交换机。”

Linux bridge只能实现以太网交换机的标准功能:

  • 自学习。
  • 自转发。
  • STP协议。

它没有能力实现防火墙和NAT,而我们的产品需求中偏偏有这个。

事后来看,简单配置一个OVS就能满足需求,我们按照tuple匹配数据包并添加到流表,并设置DROP action即可。只是在2012年产品预研阶段,我们没有OVS。

Linux bridge提供的 nf_call_iptables 这么一个有用的机制:

  • 被bridge处理的数据包可以穿过IP层的Netfilter HOOK链。

在这里插入图片描述

这已经是一个事实上的SDN模型了,虽然并不是标准的。

我们知道iptables可以配出几乎所有的ACL/防火墙/mangle需求,如果实在不行,那就求助于xtables-addons,如果还不行,那就照猫画虎自己写一个match/target,而我自己在那些年也写了很多。

如此一来,Linux bridge配合Netfilter几乎可以满足需求了。唯一的问题在于iptanles规则集超过8000条后的单机性能问题。

连续几个月,我大部分的时间和精力都投入到了Netfilter的性能优化,关于nf_conntrack的优化自然不必再说,这里列出几个关于iptables规则预处理的优化(这些文章是后面补的,在产品研发上线阶段,哪有时间写这些):
ipset高大上性能果断将nf-HiPac逼下课
https://blog.csdn.net/dog250/article/details/41171643/
可编译易用的模块化nf-HiPAC移植成功
http://www.javashuo.com/article/p-thjqnfuz-hz.html
玩转高性能超猛防火墙nf-HiPAC
https://blog.csdn.net/dog250/article/details/41289217
iptables高性能前端优化-无压力配置1w+条规则
https://blog.csdn.net/dog250/article/details/77618319
探索iptables BPF模块的悲惨历程
https://blog.csdn.net/dog250/article/details/9103817
使用iptables的bpf match来优化规则集-HiPAC/ipset/n+1模型之外的方法
https://blog.csdn.net/dog250/article/details/77790504


Linux bridge的意义在于:

  • 它在通用Linux上软实现了一个交换机并且可以跑在通用x86平台上,验证了可编程交换机的可行性,相当于一个POC。

然而,通过Linux bridge实现软件交换机的并不多,即使后来也没有。因为,SDN来了,OVS来了。

无论如何,Linux bridge,包括Linux的IP forward都为程序员探究网络打开了一个口子,而且这个口子越开越大。

SDN软交换机:OpenVSwitch

小溪可以汇成洪流,当有越来越多的需求传统网络设备厂商满足不了的时候, 可编程 的优势就凸显出来了!

随着云业务需求的爆发,虚拟化技术飞速发展。

系统管理越来越不能忍受数据中心机房里堆满的那些又占地方又傻瓜的交换机设备,同样不能容忍的是配置一条交换机命令必须由行动缓慢的厂商认证的网络管理员来操作。

云计算业务不再需要系统管理员和网络管理员的职责边界,这是导火索,直接导致了SDN时代的到来!

如果说业务无关的核心传输网络需要专业的网络管理员来管理还可以理解,那么数据中心这种业务重地,势必就要网工网管免进了。

插句玩笑话,如果交换机是可编程的,那便可以彻底踢开不懂编程只会敲特定厂商设备命令行的网工网管了吧。

SDN概念的发生,发展本文不谈,那是学术圈的事,我们关注的是,它的标准已经在事实上确定了,这些标准包括但不限于SDN各组件间的编程接口和通信协议,虽然学术界和业界对此均尚未达成一致,但我们能看到的是, 各种“可以互操作”的自研交换机 已经在各大云厂商的数据机房遍地开花了。

有了编程标准和协议标准,实现一个交换机便不是什么难事,其实我上面的Linux bridge/Netfilter交换机按照这些标准进行重构,也是一个自研实现。

软实现

OpenVSwitch是一款很好用的SDN软件交换机,详见:
https://www.openvswitch.org/

前面提到过,SDN交换机本质上和以太网交换机是一致的,都是数据包转发设备,不同的是SDN交换机的转发策略更加灵活,而以太网交换机只有Port/MAC映射转发一种策略。

策略的灵活性表现在SDN交换机拥有 “可编程的复杂流表” ,由于其灵活的可编程特征,必然以性能为代价,所以它必须作为一个独立的控制面存在,而数据面则作为流表项的cache用来做快速转发。

因此,OpenVSwitch的数据面在内核态实现转发,这个类似于Linux bridge,而用户态的
ovs-vswitchd守护进程则作为控制面存在。和标准的offload机制一样,OVS也会执行下面的逻辑:
在这里插入图片描述

更加直观的一幅来自OVS设计Paper的经典图示:
在这里插入图片描述
关于流表和cache的事情,参考一篇Paper就够了:
http://www.openvswitch.org//support/papers/nsdi2015.pdf
我会再写一篇文章,谈谈我自己对流表cache的理解,可能稍微和OVS作者们有所不同。

Linux switchdev模型

如果仅仅是软件实现一个OVS并打成包,那实在就是开发者的自娱自乐了,真正可部署的交换机还是需要硬件实现,换句话说,软件OVS仅仅是一个高版本的另一个POC,应付高性能场景,专有硬件offload必不可少。

专有转发硬件与Linux的接口依然不够友好,厂商可以让自己的硬件支持Linux,然而必须配以厂商专用的软件工具,换句话说,Linux没有针对硬件的通用驱动接口来实现对交换机的配置。

Linux的switchdev模型完成了这一使命:
https://lwn.net/Articles/675826/

我们来看一个关于switchdev的框图,来自Linux内核Document的 Documentation/networking/switchdev.txt :
在这里插入图片描述

HW Offload自研交换机

统一的配置接口OpenFlow/OVS有了,统一的驱动接口switchdev有了,剩下的就是设计硬件并编写代码实现这些接口了,硬件可以交给硬件团队来做,以下三类实现形式可供选择:

  1. ASIC实现。
  2. FPGA实现。
  3. NFP实现。

编写代码这种事那便是程序员的专场了,于是你看,阿里,腾讯,百度,均有自己的自研交换机团队,你看,程序员都来靠编程做网络设备了,你看,这就是软件定义网络了。


有趣的是,传统的巨无霸厂商也在逐渐往通用处理上靠了,比如数据面也有ARM/NFP实现的了。

历史一次又一次证明,使用专用硬件是得不偿失的,它只能在最开始稍微制造点性能门槛,而性能问题,时间总是可以解决的。

回到最初

我们可以预见,机房里的景色回到了总线式以太网的最初:
在这里插入图片描述
没有盒子 的样子。


浙江温州皮鞋湿,下雨进水不会胖。