OpenVirteX架构研究(二)

来源:互联网 发布:淘宝什么时候能买彩票 编辑:程序博客网 时间:2024/06/06 03:08

OpenVirteX组件简介

2.1 概述

OVX网络表示法,物理网络和虚拟网,均是交换机、端口、链路、主机和地址对象的集合。对于一个租户,这些组件看起来与实际的数据路径、端口、链路和主机并无差别。前一章描述的全局映射(global map)构建了在物理对象和虚拟组件对象之间的n–>1映射,以实现租户拓扑映射到物理网络中。

为了减少关于OVX对象和物理网络的困惑,我们首先给出了这篇教程的一些习惯用语以及涉及的术语。

  • Infrastructure表示运营商或提供商的实际网络,可以理解为物理网络;
  • datapath经常和物理网络并存,可以与switch互换使用;
  • Network一词单独出现表示物理网络, physical networkvirtual network 分别表示OVX的表示法。
  • 对于Switch和Link等首字母大写的,表示OVX构造。
  • Tenant controller,controller,network OS以及NOS可以互换使用。

2.1.1 实现类

目前,OVX的版本是由Java开发的,组件被定义在包[net.onrc.openvirtex.elements.*]内的类中,并且每个组件定义为一个基类,所有基类如下表所示

表2-1 组件基类

Base Class Representation Definition Network The full network topology public abstract class Network<T1 extends Switch, T2 extends Port, T3 extends Link> Switch A switch public abstract class Switch<T extends Port> Port A port on a switch public class Port<T1 extends Switch, T2 extends Link> Link A connection between two ports public abstract class Link<T1 extends Port, T2 extends Switch> Host A network host public class Host IPAddress An IP Address public abstract class IPAddress

这些类均继承自每个组件的物理或虚拟版本。当前的组件类以及其父类展示如下。

表2-2 虚拟组件

Base Class Physical Component Class Virtual Component Class(es) Network PhysicalNetwork OVXNetwork Switch PhysicalSwitch OVXSwitch (child classes OVXSingleSwitch, OVXBigSwitch) Port PhysicalPort OVXPort Link PhysicalLink OVXLink, SwitchRoute Host – Host IPAddress PhysicalIPAddress OVXIPAddress

例如,PhysicalPort表示在物理网中的一个交换机的物理端口,OVXSwitch表示由OVX为租户分配的一个虚拟交换机。因此,我们亦可以通过如下约定理解上述组件:大部分表示物理网络的组件的名字都以“Physical”开头;而所有租户网络,也就是虚拟网络,则以“OVX”开头。注意:主机(Host)只有虚拟表示方式。

OVX通过组装一个PhysicalNetwork实例建立起了物理网络的相关内容。PhysicalNetwork实例由物理网络中的switch、link、port对象的实例组装而成。它们由各种网络发现技术或者方法被探测或发现。虚拟网络表达,或者OVXNetwork 实例,由运营商通过API调用创建。这些API负责创建网络对象,并将它们映射到OVX提供的PhysicalNetwork组件中。

关于网络发现(Network discovery)和JSONRPC API,我们会在下一篇讨论。

2.2 组件状态机

网络元素(network element)包含各种状态,这些状态与其它元素的状态相互影响。例如,如果物理网络中的一个交换机关闭,它的所有端口和任何与之相关的链路都会下线或断开,并改变OVX感知到的物理网络拓扑。

为了使OVX跟踪和描述各种组件的状态以及彼此如何交互,组件类实现了有限状态机(finite state machines, FSMs)。状态转移由其它组件驱动。本篇主要给出了这些FSM的简介。

2.2.1 基本FSM状态

除了Address 类和OVXSwitch 子类,目前,每个组件类有4个状态:

  • INIT:刚创建时的状态,也就是,其类的构造函数刚调用;
  • INACTIVE:等待网络事件,例如,OpenFlow消息和网络发现事件;
  • ACTIVE:正常运行状态,所有事件均以期望的方式处理;
  • STOPPED:销毁。如果使用该对象,则必须重新创建。

例如,管理员关闭的端口处于INACTIVE,并且一个被运营商从物理网络中删除的OVXSwitch的状态时STOPPED。

目前,FSM由Java 枚举实现。该方法易于修改,如果需要加入一个新的状态,我们只需简单地添加状态及其相关的行为到FSM即可。每个组件类的FSM被命名为State,也就是,PhysicalSwitch和OVXSwitch的FSM状态为SwitchState。

2.2.2 组件FSM的接口

带FSM的组件类实现Java接口Component。该接口定义了一系列状态间移动的方法。为了统一,每个方法关联一个通用的动作(actions)集合。这些动作主要在功能上实现一个组件在两个状态间迁移:

  • register() [INIT -> INACTIVE]:添加组件到映射表并存储,检验依赖条件是否满足(例如,新的端口必须添加到已经存在的交换机上)
  • boot() [INACTIVE -> ACTIVE]:打开控制信道,激活依赖的组件(例如:如果一个链路两端的端口上线,则启动该链路)
  • teardown() [ACTIVE -> INACTIVE]:关闭控制信道,激活依赖的组件(例如:如果一个端口下线,其关联的链路也会下线)
  • unregister() [INACTIVE -> STOPPED]:从映射表和存储中删除,去激活或者去注销依赖的组件。(例如:一条链路不再存在,所以必须调用unregister()函数,并且其关联的两个端口也要被注销。)

图2.1 给出了一个组件FSM的一般模型:状态迁移及其触发方法。派生自每个OVX组件类类都要实现Component及其FSM。

这里写图片描述

图2.1 OVX组件FSM状态转移图

注意,一个组件只能从INACTIVE状态被激活(activated)或者被停止(stopped ),以保证所有依赖项在某依赖启动运行或从网络中删除之前能够被安全地处理。本节讨论了组件FSM如何被耦合到一起以完成组件依赖并实现网络状态同步。

2.3 组件的持久化

虚拟组件由管理员配置。那么管理员就希望其配置能够保存,使得OVX重启后还能访问。OVX实现了将配置存储到远程数据库中,并在重启后恢复。

组件的类可以通过实现接口Persistable实现存储功能。该接口具有如下抽象方法。

Method Return Description Example getDBName() String Database name “VNET getDBIndex() Map<String,Object> 组件数据存储的文档的唯一索引 Key=”tenantId”, Value=Tenant ID (Integer) getDBKey() String 一个虚拟组件的数据存储的文档的键值 “switches”, “links”, “ports”, “routes”, “hosts” getDBObject() Map<String,Object> 列出所有添加到列表中的元素 (see the details below)

Persistable定义在[net.onrc.openvirtex.elements]。这些方法使得实现其的组件能够将数据序列化到数据库或者从数据库反序列化。更详细的讨论可以参考下一篇。

剩余章节将重点讨论各种元素的类定义中的各种包。

2.4 交换机[net.onrc.openvirtex.elements.datapath]

一个交换机代表了一个数据路径(datapath),由一组端口、一个交换机ID(DPID)、相关能力和属性(capabilities / attributes)的描述以及一个channel组成。

protected boolean isConnected = false;          // Channel liveness indicationprotected OVXDescriptionStatistics desc = null; // Switch statistics// T extends Port.protected HashMap<Short, T> portMap             // The ports on this switch, keyed by port numberprotected OFFeaturesReply featuresReply         // The Features Replyprotected Long switchId                         // The DPID of the switchprotected Channel channel                       // The control channel to the datapath

Switch子类作为OVX与租户NOS()之间、OVX与datapath (PhysicalSwitch)之间的OpenFlow信道的锚点。所有到达OVX的消息要么分别被北向或南向的事件循环直接处理,要么通过sendMsg() 和 handleIO()方法发送到交换机。下面介绍继承了Switch的几个类:

PhysicalSwitch (extends Switch)代表物理网络中的交换机。在OVX与交换机的握手通信期间,每个PhysicalSwitch的属性值来自两方面:由来自OVX的OpenFlow消息的内容填充,或者由运行时的状态消息填充。PhysicalSwitch维护了一张交换机的流表,每个XID翻译器代表与租户控制器之间的控制流量的OpenFlow XID。

相关组件:

  • StatisticsManager statsMan : 来自相关交换机的统计集合(MongoDB概念)
    *AtomicReference<Map<Integer, List<OVXFlowStatisticsReply>>> flowStats : 流表、以租户为key的项。
  • AtomicReference<Map<Short, OVXPortStatisticsReply>> portStats: 端口统计,以端口为键值*
  • XidTranslator<OVXSwitch> translator: XID 聚合/分发器((de)multiplexer);
  • SwitchState state : PhysicalSwitch实例的FSM。

PhysicalSwitch也包含了一个内部类,SwitchDeregAction,同步PhysicalSwitch之上的虚拟元素的状态。下一篇详细讨论OVX的状态管理。

OVXSwitch (extends Switch)是所有OVX中虚拟交换机的父类,也就是,对于租户控制器可见的交换机。OVXSwitch实现了FeaturesReply以响应租户,并维护虚拟流表,以及一个buffer map以存储bufferID为key,PacketIns为值。另外,OVXSwitch能够连接到多个控制器并处理控制器角色。关于角色管理,我们在下一篇博客翻译。

相关组件:

  • LRULinkedHashMap<Integer, OVXPacketIn> bufferMap
  • Integer tenantId : 该交换机属于的租户网络的ID;
  • OVXFlowTable flowTable : 存储交换机的流表项的结构;
  • XidTranslator<Channel> channelMux : Channel 复用和解复用器((de)multiplexer), 对于多个NOS连接;
  • RoleManager roleMan: 管理租户控制器的角色消息;
  • SwitchState state : OVXSwitch 实例的FSM。

另外,OVXSwitch直接实现了一些OFFeaturesReply域:

// Note, some attributes of a virtual switch are fixed:protected static int supportedActions = 0xFFF; // The supported actions.protected static int bufferDimension = 4096;   // The buffer dimension.protected Short missSendLen = 128;             // The miss send len. Default in spec is 128protected OVXSwitchCapabilities capabilities;  // The capabilities.

下述两个OVXSwitch的子类代表交换机虚拟化的两种模式。

  • OVXSingleSwitch: 映射到单个物理交换机的虚拟交换机;*
  • OVXBigSwitch:映射到多个物理交换机的虚拟机交换机,并将这组交换机看做单个“Big”虚拟交换机(BVS)的交换矩阵。OVXBigSwitch维护一张穿过该虚拟交换矩阵的所有路径的路由表。*

相关组件:

  • RoutingAlgorithms alg:计算路径的算法,分为人工指定或者计算的最短路(SPF);
  • HashMap<OVXPort, HashMap<OVXPort, SwitchRoute>> routeMap: 给定出入端口条件下,BVS的路由映射;

图2.2 给出了上述Switch类在虚拟网中的位置。

这里写图片描述

图2.2 OVX中不同Switch类

每个PhysicalSwitch (psw1, 2 and 3)直接对应物理网络中的一个交换机(switch1, 2, and 3)。虚拟交换机vsw1是一种OVXSingleSwitch的实例,直接映射在了PhysicalSwitch psw1之上。vsw2是一个OVXBigSwitch实例,映射在psw2和psw3之上,并且将两者之间的链路作为一个SwitchRoute。每个租户网络可以同时包含两种类型的OVXSwitch,只要它们不是位于相同的PhysicalSwitches上,也就是,在物理网络中不重叠。最后,物理交换机实例OpenFlow信道的终点。

2.5 Ports [package net.onrc.openvirtex.elements.port]

交换机端口是Port子类的实例,存储在交换机类的portMap数据结构中。端口具有的属性继承自OpenFlow的ofp_phy_port数据结构。OVX添加了如下信息支持网络虚拟化:

// T1 extends Switch, T2 extends Linkprotected MACAddress mac           // the hardware address of the portprotected Boolean isEdge           // true if this port is an edgeprotected T1 parentSwitch          // the switch that this port belongs toprotected LinkPair<T2> portLink    // if not an edge, the Links to/from this port

关于ofp_phy_port的详细结构可以参考OpenFlow规范。如果没有链路依赖该端口,则标记isEdge为true。另外,Ports也由一个state属性,是ofp_phy_port一部分,与Port类的FSM无关,但是其值会影响到Port子类的FSM。这将在下一篇讨论。

OVX实现了如下两种Port子类:

PhysicalPort (extends Port <PhysicalSwitch, PhysicalLink>):是PhysicalSwitch的一个端口。端口值及其属性来自交换机的功能回应消息( Features Reply)。PhysicalPort维护了一种自身到虚拟端口的映射ovxPortMap。每个PhysicalPort最多可以为每个租户网络承载一个OVXPort。
所有组件:
* Map<Integer, HashMap<Integer, OVXPort>> ovxPortMap
* PortState pstate:端口FSM状态

OVXPort (extends Port<OVXSwitch, OVXLink>):OVXSwitch的端口。OVXPort通过管理配置实例化。

组件:

  • Integer tenantId:该端口所在的OVXSwitch的所在虚拟网络的租户ID;
  • PhysicalPort physicalPort:
  • PortState pstate:端口FSM状态。

2.6 Links和Routes [package net.onrc.openvirtex.elements.link/net.onrc.openvirtex.routing]

OVX将Switch和Port的互联表示为链路。链路定义为两个端点,Switch/Port的源和目对。

protected T1 srcPort        // source Portprotected T1 distort        // destination Port// endpoint Switches are fetched from the parentSwitch attributes of the Portspublic T2 getSrcSwitch() {    return (T2) this.srcPort.getParentSwitch();}public T2 getDstSwitch() {    return (T2) this.dstPort.getParentSwitch();}

链路是具有方向的,所以一对方向不同的具有相同端点的链路构成双向链路。在端口类中由LinkPair结构维护。我们可以通过三种方式拓展链路:

(1) PhysicalLink (extends Link<PhysicalPort, PhysicalSwitch>):两个PhysicalSwitches通过PhysicalPorts连接。OVX通过拓扑发现模块找到物理链路(PhysicalLink)。

相关组件:

  • Integer linkId :链路的全局唯一标识;
  • AtomicInteger linkIds: 计数器的全局ID;
  • LinkState state:物理链路FSM状态。

(2)OVXLink (extends Link<OVXPort, OVXSwitch>):在同一租户网络中,由两个OVXPorts连接两个OVXSwitches形成。OVXLink可以映射到一个或多个邻接的PhysicalLinks上,OVXLinks由租户配置生成。

组件:

  • Integer linkId :链路ID,租户网络内的唯一标识;
  • Integer tenantId:该虚拟链路最在租户网络ID;
  • Mappable map:全局map的指针;
  • LinkState state:OVXLinks的FSM状态;
  • RoutingAlgorithms alg:将一条OVXLinks映射到一个或多个邻接的PhysicalLinks上。目前支持静态的方式(人工配置)和动态计算的最短路(SPF)。

(3)SwitchRoute (extends Link<OVXPort, PhysicalSwitch>):位于同一OVXBigSwitch上的两个OVXPorts的互联,定义为一条穿过虚拟交换矩阵的路径。SwitchRoute可以映射为一个或者多个邻接PhysicalLinks,且两种类型的短节点定义为:

  • BVS ingress/egress port:租户可见的OVXPorts;
  • SwitchRoute endpoints:位于BVS内部的PhysicalPorts;

组件:

  • Integer routeId:SwitchRoute的ID,对于OVXBigSwitch来说是唯一的;
  • OVXSwitch sw:该SwitchRoute所属的switch;
  • RouteState state:SwitchRoute的FSM状态;
  • PhysicalPort inPort:SwitchRoute 的入端点;
  • PhysicalPort outPort:SwitchRoute 的出端点;

SwitchRoutes可以由一个租户指定,或者OVXBigSwitch实例的路由算法(RoutingAlgorithm)产生。图2.3和2.4总结了3种类型的链路的结构和关系。

这里写图片描述

图2.3 三种链路的结构

这里写图片描述

图2.4 各种链路映射

图的上面是两个租户,底部是OVX的网络视图(也就是物理网络)。实际上只有一个物理网络,这里我们为了清晰表达租户网络而画了两个。右边的图:租户1由两个OVXLinks,vlink1 和 vlink2。其中Vlink1对应路径ps1-ps3-ps2,其穿过物理链路l2和l3。vlink2是1:1映射到l5。右图:租户2包含OVXLinks(红色)和一个SwitchRoute,连接了OVXBigSwitch vs2的端口。后者映射到l3(蓝色)。

2.6.1 虚拟链路弹性(Resilience)

虚拟链路(OVXLinks and SwitchRoutes)与一个或多个物理链路(PhysicalLinks)列表(list)关联。我们称这些列表为路径(path)。一条虚拟链路的优先级就是它的原始路径(primary path)的优先级的值。原始路径可能是该虚拟链路的唯一路径集合,也可能是最高优先级的路径。当多条路径绑定到一个虚拟链路上时,未使用的路径可以用来引入组件弹性(component resilience),实现方法如下:

  • private byte priority: 虚拟链路的当前优先级;
  • private final TreeMap<Byte, List<PhysicalLink>> backupRoutes:包含可选路径的容器,其键为优先级;
  • private final TreeMap<Byte, List<PhysicalLink>> unusableRoutes:维护失败路径的容器,其键为优先级。

关于弹性的详细论述我们将在下一篇讨论。

2.7 Addresses [package net.onrc.openvirtex.elements.address]

IP地址表示为整数,并关联到网络主机。OVX在虚拟化过程汇总标示两种类型的IP地址。

OVXIPAddress是IP地址的网络主机,通过外部方式分配主机。OVXIPAddress 在一个租户网络中是唯一的。

PhysicalIPAddress由OVX分配,并在整个网络中是唯一的。OVXIPAddresses被映射到核心网络中的PhysicalIPAddress上,以便于在不同租户之间分发流量。该过程我们将在下一篇中的地址虚拟化详细讨论。

2.8 Hosts [package net.onrc.openvirtex.elements.host]

主机表示租户网络的流量终点。一般地,主机由附着点(attachment points)、地址和唯一ID定义。

private final Integer hostId;               // OVX-asigned UUIDprivate final MACAddress mac;               // MAC address of host in the networkprivate final OVXPort port;                 // Attachment pointprivate OVXIPAddress ipAddress;             // Network addressprivate HostState state                     // Host FSM

OVX的主机是虚拟化的构造,没有区分物理机和虚拟机。主机的物理表示方法是通过找到其物理上等价的附着点和网络地址产生。

public HashMap<String, Object> convertToPhysical() {     HashMap<String, Object> map = new HashMap<String, Object>();     map.put("hostId", this.hostId);     map.put("dpid", this.port.getPhysicalPort().getParentSwitch().getSwitchName());    // Find Physical attachment point that corresponds to Host's virtual one    map.put("port", port.getPhysicalPortNumber());    map.put("mac", this.mac.toString());    // Find Host's PhysicalIP, if it has one    if (this.ipAddress.getIp() != 0)            try {                map.put("ipAddress", OVXMap.getInstance().getPhysicalIP(this.ipAddress, this.port.getTenantId()).toSimpleString());

当isEdge 为true时,OVXPort的接入的是Host。

2.9 Networks [package net.onrc.openvirtex.elements.network]

Network类存储描述交换机、链路、端口和主机的映射。

protected final Set<T1> switchSet;                  // set of all switches found in this networkprotected final Set<T3> linkSet;                    // set of all links within this networkprotected final Map<Long, T1> dpidMap;              // mapping between switches and their DPIDsprotected final Map<T2, T2> neighborPortMap;        // mapping between ports that are endpoints of the same linkprotected final Map<T1, HashSet<T1>> neighborMap;   // mapping between a switch and its adjacencies

Network并不存储SwitchRoute,或者端口与交换机的归属关系,因为这些在交换机内部维护着。当前OVX由两种网络表达形式。

PhysicalNetwork:单例类,表示OVX的网络视图。理想情况下,PhysicalNetwork是底层物理网络的一对一复制。PhysicalNetwork维护着基于LLDP的拓扑发现模块,以及一个HashedWheelTimer驱动拓扑发现和统计记录。我们在下一篇详细讨论拓扑发现。

组件:

  • PhysicalNetwork instance : PhysicalNetwork的单例;
  • ArrayList<Uplink> uplinkList
  • ConcurrentHashMap<Long, SwitchDiscoveryManager> discoveryManager:交换机(DPID)与拓扑/端口状态发现管理器之间的对应关系;
  • HashedWheelTimer timer:其中周期性任务的定时器;
  • NetworkState state:PhysicalNetwork 的FSM

2.10 共享的全局映射[package net.onrc.openvirtex.elements], ovxPortMap

物理网络与租户网络之间的映射存储在全局可访问的数据结构中——一个单例OVXMap结构。该映射接口定义了所有常用的操作函数。

OVXMap实现为一个Java Maps的集合,其键为各种网络组件或他们的标识。

HashMap Key Values virtualSwitchMap OVXSwitch PhysicalSwitches physicalSwitchMap PhysicalSwitch Map<TenantID,OVXSwitch> virtualLinkMap OVXLink PhysicalLinks physicalLinkMap PhysicalLink Map routetoLinkMap SwitchRoute PhysicalLinks phyLinktoRouteMap PhysicalLink SwitchRoutes using PhysicalLink, keyed on TenantID networkMap TenantID OVXNetwork physicalIPMap PhysicalIPAddress (as String) OVXIPAddress virtualIPMap OVXIPAddress PhysicalIPAddress macMap MACAddress (as String) Tenant ID as integral value

除了OVXMap,PhysicalPort’s的ovxPortMap存储着所有OVXPorts到PhysicalPort的映射。

2.11 消息 [package net.onrc.openvirtex.messages]

OVX将OpenFlow消息看做特殊的消息类实例。每个OpenFLow消息[org.openflow.protocol]都具有一个OVX的等价形式,也就是,所有消息类使用相同的名称,只是将OF前缀替换为“OVX”前缀。这些消息类实现了以下Java接口之一:

  • Virtualizable (public void virtualize(PhysicalSwitch sw)):处理到租户方向的消息,来自PhysicalSwitch sw,包括确定哪个租户应该收到该消息,重写该消息内容使其与该租户的OVXNetwork网络拓扑一致。

  • Devirtualizable (public void devirtualize(OVXSwitch sw)):处理到网络方向的消息,由租户控制器发送到OVXSwitch sw。

前一节的图1.2描述了该过程。在下一篇中,我们将详细描述核心事件循环调用这些方法的过程,以及其详细的虚拟化和反虚拟化的过程。

0 0
原创粉丝点击