- 积分
- 519
- 鸿鹄币
- 个
- 好评度
- 点
- 精华
- 注册时间
- 2017-5-31
- 最后登录
- 1970-1-1
- 阅读权限
- 40
- 听众
- 收听
中级工程师
   
|
一、控制器集群基本知识1.1 Consensus一致性Consensus一致性是指多个服务器在状态达成一致,但是在一个分布式系统中,因为各种意外可能,有的服务器可能会崩溃或变得不可靠,它就不能和其他服务器达成一致状态。这样就需要一种Consensus协议,一致性协议是为了确保容错性,也就是即使系统中有一两个服务器宕机,也不会影响其处理过程。
为了以容错方式达成一致,我们不可能要求所有服务器100%都达成一致状态,只要超过半数的大多数服务器达成一致就可以了,假设有N台服务器,N/2 +1就超过半数,代表大多数了。
odl控制器集群采用Raft一致性算法进行Leader的选举。每台控制器都有3种状态,分别为Follower、Candidate、Leader,各个角色如下:
- Leader: 处理所有客户端交互,比如日志复制等,一般一次只有一个Leader
- Follower: 类似选民,完全被动
- Candidate候选人: 类似Proposer律师,可以被选为一个新的领导人
1.2 控制器Leader选举过程动画演示http://thesecretlivesofdata.com/raft/
官网介绍https://raft.github.io/
1. 任何一个服务器都可以成为一个候选者Candidate,它向其他服务器Follower发出要求选举自己的请求:

2. 其他服务器同意了,发出OK。

注意如果在这个过程中,有一个Follower宕机,没有收到请求选举的要求,因此候选者可以自己选自己(每个候选人都是选自己的),只要达到N/2 + 1 的大多数票,候选人还是可以成为Leader的。
3. 这样这个候选者就成为了Leader领导人,它可以向选民也就是Follower们发出指令,比如进行日志复制。

4. 以后通过心跳进行日志复制的通知

5. 如果一旦这个Leader当机崩溃了,那么Follower中有一个成为候选者,发出邀票选举。

6. Follower同意后,其成为Leader,继续承担日志复制等指导工作:

7.如果同时又两个Follower变成Candidate参与Leader的竞选,则进入分裂选举(Split Vote)。

二、clustering集群架构1、控制器集群主要有两个子系统支撑,一个是Distributed Data Store,一个是Remote RPC Connector。Distributed Data Store做控制器集群的Data Store同步,而Remote RPC Connector负责远程过程调用,即当RPC请求到Follower时,Follower会将该请求转向Leader控制器,对于用户而言,由谁提供RPC返回值是透明的。

2、控制器集群是基于分布式编程接口库AKKA,而AKKA是基于actor模型实现的并发处理框架。基于事件驱动的并发处理模型,每一个actor拥有自己的属性和操作,避免了通常情况下因为多个线程之间要共享属性(数据)。

3、数据同步分为DataStore与Remote RPC的数据同步,基本原理为先将操作的数据保存为一堆的快照,等操作确认无误后再提交至数据库

4、DataStore中有一个术语为Shard(数据树碎片),将数据库分为多个数据树碎片(shard),初始状态时包括inventory、topology、toaster、toaster,可以在distribution-karaf-0.3.3-Lithium-SR3/configuration/initial/module-shards.conf中看的这4个shard。每个模块可以分布在不同的shard上。各自的shard有各自的leader和follower选举结果,比如inventory的leader在vm1,而topology的leader在vm2上。

5、当inventory-leader的datastore数据发生变化时,会自动同步给其他follower。

6、Raft一致性算法选举过程状态图如下:

7、当北向REST API 发送一个RPC请求至控制器时,通过RPC路由,由Leader做出反馈,此过程对应用户而言是位置透明的。

8、集群的代码实现结构大致如下:

三、openflow与控制器集群Opendaylight控制器支持两种版本的OpenFlow协议,OpenFlow 1.3和OpenFlow 1.0。在控制器集群中,两者的区别有:
1、OpenFlow 1.3在OpenFlow的1.3中,每个交换机被连接到属于集群的每个控制器节点。交换机分配到以下每个控制器节点角色之一:
- Master----所有的同步和异步消息被发送到主控制器节点。此节点有交换机的写入权限。
- Slave----仅同步消息发送到该控制器节点。此节点只有交换机的读权限。
- Equal----当该角色被分配给控制器节点,该节点具有与主节点相同的特权。默认情况下,控制器首先连接到交换机时被赋予Equal的角色。
2、 OpenFlow 1.0因为OpenFlow 1.0不支持角色,连接到集群的交换机任何时候只连接一台控制器节点,比如采用floating/virtual IP address形式。当交换机连接的控制器节点down机了,交换机会自动的连接到另外的控制器节点,当然这个控制器节点是被选举出来的Leader节点(作为inventory-operational-shard 的leader)。
就像OpenFlow 1.3一样,在控制器节点上的每一个datastore被分成了shards碎片,其中的某一个shards碎片作为leader。通过配置floating/virtual IP address,交换机连接到inventory-operational shard leader 驻留的控制器节点(master node)。
3、 集群中的流表修改操作in-memory datastores中有两种类型:config 和 inventory,同时在每一个datastores都有四个shards驻留:default, inventory, toaster, and topology,注意修改流表会同时涉及config and operational datastore 的inventory碎片。
修改流表时:
1)增加流表的请求被路由到inventory-config-shard leader驻留的主控制器节点。
2)当inventory-config-shard leader收到流之后,leader会备份该流,然后提交到datastore。
3)当流被提交到datastore时会发出一个通知(notification),同时增加流的RPC(远程过程调用)会发往remote RPC connector。注意:所有的交换机的RPC都是注册在了主控节点上(master node)。
4)Remote RPC connector定位出master node并且转发增加流的RPC到master node上。
5)当master node的RPC component接受到该增加流的RPC,会将该RPC转发至OpenFlow plug-in,OpenFlow plug-in将该RPC转发给交换机。
6)在此背景下,Statistics Manager统计数据管理器通过执行流定期轮询交换机,通过对交换机执行流量等统计数据的RPC。统计数据管理器仅在主节点上启用。
7)交换机对此RPC做出反馈(采用notifications),该notifications只发往master node。
8)当该notifications被接受到,Statistics Manager增加该流到inventory-operational datastore。
4、通过Mininet模拟连接到odl集群中的相关命令1)查看交换机连接了哪些控制器
Java
sudo ovs-vsctl list CONTROLLER
1
| sudo ovs-vsctl list CONTROLLER
|
2)采用openflow1.3连接控制器
Java
sudo mn --topo single,3 --mac --controller=remote,ip=192.168.7.108,port=6653 --switch ovsk,protocols=OpenFlow13
1
| sudo mn --topo single,3 --mac --controller=remote,ip=192.168.7.108,port=6653 --switch ovsk,protocols=OpenFlow13
|
3)步骤2)只是启动了mininet的1.3版本,还需要对交换机进行配置
Java
ovs-vsctl set bridge s1 protocols=OpenFlow13
1
| ovs-vsctl set bridge s1 protocols=OpenFlow13
|
4)查看openflow1.3流表
Java
xterm s1ovs-ofctl dump-flow s1 -O OpenFlow13
1
2
| xterm s1
ovs-ofctl dump-flow s1 -O OpenFlow13
|
四、点滴记录1、OpenFlow1.2 开始支持多控制器
OpenFlow 1.2引入多控制器的理念,希望通过多个控制器的协同工作提高全网的可靠性。
-----OpenFlow交换机在其初始化时,即与一至多个配置好的控制器建立连接。多个控制器之间可以提供负载均衡能力和快速故障倒换,同时增加角色类消息用于控制器之间协商主备关系
-----控制器的角色在缺省情况下为EQUAL,在此状态下的控制器可以响应来自OpenFlow交换机发来的请求;控制器角色也可以设为SLAVE,在此状态下控制器只负责监听,不响应交换机发送的消息;另外,控制器还可以是MASTER角色,这种状态下的控制器行为与EQUAL类似,唯一的差异在于系统中只能有一台MASTER。
2、OpenFlow 1.3增加了两个controller-to-switch消息
-----Role-Request:用于控制器向其OpenFlow通道进行角色的设置或查询
-----Asynchronous-Configuration:用于控制器设置或查询异步消息的附加过滤器,一般用于多控制器的连接建立
3、mininet构建mininet大型网络集群
mn --cluster localhost,server1,server2
4、Li版SR2标记odl的集群bug,openflowplugin出现多台控制器同时操作交换机导致冲突的bug。
https://bugs.opendaylight.org/show_bug.cgi?id=4105
http://www.sdnlab.com/community/article/103
5、odl采用RAFT协议进行集群选举,而根据RAFT协议,三节点是能够进行集群部署的最小配置,也即是odl要实现HA,至少是三个节点。
6、从lithium版本开始,在karaf中,会存在odl-openflowplugin-nsf-services-li与odl-openflowplugin-nsf-services这样两种相似的feature,它们的内在区别就在于,-li后缀所标识的feature,是lithium版本针对于openflowplugin在helium版本上存在的问题而进行新设计后的实现,像EntityOwnershipService就只在新设计的openflowplugin被实现了。如果要测试新版本的openflowplugin,则要注意安装-li后缀的特性。
具体的做法就是,针对于一个由openflow:dpid所标示的of设备,每个集群实例上的ofplugin都注册自己为candidate,利用raft的选主机制,选出一个ofplugin做为主,ofplugin得到升主通知后,就作为该设备的rpc owner,并通过openflow的role request消息设置自己为master,其他raft follower实例则设置自己为slave,这样就在一定程度上解决了不支持主备的问题。
entityowner这个服务是一个通用的服务,其他app也可以自己注册一个全集群唯一的entity,从而实现多集群实例下的选主操作,并在主故障时,处理新主实例的升主操作,提高app的可用性。具体的使用办法是在自己app的yang模型里,增加对entityownerservice的引用。
7、在验证过程中,我遇到了bug4473这个lithum design中存在的不兼容ovs 2.4.0的table feature消息中的nxm扩展的问题,会导致of设备不能被加进到inventory数据库中,这个问题暂时还未被fix,大家在使用中,可以注意降级,避免浪费时间定位。
|
|