如果说openstack里面出来nova比较复杂,之前说了,因为一切源于nova,nova的复杂性在于数据在nova内部不断的api,conductor,scheduler,manager转转转,
那么剩下的部分,在openstack里和nova匹敌,一定程度上超过nova的就是neutron,甚至有人说,对于云而言,网络的软件定义能否做到让人满意直接影响到openstack
自身的前途,加上网络本身的复杂性,各种不同的实现方式,plugin,driver,manager,作为一个非网络放心,网络本身也不是强项的人来说,你需要的只有耐心。
还有一点头疼的是,neutron源于quantum,致使nova和neutron里面现在还有quantum的残留,各种deprecate的东西,也让人看着不舒服。不过从ironic到现在,
我们习惯于从wsgi服务出发(或者从neutron client出发也一样), neutron的发展很快,从i懂啊j到k版大体上相似,细节上变化很多,我装的是Juno的,看的源码是Kilo
的,囧。。。,不过这不影响,首先我们看一眼setup.cfg, neutron的entry_points估计是整个openstack中最复杂的了。。。
我们看/usr/bin/neutron-xxx ,Juno和Kilo已经不一样了,Kilo中查看脚本对应的main在哪儿呢?
console_scripts =
neutron-db-manage = neutron.db.migration.cli:main
neutron-debug = neutron.debug.shell:main
neutron-dhcp-agent = neutron.cmd.eventlet.agents.dhcp:main
neutron-hyperv-agent = neutron.cmd.eventlet.plugins.hyperv_neutron_agent:main
neutron-keepalived-state-change = neutron.cmd.keepalived_state_change:main
neutron-ibm-agent = neutron.plugins.ibm.agent.sdnve_neutron_agent:main
neutron-l3-agent = neutron.cmd.eventlet.agents.l3:main
neutron-linuxbridge-agent = neutron.plugins.linuxbridge.agent.linuxbridge_neutron_agent:main
neutron-metadata-agent = neutron.cmd.eventlet.agents.metadata:main
neutron-mlnx-agent = neutron.cmd.eventlet.plugins.mlnx_neutron_agent:main
neutron-nec-agent = neutron.cmd.eventlet.plugins.nec_neutron_agent:main
neutron-netns-cleanup = neutron.cmd.netns_cleanup:main
neutron-ns-metadata-proxy = neutron.cmd.eventlet.agents.metadata_proxy:main
neutron-nvsd-agent = neutron.plugins.oneconvergence.agent.nvsd_neutron_agent:main
neutron-openvswitch-agent = neutron.plugins.openvswitch.agent.ovs_neutron_agent:main
neutron-ovs-cleanup = neutron.cmd.ovs_cleanup:main
neutron-restproxy-agent = neutron.plugins.bigswitch.agent.restproxy_agent:main
neutron-server = neutron.cmd.eventlet.server:main #wsgi
neutron-rootwrap = oslo_rootwrap.cmd:main
neutron-rootwrap-daemon = oslo_rootwrap.cmd:daemon
neutron-usage-audit = neutron.cmd.usage_audit:main
neutron-metering-agent = neutron.cmd.eventlet.services.metering_agent:main
neutron-sriov-nic-agent = neutron.plugins.sriovnicagent.sriov_nic_agent:main
neutron-sanity-check = neutron.cmd.sanity_check:main
远超nova的script了已经。。。
wsgi服务从neutron.cmd.eventlet.server:main开始,一开始的逼格就决定了写neutron的人是个不走寻常路的
if not cfg.CONF.config_file:
sys.exit(_("ERROR: Unable to find configuration file via the default"
" search paths (~/.neutron/, ~/, /etc/neutron/, /etc/) and"
" the '--config-file' option!"))
程序就不能设置config_file,非要走默认的,我还是追到oslo_config.cfg中的CONF,发现初始化的时候会搜索默认的目录去找到config-file
neutron_api = service.serve_wsgi(service.NeutronApiService) #NeutronApiService中默认的app_name='neutron',对应到paste.ini中的入口为neutron
api_thread = pool.spawn(neutron_api.wait)
我不得不说,neutron在WSGI服务的写法上也无所不用其极,从main中最后走到:
def _run_wsgi(app_name):
app = config.load_paste_app(app_name)
if not app:
LOG.error(_LE('No known API applications configured.'))
return
server = wsgi.Server("Neutron")
server.start(app, cfg.CONF.bind_port, cfg.CONF.bind_host,
workers=cfg.CONF.api_workers)
# Dump all option values here after all options are parsed
cfg.CONF.log_opt_values(LOG, std_logging.DEBUG)
LOG.info(_LI("Neutron service started, listening on %(host)s:%(port)s"),
{'host': cfg.CONF.bind_host, 'port': cfg.CONF.bind_port})
return server
启动服务,这时来了一个neutron的rest call,我们看paste.ini文件,
neutron/api/v2/router.py中的APIRouter
看看router.py前面定义的这些global的变量,我立刻就明白了写neutron的人是个精简的python追求者,它对routes包的使用很熟,一行冗余代码都不愿意写
RESOURCES = {'network': 'networks',
'subnet': 'subnets',
'subnetpool': 'subnetpools',
'port': 'ports'}
SUB_RESOURCES = {}
COLLECTION_ACTIONS = ['index', 'create']
MEMBER_ACTIONS = ['show', 'update', 'delete']
是的,neutron提炼了collection_actions和member actions,针对它的本职工作network,subnet,subnetpool,port生成Router,
在_map_resource中controller:
controller = base.create_resource(
collection, resource, plugin, params, allow_bulk=allow_bulk,
parent=parent, allow_pagination=allow_pagination,
allow_sorting=allow_sorting)
前面提过router的使用,不知道以后nova,keystone什么的会不会也变成这种,其实读起来费劲,没必要,
但是在这里我们看到了第一个概念core plugin:
plugin = manager.NeutronManager.get_plugin()而NeutronManager中:
plugin_provider = cfg.CONF.core_plugin #一般地指定为“ml2 = neutron.plugins.ml2.plugin:Ml2Plugin”
self.plugin = self._get_plugin_instance(CORE_PLUGINS_NAMESPACE, plugin_provider)
self.service_plugins = {constants.CORE: self.plugin}
接下来还有service_plugins,service_providers,type_drivers,mechanism_drivers,extension_drivers
let's trace into the neutron, until we find all these things, we dive into the conception of the network itself, not only neutron:)
今天太晚,就先这样吧