记OpenStack网络参数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的排序开始选择可用的网络类型。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值