1.neutron-openvswitch-agent启动脚本定义在/usr/bin/neutron-openvswitch-agent中,它调用了ovs_neutron_agent中的main()方法。
启动命令:
usr/bin/python2 /usr/bin/neutron-openvswitch-agent --config-file /usr/share/neutron/neutron-dist.conf --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2/openvswitch_agent.ini --config-dir /etc/neutron/conf.d/common --config-dir /etc/neutron/conf.d/neutron-openvswitch-agent --log-file /var/log/neutron/openvswitch-agent.log
2.该方法又调用了ovs agent中的main()方法。
neutron/cmd/eventlet/plugins/ovs_neutron_agent.py
def main():
agent_main.main()
3.根据of_interface的配置,包含ovs-ofctl和native两种方式,执行具体的启动流程。
neutron/plugins/ml2/drivers/openvswitch/agent/main.py
def main():
common_config.init(sys.argv[1:])
driver_name = cfg.CONF.OVS.of_interface
mod_name = _main_modules[driver_name]
mod = importutils.import_module(mod_name)
mod.init_config()
common_config.setup_logging()
profiler.setup("neutron-ovs-agent", cfg.CONF.host)
mod.main()
4.根据neutron.conf中的默认配置,执行native中的mian()方法。
neutron/plugins/ml2/drivers/openvswitch/agent/openflow/native/main.py
def main():
app_manager.AppManager.run_apps([
'neutron.plugins.ml2.drivers.openvswitch.agent.'
'openflow.native.ovs_ryuapp',
])
5.通过Ryu启动OVS应用,调用ovs agent的main()方法。
neutron/plugins/ml2/drivers/openvswitch/agent/openflow/native/ovs_ryuapp.py
def agent_main_wrapper(bridge_classes):
try:
ovs_agent.main(bridge_classes)
except Exception:
with excutils.save_and_reraise_exception():
LOG.exception("Agent main thread died of an exception")
finally:
# The following call terminates Ryu's AppManager.run_apps(),
# which is needed for clean shutdown of an agent process.
# The close() call must be called in another thread, otherwise
# it suicides and ends prematurely.
hub.spawn(app_manager.AppManager.get_instance().close)
class OVSNeutronAgentRyuApp(app_manager.RyuApp):
OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
def start(self):
# Start Ryu event loop thread
super(OVSNeutronAgentRyuApp, self).start()
def _make_br_cls(br_cls):
return functools.partial(br_cls, ryu_app=self)
# Start agent main loop thread
bridge_classes = {
'br_int': _make_br_cls(br_int.OVSIntegrationBridge),
'br_phys': _make_br_cls(br_phys.OVSPhysicalBridge),
'br_tun': _make_br_cls(br_tun.OVSTunnelBridge),
}
return hub.spawn(agent_main_wrapper, bridge_classes, raise_error=True)
6.加载配置文件、插件,校验配置项,创建ovs agent实例,daemon_loop()方法定时更新端口信息。
neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py
def main(bridge_classes):
prepare_xen_compute()
ovs_capabilities.register()
ext_manager.register_opts(cfg.CONF)
ext_mgr = ext_manager.L2AgentExtensionsManager(cfg.CONF)
# now that all extensions registered their options, we can log them
n_utils.log_opt_values(LOG)
validate_tunnel_config(cfg.CONF.AGENT.tunnel_types, cfg.CONF.OVS.local_ip)
try:
agent = OVSNeutronAgent(bridge_classes, ext_mgr, cfg.CONF)
capabilities.notify_init_event(n_const.AGENT_TYPE_OVS, agent)
except (RuntimeError, ValueError) as e:
LOG.error("%s Agent terminated!", e)
sys.exit(1)
agent.daemon_loop()
OVSNeutronAgent的初始化方法中主要创建br-int、br-tun以及vlan和flat网络模式下与物理网络相关联的br-phys网桥,启动rpc服务,创建定时任务,定时向neutron server更新ovs agent的状态。
def setup_integration_br(self):
'''Setup the integration bridge.
'''
# Ensure the integration bridge is created.
# ovs_lib.OVSBridge.create() will run
# ovs-vsctl -- --may-exist add-br BRIDGE_NAME
# which does nothing if bridge already exists.
self.int_br.create()
self.int_br.set_secure_mode()
self.int_br.setup_controllers(self.conf)
if self.conf.AGENT.drop_flows_on_start:
# Delete the patch port between br-int and b