随着互联网和数据中心流量的爆炸式增长,SDN 已经逐步取代静态路由交换设备成为构建网络的主流方式,本系列是免费电子书《Software-Defined Networks: A Systems Approach》的中文版,完整介绍了 SDN 的概念、原理、架构和实现方式。原文: Software-Defined Networks: A Systems Approach
第 3 章 基本架构
SDN 是一种利用可编程的商用硬件构建网络的方法,从而通过软件实现智能的包转发控制以及其他网络操作。实现这样的设计不依赖任何特定协议栈,而是需要一组开放 API 以及支持这些 API 的新软件组件。本章将介绍 SDN 软件栈的基本架构。
本章定义了这种软件栈的一般架构,介绍了符合该架构的一个示例集合,不过能够集成到该架构中的特定组件和工具其实有多种选择。我们这样做只是为了使讨论更加具体,我们介绍的组件有两个重要属性。第一,它们是开源的,可以在 GitHub 上免费获得。第二,它们旨在共同努力,提供全面的解决方案,覆盖我们需要的所有场景。这两个属性使得任何人都可以构建出在生产网络中运行的相同的端到端系统。
3.1 软件栈(Software Stack)
图 15 给出了软件栈的概览,包括一个运行本地交换机操作系统(Switch OS) 的裸金属交换机(Bare-Metal Switch),由一组控制应用程序(Control Applications) 控制,这些控制程序托管在全局网络操作系统(Network OS) 上。图 15 右边显示了一组对应的范例开源组件(SD-Fabric, ONOS 和 Stratum),左边显示了相关的 P4 工具链。本章将介绍这些组件,后面章节将给出更多细节。
请注意此图与第 1 章中的图 2 之间的相似性。两幅图都包含两个开放接口: 一个在控制程序和网络操作系统之间,另一个在网络操作系统和底层可编程交换机之间。在图 15 中,这两个接口被描述为“API shims”,在示例组件的上下文中,第一种接口对应于 gNMI、gNOI 和 FlowObjective 的组合,第二种接口对应于 gNMI、gNOI 和 P4Runtime 或 OpenFlow 的组合。gRPC 是这些 API 的传输协议,这是一种常规的实现选择。(注意,与其他协议不同,OpenFlow 不会在 gRPC 上运行。)
图 15. SDN 软件栈总体架构。
重要的是要记住,图 15 中列出的软件组件都对应于活跃开源项目,因此会继续发展(就像它们的 API 一样)。每个组件的特定版本(及其相关 API)已经集成并部署到试验和生产环境中。例如,虽然图中显示 P4Runtime 是 Switch OS 导出的候选控制接口,但也有一些部署的解决方案使用 OpenFlow。(包括 Comcast 的部署。)类似的,虽然图中显示 gNMI/gNOI 作为交换机的配置/操作接口,但也有使用 NETCONF 的解决方案。
本书的目的不是要试图跟踪所有可能的组合的组件版本和 API,而是在图 15 中选择专注于单一一致的堆栈,因为这代表了迄今为止我们基于早期软件栈所能做出的关于"正确"方法的最佳判断。
3.1.1 交换机实现 vs 主机实现(Switch vs Host Implementation)
图 15 显示了从单一交换机视角出发的软件栈视图,但是从网络视角分析也很重要。图 16 通过关注连接虚拟机(VM)的网络端到端路径给出了这样一个视角。
图 16. 软件定义网络的端到端视角,包括终端主机和托管虚拟机。
这一视图突出了系统的两个重要方面。首先强调了网络操作系统(如 ONOS)是网络范围内的,而交换机操作系统(如 Stratum)在每个交换机内。
其次,SDN 软件栈的一部分运行在终端主机上。尤其是需要在服务器管理程序中运行虚拟交换机(vSwitch, Virtual Switch) 软件,负责将数据包转发到 VM 以及转发从 VM 返回的包。(当然,并不是每个终端主机都运行 VM,但类似架构同样适用于容器主机或裸金属服务器。)就像物理交换机一样,vSwitch 将数据包从输入端口转发到输出端口,但这些是连接到 VM(或容器)的虚拟端口,而不是连接到物理机器的物理端口。
幸运的是,可以把 vSwitch 看作物理交换机,包括其支持的 API。注意一个实现细节,即 vSwitch 是在通用处理器上而不是在专用集成电路(ASIC)上通过软件实现的。因此作为软件交换机,大大降低了引入额外功能的障碍,从而能够提供丰富、动态的功能集。例如,OVS(Open vSwitch) 是一款应用广泛的开源 vSwitch,支持 OpenFlow 作为北向 API,构成了原有 Nicira 网络虚拟化平台的数据平面。OVS 可以与一系列补充工具集成,比如另一个开源组件 DPDK(数据平面开发工具包, Data Plane Development Kit),从而优化 x86 处理器上的数据包转发操作。虽然这是一个重要的主题,但本书不会探讨 vSwitch(如 OVS 或其他终端主机优化)的所有可能性,而是像对待端到端路径上的任何其他交换机一样对待 vSwitch。
图 16 显示的另一个实现细节是,主机可能用智能网卡(SmartNIC, Smart Network Interface Card) 来辅助(甚至取代)vSwitch。厂商将内核功能卸载到网卡上已经有很长的历史了(例如,从计算 TCP/IP checksum 到支持 VM),但在 SDN 环境中,一种可能的有趣应用是复制网络交换机上的转发流水线。这同样有一系列可能的实现选择,包括 FPGA 和 ASIC,以及网卡是固定功能还是可编程(使用 P4)。就我们的目的而言,将把这种智能网卡当作端到端路径上的另一个交换组件。
主机中心视角
本书采用面向网络的 SDN 视角,将终端主机(运行在主机操作系统中的虚拟交换机和连接主机到网络的网卡)视为网络的扩展,在网络操作系统的控制下运行。不过以主机为中心的观点同样有效,更重要的是,其附带了一个健壮的开源软件生态系统,作为主机操作系统的一部分运行。
DPDK 是其中一个例子,但另一个受到关注的是 eBPF(扩展伯克利包过滤器, extended Berkeley Packet Filter)和 XDP(快速数据路径, eXpress Data Path)的组合,它们提供了一种方法来在 OS 内核(甚至可能在 SmartNIC 上)中编程通用的 Match-Action 规则。这在精神上与 OpenFlow 和 P4 相似,只是它们允许 Action 部分是任意程序。相比之下,OpenFlow 定义了一组固定的动作,而 P4 是表达动作的特定语言(例如,不包括循环)。当 Action 必须在固定周期内执行时,这是必要的,例如基于交换机的转发流水线。它还使数据平面的形式化验证(formal verification)成为可能,这是第 10 章讨论的一个很有前途的机会。
3.2 裸金属交换机(Bare-Metal Switch)
我们从图 15 和图 16 所示软件栈从下往上介绍,底层的网络数据平面是由一组互连的裸金属交换机实现。我们现在重点关注单个交换机,整个网络拓扑是由运行在软件栈顶层的控制程序决定,后面我们会介绍一个管理叶脊拓扑的控制应用程序。
该架构与交换机供应商无关,本章介绍的完整软件栈运行在基于 Tofino 和 Tomahawk 交换芯片构建的交换机上,分别由 Barefoot Networks(现在是英特尔)和博通制造。Tofino 芯片实现了基于 PISA 的可编程转发流水线,而 Tomahawk 芯片实现了固定功能流水线。
两种芯片都通过两个 P4 程序定义转发流水线,第一个(forward.p4
)指定转发行为,第二个(arch.p4
)指定目标转发芯片的逻辑架构。P4 编译器生成加载到网络操作系统和交换机中的目标文件,图 15 中我们没有指出这些目标文件(后面将在第 4 章和第 5 章中介绍详细信息),但是两个组件都需要感知输出逻辑,因为一个实现转发行为(交换机),而另一个控制转发行为(网络操作系统)。
我们将在第 4 章介绍编译器工具链的细节。现在,我们将只回答为什么在有固定功能交换芯片的情况下,还需要一个 P4 程序(我们没有使用 P4 来修改其固定行为)。简单总结一下,因为我们需要正式的转发流水线规范来生成数据平面 API。P4 程序提供了转发流水线的抽象模型,无论芯片的实际硬件流水线是固定的还是可编程的,我们仍然需要知道如何将抽象流水线映射到物理流水线上,这就是arch.p4
起作用的地方。对于可编程芯片,forward.p4
实际上定义了流水线,而对于固定功能芯片,仅仅只是通过forward.p4
描述流水线。我们仍然需要forward.p4
,因为在两种情况下工具链都需要使用它以及arch.p4
生成位于控制平面和数据平面之间的 API。
3.3 交换机操作系统(Switch OS)
从基本硬件往上看,每个交换机运行一个本地交换机操作系统。不要与管理交换机网络的网络操作系统混淆,这个交换机操作系统运行在交换机内部的商品处理器上(图 15 中没有显示)。它负责处理发送给交换机的 API 调用,例如来自网络操作系统的调用,以及对交换机内部资源采取适当的操作,有时会影响交换机芯片。
有多种开源交换机操作系统(包括最初由 Microsoft Azure 开发的 SONiC),但我们使用 Stratum 和 Open Network Linux(ONL) 的组合作为主要示例。ONL 是 Linux 的交换机发行版(最初由 Big Switch Networks 提供),而 Stratum(最初由谷歌开发)主要负责外部 API 和内部交换机资源之间的转换。因此,我们有时把 Stratum 称为瘦交换机操作系统(Thin Switch OS) 。
Stratum 在交换机与外部世界的所有交互中起到中介作用,包括加载 P4 编译器生成的目标文件,该文件定义了数据平面和控制平面之间的契约。契约有效的用自动生成的规范替换了 OpenFlow 的流规则抽象。其他 Stratum 管理 API 定义如下:
- P4Runtime: 控制转发行为的运行时接口,是填充转发表和操作转发表状态的关键。P4Runtime 独立于任何特定 P4 程序,并且与底层硬件无关。这与 OpenFlow 形成了鲜明对比,OpenFlow 对转发模型以及如何与控制平面交互有着相当明确的规定。(为了完整起见,图 15 还列出了 OpenFlow 作为另一个控制接口。)
- gNMI(gRPC Network Management Interface): 用于设置和检索配置状态。gNMI 通常与 OpenConfig YANG 模型配对,后者定义配置和状态树的结构。
- gNOI(gRPC Network OperationsInterfaces): 用于设置和检索运行状态,如证书管理、设备测试、软件升级、组网故障处理等。
如果你还记得在第一章中介绍的控制和配置之间的区别,那么你会认出 P4Runtime 就是控制 API,而 gNMI/gNOI 组合在一起就是交换机传统配置 API 的现代版本。后一种 API 在历史上被称为 OAM 接口(即"Operations, Administration, and Maintenance"),通常被实现为命令行接口(当然,这不是真正的 API)。
3.4 网络操作系统(Network OS)
网络操作系统是配置和控制交换机网络的平台,作为逻辑上集中的 SDN 控制器在交换机之外运行,并在全网范围内管理一组交换机。这个角色的核心是负责监控交换机状态(例如,检测端口和链路故障),维护反映网络当前状态和拓扑的全局视图,并为任何感兴趣的控制程序提供该视图。这些控制程序反过来"指示"网络操作系统根据它们提供的服务来控制底层交换机的数据包流,这些"控制指令"的表达方式是网络操作系统 API 的关键方面。
我们基于 ONOS(开放网络操作系统, Open Network Operating System) 这一特定网络操作系统作为范例来完整描述这一概念,ONOS 在性能、可伸缩性和可用性方面是最好的。简单来说,ONOS 负责三件事情:
- 管理拓扑(Managing Topology): 跟踪网络基础设施及其互联设备,为平台和其他应用程序提供网络环境的共享视图。
- 管理配置(Managing Configuration): 帮助在多个网络设备上执行、跟踪、回滚和验证原子配置操作。这可以有效反映每个交换机的配置和操作接口(也使用 gNMI 和 gNOI),但是在网络级别而不是设备级别上实现的。
- 控制交换(Controlling Switches): 控制网络交换机的数据平面数据包处理流水线,并对流水线内的流规则、组、监控等构建块进行后续控制。
关于最后一个角色,ONOS 导出了一个北向 FlowObjectives 抽象,以一种独立于流水线的方式泛化流规则接口(在第 6 章中有更详细的描述),但不像独立交换机导出的控制接口那样标准化[1]。与传统服务器操作系统一样,基于 ONOS API 上的应用程序不容易移植到另一个网络操作系统上。对这个接口的需求是开放的以及定义良好的,当前并不是只有一个这样的接口。如果随着时间的推移,如果业界对网络操作系统接口达成了共识,那么应用程序将更容易被移植。但就像服务器操作系统一样,在软件栈中层级越高的操作系统,就越难以达成这样的共识。
[1] 我们没有说 FlowObjectives 是控制交换机的理想接口。API 会出于实际需要而发展,允许开发人员处理不同的流水线。定义通用接口是正在进行的研究的主题。
最后,尽管图 15 没有显示关于 ONOS 内部的任何细节,但为了更好的理解其在更高层面上所扮演的角色,我们注意到在任何网络操作系统中最关键的子系统是可伸缩键/值存储(Scalable Key/Value Store)。由于 ONOS 提供了一个逻辑上集中的网络视图,其性能、可伸缩性和可用性的关键在于如何存储这些状态。在 ONOS 中,这个存储是由一个名为 Atomix 的开源项目提供的,该项目实现了 RAFT 共识算法。像 Atomix 这样的存储服务是当今几乎所有水平可伸缩云服务的基石,我们将在第 6 章中详细介绍。
3.5 叶棘网络(Leaf-Spine Fabric)
由于我们使用 ONOS 作为网络操作系统,所以仅限于使用 ONOS 托管的 SDN 控制应用程序。为了说明问题,我们使用 SD-Fabric 作为控制应用程序,它在可编程交换机网络上实现了叶棘网络。意思是,SD-Fabric 定义了特定的网络拓扑结构,特别是数据中心集群常见的叶脊拓扑结构。如 2.3 节所述,该拓扑包括一组叶交换机,每一个都作为 ToR 交换机(即连接单个机架中的所有服务器),然后叶交换机再由一组脊交换机互连。
从架构上来说,SD-Fabric 扮演了三个角色。首先,提供了一个交换结构,在多机架集群中将服务器和运行在这些服务器上的虚拟机相互连接。其次,使用 BGP 将集群作为整体连接到对等网络,包括 Internet(也就是说,其行为很像路由器)。最后,将集群作为整体连接到下游接入网(即 PON、RAN 等接入网)。换句话说,与其将 SD-Fabric 看作传统的在数据中心内部构建的叶脊网络,不如将其看作是运行在网络边缘的互连系统,帮助连接访问特定边缘云和基于 IP 的数据中心云。
在实现方面,SD-Fabric 实际上对应一套运行在 ONOS 上的控制程序,而不是单一应用程序。该套件支持多种控制平面特性,包括:
- VLAN 和 L2 桥接
- IPv4 和 IPv6 单播/组播路由
- DHCP L3 中继
- 服务器和上行路由器的双归属冗余
- QinQ 转发/终止
- 基于 MPLS 的伪连接
对于每个特性,都有相应的控制程序与 ONOS 交互,通过观察网络拓扑的变化并发出 Flow Objective 而实现,而不是基于任何传统路由器/交换机的标准协议实现。只有当 SD-Fabric 需要与外部通信(例如,上游城市/核心路由器)时,才会涉及到传统协议,这时需要使用标准 BGP(由开源 Quagga 服务器实现)。这实际上是 SDN 环境的共同特征: 内部或在新领域避免传统路由协议,但与外部世界的交互仍然需要。
图 17. SD-Fabric 控制程序套件,管理(可能是分布式的)叶脊网络。
最后,SD-Fabric 有时部署在一个站点,多个 RAN 基站通过 SD-Fabric 叶交换机连接。但是,SD-Fabric 还可以使用多层棘网络扩展到多个站点,如图 17 所示。第 7 章会更详细介绍这部分内容。