neutron的代码一坨,越来越膨胀,新手看起来可能分不清楚东西,而且看了就忘记了,我也一样,经常忘记,定位问题时又得回头看,这次决定记录一下。上次说了neutron的几大概念,这次说一说代码,看代码要分析代码是怎么运行的,抓住最重要部分就行了。具体运行就是看执行流,就是几个进程,几个线程和协程,这些执行流分部在几个节点,节点之间怎么传递消息的,同一节点上执行流怎么同步的。执行流的入口代码在哪里,谁创建了谁,回收了谁,谁打开了那个socket和文件。一句话就是先搞清楚有几个参与主体,主体参与的期限,主体之间如何交互,主体内部的逻辑可以先不追究,搞清楚这些对这一坨代码就大体有一个了解了。
主体
我们先用ps命令分析一个neutron相关的进程
neutron server有如下进程,有neutron-server,rpc worker,periodic worker,一个neutron-server是其它进程的父进程。这儿先当作一个整体,不再区分进程之间的不同,留到专门写neutron-server的文章分析。
代码语言:javascript复制neutron 355437 1 2 Sep15 ? 03:36:32 /usr/bin/python2 /usr/bin/neutron-server --config-file /usr/share/neutron/neutron-dist.conf --config-dir /usr/share/neutron/server --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugin.ini --config-file /etc/neutron/l2gateway_agent.ini --config-file /etc/neutron/plugins/ml2/ml2_conf_genericswitch.ini --config-dir /etc/neutron/conf.d/common --config-dir /etc/neutron/conf.d/neutron-server --log-file /var/log/neutron/server.log
neutron 357148 355437 1 Sep15 ? 01:40:42 /usr/bin/python2 /usr/bin/neutron-server --config-file /usr/share/neutron/neutron-dist.conf --config-dir /usr/share/neutron/server --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugin.ini --config-file /etc/neutron/l2gateway_agent.ini --config-file /etc/neutron/plugins/ml2/ml2_conf_genericswitch.ini --config-dir /etc/neutron/conf.d/common --config-dir /etc/neutron/conf.d/neutron-server --log-file /var/log/neutron/server.log
neutron 357155 355437 74 Sep15 ? 4-11:37:20 neutron-server: rpc worker (/usr/bin/python2 /usr/bin/neutron-server --config-file /usr/share/neutron/neutron-dist.conf --config-dir /usr/share/neutron/server --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugin.ini --config-file /etc/neutron/l2gateway_agent.ini --config-file /etc/neutron/plugins/ml2/ml2_conf_genericswitch.ini --config-dir /etc/neutron/conf.d/common --config-dir /etc/neutron/conf.d/neutron-server --log-file /var/log/neutron/server.log)
neutron 357260 355437 20 Sep15 ? 1-05:34:18 neutron-server: periodic worker (/usr/bin/python2 /usr/bin/neutron-server --config-file /usr/share/neutron/neutron-dist.conf --config-dir /usr/share/neutron/server --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugin.ini --config-file /etc/neutron/l2gateway_agent.ini --config-file /etc/neutron/plugins/ml2/ml2_conf_genericswitch.ini --config-dir /etc/neutron/conf.d/common --config-dir /etc/neutron/conf.d/neutron-server --log-file /var/log/neutron/server.log)
l3 agent相关的进程
代码语言:javascript复制neutron 3174493 1 4 Jun19 ? 4-08:31:48 /usr/bin/python2 /usr/bin/neutron-l3-agent --config-file /usr/share/neutron/neutron-dist.conf --config-dir /usr/share/neutron/l3_agent --config-file /etc/neutron/neutron.conf --config-dir /etc/neutron/conf.d/common --config-dir /etc/neutron/conf.d/neutron-l3-agent --log-file /var/log/neutron/l3-agent.log
root 3178242 1 0 Jun19 ? 00:00:00 /usr/bin/python2 /bin/privsep-helper --config-file /usr/share/neutron/neutron-dist.conf --config-file /etc/neutron/neutron.conf --config-dir /etc/neutron/conf.d/neutron-l3-agent --privsep_context neutron.privileged.default --privsep_sock_path /tmp/tmpSv6saY/privsep.sock
root 3178309 3174493 0 Jun19 ? 00:00:00 sudo neutron-rootwrap-daemon /etc/neutron/rootwrap.conf
ovs agent相关的进程
代码语言:javascript复制neutron 565145 1 11 Jul03 ? 8-20:52:46 /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
root 566168 1 0 Jul03 ? 00:00:00 /usr/bin/python2 /bin/privsep-helper --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/neutron-openvswitch-agent --privsep_context neutron.privileged.default --privsep_sock_path /tmp/tmpa5rVwk/privsep.sock
root 566274 565145 0 Jul03 ? 00:00:00 sudo neutron-rootwrap-daemon /etc/neutron/rootwrap.conf
neutron 2000737 565145 0 Aug09 ? 00:01:28 ovsdb-client monitor tcp:127.0.0.1:6640 Interface name,ofport,external_ids --format=json
交互
我们主要分析一下neutron-server,l3-agent和ovs-agent之间交互的代码。
neutron/api/rpc/有目录agentnofifiers和handlers,agentnofifiers下l3_rpc_agent_api.py文件,里面有L3AgentNotifyAPI。handlers目录下有l3_rpc.py,里面有L3RpcCallback。neutron/agent/l3/agent.py中的L3PluginApi,L3NATAgent中init中self.plugin_rpc = L3PluginApi(topics.L3PLUGIN, host),说明PluginApi是agent主动向server发送rpc消息的,server侧用L3RpcCallback用响应。neutron/agent/l3_agent.py中server = neutron_service.Service.create()有一个参数topic=topics.L3_AGENT,而L3AgentNotifyAPI的也有一个参数topic=topics.L3_AGENT,这两个把两者关系到一起,server执行L3AgentNotifyAPI.routers_updated,l3 agent侧就执行L3NATAgent.routers_updated。
ovs agent和l3 agent就有点不同了,相同的地方是server都有AgentNotifierApi通知agent和RpcCallbacks处理agent的rpc请求。不同的是ovs agent通知server的PluginApi被CacheBackedPluginApi继承,CacheBackedPluginApi中用到了RemoteResourceCache和RemoteResourceWatcher,就是server push或者agent pull过来的消息,agent先做了cache,然后在agent进程内registry.notify,当然首先是agent启动时registry.subscribe过,好处是下次不用从server请求了,直接上cache中取。
openstack引进OVO(Oslo Versioned Objects)后支持rolling upgrade,就是不断升级,升级就存在先升级server还是先升级agent的问题,两者之间通信,一旦升级了一方,另一方发送过来的rpc就有可能不能正常处理,OVO给重要的资源加了版本号,rpc中带上了版本号,另一方根据版本号来做兼容处理。agent和server之间又分为push和pull,push就是server主动发起通知agent,如server用类ResourcesPushRpcApi通知agent,agent用类ResourcesPushRpcCallback做处理,pull就是agent主动从server请求数据,如agent的一个extension用类ResourcesPullRpcApi主动请求数据,server用类ResourcesPullRpcCallback做处理。其实server之间也是要同步数据的,一个节点上的server用类ResourcesPushToServersRpcApi通知其它节点上的server,其它server用类ResourcesPushToServerRpcCallback做处理。这此接口相比get_dvr_mac和update_device_up抽象了很多,参数用到了resource type和resouce id,neutron的resource最主要的就是port和neutron等。
上面说的用于进程之间,如server和agent之间或者多个server之间。registry.notify和registry.subscribe用于一个进程之内,如server的一个plugin要感知核心资源port的变化,那就需要subscribe port的变化,port有变化了,server会notify,这样plugin就实时感知到了port的变化,不需要poll频繁查询数据库。
总结
没有时间专门看代码,基本就是定位问题时顺便看一下,看到什么觉得重要就记录一下,希望能有时间这个系列能再写二篇server和agent,把neutron的架构补全。