本节讨论分布式ONOS的设计与实现。ONOS是一个全新设计的一个分布式SDN操作系统。目前,ONOS可以部署在一组服务器上,彼此协同地提供比单控制器更优的服务。例如,分布式机制提供了容错和弹性机制,可以容忍单个控制器实例的故障。另外,该系统可以承载比单个控制器实例更多的控制负载,具有良好的扩展性。
除了讨论其优点外,该系统也面临一些工程问题。下面我们讨论ONOS如何克服这些问题。
### 概述
多实例ONOS部署是一个或多个ONOS实例的集群。ONOS实例也称为节点(node)。每个实例有唯一的NodeId。集群中的每个节点管理网络中部分区域的状态。本地区域的状态信息由管理该区域的节点作为事件(events)在集群内传播。事件在仓库(store)里产生,并通过分布式仓库内建的各种服务在集群里共享。
除了数据发布,ONOS集群还必须:
* 检测并处理节点的加入或离开集群;
* 委托控制设备,一个设备只有一个主控制器。
第一条由集群子系统管理,包括集群管理和主控管理。本节将详细分析分布式仓库,描述这些管理功能。
### 分布式仓库(stores)
根据服务需求的不同,一个仓库内的内容如何发布到不同的节点可能具有不同的方案(例如,强一致性(strongly consistent),最终一致性(eventually consistent)等)。因此,最好的方案是,将不同服务的仓库实现合适的分布式机制。目前,主控(mastership)管理的仓库使用Hazelcast的分布式结构,即强一致性。对于设备、链路和主机管理的仓库使用最优副本技术( optimistic replication technique),通过背景协商协议(background gossip protocol )确保最终一致性。
两个不同节点上的同一子系统直接通过仓库同步。仓库只需同步子系统的状态。例如,一个DeviceStore,仅掌握了设备的状态,并不知道主机或链路信息如何被获取。下图总结了两个节点和一个子系统”A”的情况。子系统A分别是两个节点的一部分。
撰写本书时,所有具有拓扑管理异常的服务均可访问分布式拓扑。分布式拓扑仓库进依赖于设备、链路和主机的分布式版本。

#### Event ordering事件顺序
对于最终一致性仓库,事件通过类似于矢量时钟的方法进行排序。 DeviceStore 和LinkStore使用的逻辑时钟是一个设备的主控切换数量的组合,因为它的发现,该节点的本地序列号将为每个观察到的事件递增。HostStore 依赖于系统时间,主机对象的寿命及其移动性阻止了其被捆绑到一个特定的设备。基于设备的逻辑时钟机制将在“网络拓扑状态”一节详细讨论。
### 集群管理
注意,ONOS也使用属于“集群”来特指网络拓扑的连接子图,其与多实例的集群没有关系。本节的集群概念是指多控制器实例组成的集群。
集群子系统负责以下功能:
* 跟踪集群的成员管理;
* 以NodeId的形式,委托节点标识;
* 提供本地节点的概念,类似于localhost。
`DistributedClusterStore`目前使用Hazelcast作为其集群成员管理——实现Hazelcast 的`MembershipListener`,并且将`MembershipEvents`翻译成ONOS 的`ClusterEvents`。另外,关于仓库之间用来通信的多播组的管理和设置也是通过它实现。
### 设备主权管理(Device Mastership Management)
一个设备可以连接集群中的任何一个或多个节点。关于一台设备,控制节点具有三个角色。
* NONE:该控制节点可能没有关于该设备的任何信息,不能与其交互;
* STANDBY:该控制节点具有该设备的信息,而且也能够读取设备状态,但是不能管理(不可写)设备。
* MASTER:该控制节点具有设备的信息,并能够完全控制(可读、可写)该设备。
这三个角色分别映射到OpenFlow1.2中定义的`MastershipRole`枚举。主权子(mastership)系统负责确保每台设备仅有一个MASTER 控制器,且其它控制器是 STANDBY 或者NONE。下一节描述服务如何分配和重分配角色,以及各种故障后的角色配置恢复。
#### 控制节点主权的生命周期Node Mastership Lifecycle
一个控制节点起始于NONE角色。在当前实现版本,第一个控制节点需要确认:设备没有主控节点,具有一个控制信道连接到该设备,成为其主控制器。任何后续发现该设备的其它控制节点成为该设备的STANDBY——如果该控制节点具有到该设备的连接,否则成为该设备的NONE。当DeviceService 通过分布式仓库间接地检测到该设备,或者如果原来的连接到该设备的连接断开了,那么该主控节点将成为NONE。角色、控制节点和设备的映射存储在MastershipStore里,作为DeviceId到RoleValue 模型对象的分布式映射。
建立的角色可以根据不同事件进行改变。ONOS目前考虑以下事件:
* 管理员干预:管理员手动第设置一个设备的控制角色;
* 从设备失联:控制节点失去了到该设备的连接通道;
* 从该集群失联:分裂脑综合征。
MastershipManager通过角色放弃(role relinquishment )和角色重选(reelection ) 负责这些角色变更事件的处理,保持“一个设备只有一个主控制器”的策略,确保一个不能正确处理设备的控制节点不被选择为主控节点。
注意:术语控制节点、`MastershipManager`、和`MastershipService`在本节中指代同一事物。
1. 角色放弃
放弃其角色的控制节点将放弃其当前角色,返回到NONE 角色。一个控制节点会在如下情况系放弃其对某设备的当前角色。
* 控制节点失去到该设备的连接,或设备故障;
* 控制节点在分裂大脑状况下,变成少数派;
* 管理员命令设置其为NONE角色;
* 一致性检测失败,也就是,如果一个OF设备向RoleRequest 发送一个错误,或发生不可预知的主权变更。
1. 角色选举
重新分配主权的控制节点可能选举另一个控制节点成为该设备的新的主控制器。触发重新选举的情况包括:
* 主控制器出现故障(角色放弃);
* 设备从主控制器失联;
* 管理员将当前主控制器降级为STANDBY 或NONE。
设备的候选控制节点从该设备的standby 控制器池中选择。目前,该池是按优先级排序的NodeID的有向列表。这可以使放弃角色的控制器简单地选择列表中的下一个节点,确保下一个节点是最优选择。
候选节点可以选择成为一个新的主控制器,也可以在面临故障的情况下,通过角色放弃指定另一个候选者。如果该设备有N个后备(standy)控制节点,重新选举能够最多发生N次。这种切换链会在该设备完全与控制平面失联的情况下出现。该机制阻止了无限的重新选举。
#### 关于大脑分裂情况
当一个集群分裂为两个不同大小的集群时,在较小规模集群中的控制节点将放弃它们的角色,或者,较大规模集群中的成员将对由较小集群控制的设备集合强制开展重新选举。MastershipManager 通过询问ClusterService判定其出于少数派或多数派。
目前的ONOS实现版本不能处理分割大小相同的两个集群的情况,两个控制集群会同时连接到网络。
### 与设备子系统的关系
设备子系统使用由`MastershipManager` 维护的角色信息确定以什么方式与设备进行交互。`MastershipManager` 也监控设备事件,作为角色重新选举和放弃的依据。最后,任何基于角色的控制消息,无论是来自网络还是发送到网络,例如,OpenFlow `RoleRequests` 和`RoleReplies`,必须通过`DeviceProvider`发送和接收;所以,`DeviceService` 必须代表`MastershipService`控制网络。
- 目录
- 前言
- 第一部分 SDN基础
- 第一章 SDN控制器综述
- 1 引言
- 2 控制器架构
- 2.1 集中式控制器
- 2.2 分布式控制器
- 2.3 北向接口编程语言
- 2.4 SDN功能组合
- 2.5 策略更新一致性
- 参考文献
- 第二章 OpenFlow学习指南
- 1 概述
- 2 环境配置
- 2.1 相关软件
- 3 虚拟机设置
- 3.1 导入虚拟机镜像
- 3.2 网络访问
- 4 开发工具手册
- 4.1 Hello world网络
- 4.2 Mininet简介
- 4.3 其它工具
- 4.4 初识控制器
- 5 控制器介绍:以创建学习型交换机为例
- 5.1 POX控制器
- 参考文献
- 第三章 Karaf使用手册
- 1 Apache Karaf
- 2 安装Apache Karaf
- 2.1 依赖条件
- 2.2 获得Apache Karaf发布包
- 2.3 安装Apache Karaf
- 2.4 首次启动
- 2.5 总结
- 3 命令行操作
- 3.1 常用命令
- 3.2 远程控制台访问
- 3.3 自定义命令
- 3.4 可选的web控制台
- 3.5 总结
- 4 仓库
- 4.1 Apache Maven库
- 4.2 Karaf系统库
- 第二部分 ONOS体系架构
- 第一章 ONOS体系概述
- 1.1 设计目标
- 1.2 剩余章节
- 第二章 系统组件
- 2.1 系统层级(system ties)
- 2.2 服务和子系统
- 2.3 子系统结构
- 2.4 事件和描述
- 第三章 构建网络状态
- 3.1 ONOS表示网络
- 3.2 网络发现
- 3.3 网络配置子系统
- 第四章 设备子对象
- 4.1 概述
- 4.2 模型对象和提供者表达
- 4.3 OpenFlow子系统
- 4.4 交换机状态
- 第五章 设备驱动子系统
- 5.1 定义
- 5.2 交付机制
- 5.3 查询机制
- 5.4 模型
- 5.5 上下文
- 第六章 分布式操作
- 6.1 集群协同
- 6.2 网络拓扑状态
- 第七章 意图框架(intent framework)
- 7.1 概述
- 7.2 意图
- 7.3 意图汇编
- 第八章 Web UI架构
- 8.1 概述
- 8.2 客户端架构
- 8.3 服务端架构
- 8.4 处理流程
- 第九章 核心UI扩展体系
- 9.1 拓扑视图架构
- 9.2 关于链路
- 第十章 联盟ONOS web UI
- 第十一章 GUI源代码目录结构
- 第十二章 组件配置
- 12.1 概述
- 12.2 组件代码示例
- 12.3 Maven例子
- 12.4 CLI命令
- 第十三章 应用程序子系统
- 13.1 概述
- 13.2 应用程序包
- 13.3 CLI命令
- 13.4 REST API和shell工具
- 13.5 Maven例子
- 13.6 内建范例和测试应用程序
- 第十四章 分布式原语
- 第十五章 标签(Label)子系统
- 15.1 概述
- 15.2 ONOS应用程序编程接口
- 15.3 使用CLI命令管理标签
- 第十六章 隧道(tunnel)子系统
- 16.1 概述
- 16.2 ONOS应用程序使用的可编程APIs
- 16.3 使用CLI命令管理隧道
- 第十七章 北向接口扩展
- 17.1 概述
- 17.2 驱动器行为
- 17.3 Treatment扩展
- 17.4 selector扩展
- 17.5 应用程序使用范例
- 第三部分 ONOS用户手册(未完,待续)
- 1 获得ONOS
- 2 ONOS源码安装
- 2.1 系统要求
- 2.2 安装JAVA,Maven and Karaf
- 2.3 使用onos测试工具远程部署onos
- 3 ONOS可执行程序安装和配置
- 3.1 运行要求
- 3.2 单机安装ONOS
- 3.3 将ONOS作为系统服务
- 3.4 通过CLI和GUI访问ONOS
- 3.5 组合一个集群
- 4 配置ONOS
- 4.1 管理ONOS应用程序
- 5 ONOS交互接口
- 6 附录A-CLI命令大全
- 7 附录B-REST APIs大全
- 第四部分 ONOS开发指南(未完,待续)
- 开发者快速入门(...)
- 开发ONOS应用程序
- 导入ONOS源码到IDEA
- 开发前配置
- 基于Maven原型生成ONOS应用工程
- 1.3.1 生成应用模板
- 1.3.2 导入APP
- 1.3.3 app添加CLI支持
- 1.3.4 app添加GUI支持
- 第五部分 OpenVirteX架构
- 第一章 OpenVirteX概述
- 1.1 网络虚拟化
- 1.2 OpenVirteX架构
- 第二章 OpenVirteX组件简介
- 2.1 概述
- 2.1.1 实现类
- 2.2 组件状态机
- 2.2.1 基本FSM状态
- 2.2.2 组件FSM的接口
- 2.3 组件的持久化
- 2.4 交换机[net.onrc.openvirtex.elements.datapath]
- 2.5 Ports[package net.onrc.openvirtex.elements.port]
- 2.6 Links和Routes[package net.onrc.openvirtex.elements.link/net.onrc.openvirtex.routing]
- 2.7 Addresses[package net.onrc.openvirtex.elements.address]
- 2.8 Hosts[package net.onrc.openvirtex.elements.host]
- 2.9 Networks[package net.onrc.openvirtex.elements.network]
- 2.10 共享的全局映射[package net.onrc.openvirtex.elements]和 ovxPortMap
- 2.11 消息[package net.onrc.openvirtex.messages]
- 第三章 操作和子系统
- 3.1 系统概述
- 3.2 启动和关闭
- 3.3 事件循环
- OpenVirteX API
- 使用指南
- 第六部分 实验设置