对Neutron ML2的设计思想的理解

最近在做一个SR-IOV网卡的测试,测试过程中再次看了下create_port的代码,同时思考了一下ml2的设计思想。希望能帮助大家理解。

我们都知道,建立一个port的时候,只需要指定network就行。

port的建立涉及到两个阶段。一个是nova,其会调用plug_XXX将port在compute主机上做相关的plug操作(列如对于plug_ovs来说会建立qbr啥的)。另一个阶段是neutron,其会保存port的相关信息到数据库中,然后相应的compute主机上的XXX agent也会对port做相关操作。

比如我想实现一个ml2的agent,那么我要做什么呢?根据上面的分析,我要做两件事情:
1.让nova把port plug到我的agent相关的对象上(比如br-int,比如qbr,比如eSwich….)
2.运行对应的agent,维护port信息

那么如何让nova调用我的agent driver实现的plug_XXX代码呢?首先肯定nova的代码里要有这个,其次这里的XXX如何获取呢?很简单,XXX就是port的binding:vif_type的值。如果一个port没有binding:vif_type,那么nova会报错。

那么binding:vif_type这个来自于哪里呢?有几种方式设置。比如:

a. 我建立port的时候指定我的nic的type,然后neutron-server在遍历mech driver的bind_port方法的时候,每个driver的bind_port会判断这个nic的type是不是自己支持的,如果是则设置这个port的vif_type,否则就忽略。这里可以注意一点,如果多个mech driver都支持,那么最后设置的mech driver会设置最终的vif type。另外这里也能看到一个设计上的隐含思想:一个环境下不能有两个mech driver其提供相同的 vif type。否则你让nova调用plug_XXX的时候把这个port放到哪个mech driver管理的对象上呢?另外这里也能看到nic和vif的区别。nic是针对vm的,所以nova和它打交道,但是vif是针对switch的,所以neutron和它打交道。

b.根据network来判断。比如我的network是vlan类型的,并且关联了phybr1这个网络。那么遍历mech driver的bind_port方法的时候,每个mech_driver都会看下自己是不是有这个phybr1的信息(即我的mapping里有没有满足这个network的segment要求的)。如果有就设置下对应的vif type,否则就忽略。一个例子就是ovs和linuxbridge,前者的配置文件中有bridge_mapping,后者有interface_mapping,我们一般只会指定前者,后者都是空,所以我们建立的网络的port的vif默认都是ovs。假如我们bridge_mapping和interface_mapping中都有phybr1这个provider_network的mapping信息,那么mech driver的bind_port在遍历的时候可能显示调用ovs,ovs将其vif设置为ovs,然后是调用linuxbridge,其又将vif的type从ovs改成了bridge。于是nova会调用plug_bridge方法将port放到linuxbridge的相关对象上了。ovs-agent和linuxbridge-agent都可以跑在这台compute上,但是只有linuxbridge-agent会的意识到这个port的存在(while循环中会从本地去数据和plugin来的数据比较,ovs-agent是得不到这个port的信息的)。这里也可以看出vif对应的mech driver同一个环境必须唯一。

从上面可以看出,最简单的让一个port被自己写的ml2 mech agent管理的方法就是直接明确port的nic type,create_port根据nic type遍历ml2 mech agent,只有我写的mech driver会的识别这个nic type,于是给这个port的vif指定唯一的vif,于是nova就会把这个port plug到我的mech agent维护的对象上去了(一般是bridge)。

当然上面的分析忽略了network type的检查。port所在的network的type必须被ml2 mech driver支持,否则也是直接忽略,不会设置vif的。

这里是个合适的时候思考下ml2的设计思想了。type manager可以认为就是在db中设置足够的信息,尤其是segment的信息。要知道,不管你compute上的agent是如何复杂,连接物理节点的物理网络是一样的,就是一个大二层。所有的ml2 mech agent都要基于这个思想来设计,既然如此,既然物理网络是一样的,那么这就给了同一个环境同时运行多种ml2 driver的可能性了。想想TCP/IP栈,上层的应用可能千差万别,但他们都能正常通信,为什么?因为分层、封装、屏蔽。ml2也是这么个思想,compute A上面可以跑XXX agent,vm中的数据在XXX agent上可能被XXX管理着,但是当他出来的时候,在物理网络它就是个打了vlan tag的数据包(如果是vlan的话),然后数据流进入compute B,B上的YYY agent负责将这个vlan tag包翻译成自己理解的东西就行了。

从上面这段可以自然而然的看到:type manager决定的是物理网络的类型!

如果理解了这个,那么对type manager就完全理解了。type manager是物理网络的类型,也就是我们的基础,我们的底层。可以把type manager看成底层的公共层,则mech manager则是基于这个公共层的上层应用了。应用可以千差万别,并且也能互相通信,只要一个前提:他们用的是同一个底层。这个是自然的,因为对于一个network,其只有一个network type。type manager的核心是segment(因为segment有type啥的信息啦)。

也就是说,只要type是一样的(肯定是一样的,因为network只有唯一的type),那么ml2支持多个mech agent同时在同一个环境下通信。

这个时候再去看ml2的设计思路就很清楚了:我官方提供type,type的标准是定下来的。你们写mech driver的人都按照这个官方要求来转换、配置吧。只要你们的流量出到物理机外是遵循这个type的,那么其余的mech agent只要也遵守这个规定,那么不同的compute上就能运行不同的mech agent。

当然啦,上面也提到了,虽然我的ml2 mech driver支持,但也要看用户想不想用。如果我用户明确指定了要用XXX agent,并且在建立port的时候指定了XXX的nic type,那么其余的ml2 mech driver也就只能忽略了。

如果我想让这个port归我所有,那么只要条件满足,把port的vif type设置为我自己的类型就行了(vif就是switch,switch就是mech啦)

那如果一个主机上运行了多个mech agent,并且他们都将port的vif type设置为相同的值,那么会发生什么呢?大家可以考虑下:)

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*