转载 https://blog.csdn.net/mr1jie/article/details/102918861
记OpenStack网络参数segment
前言
网络实现
介绍
Neutron和ODL的结合
如何选择segment
如何对segment排序
总结
前言
在一次与友商的SDN控制器进行对接的项目中,网络使用vxlan,在Neutron中安装ODL插件进行和友商SDN的对接。
网络实现
介绍
虽然使用的vxlan,但是项目中,OpenStack云平台处仍然使用vlan网络(出宿主机前);即云平台只创建vxlan网络,网络实现还是走vlan模式,具体的vlan分装成vxlan的动作是在SDN控制下的交换机中再实现。
即宿主机处为vlan2000,传入到接入层交换机再加装为vxlan22000
那么如何实现创建的网络为vxlan,却让网络上的port走vlan网络呢?
Neutron和ODL的结合
这里主要分析一下创建网络的流程,创建网络选择使用vxlan,输入vni,如22000,创建网络存入数据库后通过ODL向SDN发送网络信息,根据提前写好的网络id范围分配一个vlan_id(2000)保存对应关系并发回OpenStack,更新网络
openstack network set --provider-network-type vlan --provider-
physical-network physnet1 --provider-segment 2000 net_name)
给网络加入多个属性。
举例:此网络拥有vlan 105 和vxlan1002
那么当网络有多个属性后,我创建port后又有如何的选择策略能保证我选到vlan呢?
如何选择segment
代码分析:
在plugin处,没有太多可以描述的地方,plugin获取所有segments的信息,传到driver;由driver开始分析,用openvswitch实现;
neutron.plugins.ml2.drivers.openvswitch.mech_driver.mech_openvswitch
class OpenvswitchMechanismDriver():
def bind_port():
super(OpenvswitchMechanismDriver, self).bind_port(context)
neutron.plugins.ml2.drivers.mech_agent
class AgentMechanismDriverBase():
def bind_port(context):
# 按顺序对segment进行绑定尝试
for segment in context.segments_to_bind:
# 如果允许对当前segment可以绑定则返回
if self.try_to_bind_segment_for_agent(context, segment,
agent):
return
class SimpleAgentMechanismDriverBase():
def try_to_bind_segment_for_agent(self, context, segment, agent):
# 检查agent支持的segment
if self.check_segment_for_agent(segment, agent):
context.set_binding(segment[api.ID],
self.get_vif_type(context, agent, segment),
self.get_vif_details(context, agent, segment))
return True
else:
return False
def check_segment_for_agent(self, segment, agent):
# 获取bridge_mapping 如phynet1:br-vlan,public:br-ex
mappings = self.get_mappings(agent)
# 获取允许的network_type 为配置中tunnel_type(vxlan or gre) + vlan, flat, local
allowed_network_types = self.get_allowed_network_types(agent)
# 传来的segmnet的类型
network_type = segment[api.NETWORK_TYPE]
if network_type not in allowed_network_types:
return False
# 当segment为flat和vlan类型时
if network_type in [const.TYPE_FLAT, const.TYPE_VLAN]:
# segment的physical_network属性 如例子中的physnet1
physnet = segment[api.PHYSICAL_NETWORK]
# bridge_mapping里要有对应的physical_network对应
if not self.physnet_in_mappings(physnet, mappings):
return False
# 检查通过即返回True
return True
按顺序进行segment的检查,如果通过即绑定,那么就对segments中的属性进行排序了。排序将vlan放在最前面,即完成创建网络后,创建port则使用vlan。
那么如何对segment排序呢?
如何对segment排序
segment 数据库中有segment_index属性
在创建port获取网络segments时
neutron.plugins.ml2.driver_context
class NetworkContext():
def __init__():
self._segments = segments_db.get_network_segments(
plugin_context, network['id']) if segments is None else segments
neutron.db.segments_db
def get_network_segments(context, network_id, filter_dynamic=False):
# 获取network_segments
return get_networks_segments(
context, [network_id], filter_dynamic)[network_id]
.......
neutron.objects.network
class NetworkSegment():
@classmethod
def get_objects(cls, context, _pager=None, **kwargs):
if not _pager:
_pager = base.Pager()
if not _pager.sorts:
# 先后添加network_id 和 segment_index 的排序信息
_pager.sorts = [
(field, True) for field in ('network_id', 'segment_index')
]
return super(NetworkSegment, cls).get_objects(context, _pager,
**kwargs)
总结
在为网络添加多个segment后,虽然在页面等查看信息时为创建网络时的信息,但是在创建port时可以根据segment的排序开始选择可用的网络类型。
————————————————