前面提到在core plugin中实际执行时和type manager, mechanism manager相关,而type manager和mechanism manager都有对应的driver,manager的操作,最后转化成为driver的操作。
先来看mechanism_manager,一般地自己配的时候配成openvswitch,像:
mechanism_drivers =openvswitch
在setup.cfg中:
openvswitch = neutron.plugins.ml2.drivers.mech_openvswitch:OpenvswitchMechanismDriver
OpenvswitchMechanismDriver继承自AgentMechanismDriverBase, 继承自neutron.plugins.ml2.driver_api.MechanismDriver
有没有发现,openvswitch那么多复杂的操作,在MechanismDriver中都是空的函数,操作在哪儿呢?我们来理一理:
1. mechanism manager中的操作,无论是create network,update port等等,做了什么事情,两部分:
a. 操作数据库
对于ML2Plugin来说涉及到的数据库的类有:
db_base_plugin_v2.NeutronDbPluginV2,
dvr_mac_db.DVRDbMixin,
external_net_db.External_net_db_mixin,
sg_db_rpc.SecurityGroupServerRpcMixin,
agentschedulers_db.DhcpAgentSchedulerDbMixin,
addr_pair_db.AllowedAddressPairsMixin,
extradhcpopt_db.ExtraDhcpOptMixin
以create_network为例,在NeutronDbPluginV2中
with context.session.begin(subtransactions=True):
args = {'tenant_id': tenant_id,
'id': n.get('id') or uuidutils.generate_uuid(),
'name': n['name'],
'admin_state_up': n['admin_state_up'],
'mtu': n.get('mtu', constants.DEFAULT_NETWORK_MTU),
'shared': n['shared'],
'vlan_transparent': n.get('vlan_transparent', False),
'status': n.get('status', constants.NET_STATUS_ACTIVE)}
network = models_v2.Network(**args)
context.session.add(network)
我trace几个函数,是想说明数据库的操作和实际的网络结构没有任何关系
b. mechanism drivers 实际操作改变网络数据
实际操作一般地,xxxx_precommit 和 xxxx_postcommit 在各个ml2的driver中,这个也就是“大二层的由来”,有了ml2,我们可以让mechanism drivers成为一个list,同时支持
多个driver,而不是原来的单一使用一个driver, 看ibm, freescale等的driver实现,都在xxxx_precommit 和 xxxx_postcommit中有对应的实现(不一定两个都实现了)
如果我们想实现自己的mechanism driver,就在ml2/drivers中,重载这些方法即可
neutron/plugins下面的结构是不是看起来比较奇怪,有ibm,思科的plugin,同时ml2/drivers下面又有他们,原因也在于ml2出现后的过度阶段,现在ml2发展的比较好,
以后应该都在ml2/drivers中
那么为什么openvswitch没有这些的具体实现,都是pass呢,因为openvswitch的agent帮我们做了工作,回想neutron一堆一堆的脚本,openstack之最,其中有
/usr/bin/neutron-openvswitch-agent启动脚本执行 neutron.plugins.openvswitch.agent.ovs_neutron_agent:main, 在main中:
1. agent_config = create_agent_config_map(cfg.CONF) #来看看我们熟悉的配置变量
integ_br=config.OVS.integration_bridge,
tun_br=config.OVS.tunnel_bridge,
local_ip=config.OVS.local_ip,
bridge_mappings=bridge_mappings,
polling_interval=config.AGENT.polling_interval,
minimize_polling=config.AGENT.minimize_polling,
tunnel_types=config.AGENT.tunnel_types,
在neutron.plugins.openvswitch.common.config中
cfg.CONF.register_opts(ovs_opts, "OVS")
cfg.CONF.register_opts(agent_opts, "AGENT")
2. agent = OVSNeutronAgent(**agent_config)
创建一个OVSDVRNeutronAgent
如果你trace一下:
self.dvr_agent.setup_dvr_flows_on_integ_br()
self.dvr_agent.setup_dvr_flows_on_tun_br()
self.dvr_agent.setup_dvr_flows_on_phys_br()
self.dvr_agent.setup_dvr_mac_flows_on_all_brs()
你会看到openvswitch的命令行操作在这里, 在neuron/agent/ovs_lib中,你要是想修改或是添加openvswitch的操作,这里是合适的
setup_rpc,设置agent的消息监听
agent收到不同的消息,network delete等,在VSNeutronAgent中处理
3. agent.daemon_loop() #是的,关键在这里
with polling.get_polling_manager(
self.minimize_polling,
self.ovsdb_monitor_respawn_interval) as pm:
self.rpc_loop(polling_manager=pm)
polling数据库, port信息发生变化,执行相应的动作,可以trace rpc_loop这个函数
为什么ovs-vsctl, ovs-ofl之类的没有所谓的create network呢:), 因为network是个抽象的概念,我们说network,实际上
是tunnel,port等组成的,这也就是为什么在setup_rpc中没有对NETWORK.CREATE的topic的监听,因为只有一个network,而不创建
port,tunnel或者securitygroup等的时候,是没有意义的,网络本身没有变化,而port等都是有network_id的。
ps,router是三层的,不是ml2的东西
我实在不是网络的爱好者,当然网络很有意思,学习neutron只因为neutron surround you,你无法在集群中离开neutron去谈cloud
mark两篇文章:
此人将plugin说的比较清楚,mark
http://blog.youkuaiyun.com/zhengleiguo/article/details/28408899
这篇很长的文章看的更深一些
http://blog.youkuaiyun.com/canxinghen/article/details/39395957