neutron核心架构
neutron组件为用户提供了云平台中软件定义网络的功能,它负责管理虚拟网络组件,包括Networks、Switches、Subnets和Routers,同时提供高级网络服务,如Load Balance、Firewall和VPN。Neutron中不同的组件及其部署的节点如下图所示:
从中我们可以看出Neutron中的组件可以分为4种
- Server:Neutron Server运行在控制节点上,外暴露一组操作逻辑网络的API,将这些逻辑操作转化为底层物理或虚拟交换机,实际的配置工作则由Plugin完成;
- Plugins: 负责管理Agents,Neutron Plugin继承自neutron/neutron_plugin_base.py,代码如下图所示,实现其中定义的CRUD操作。在Neutron的早期版本种有很多针对各种底层交换机实现的Plugins,比如Linux Bridge Plugin、Open vSwitch Plugin等,如今的Neutron版本中引入了ML2 Plugin,各个交换机相关的代码转移到ML2 Plugin下一级的Mechanism Drivers中。ML2 Plugin的Driver分为两种:Type Drivers和Mechanism Drivers。Type Drivers定义了Neutron的网络类型,Neutron目前支持的网络类型包括Local网络(类似VirtualBox中的Host-only网络),Flat网络(所有虚机都处在同一个二层网络中),VLAN网络(网络拓扑结构和Flat模式类似,但是每个玩网络都带有VLAN ID),VXLAN网络(可以使用VxLAN协议在计算节点之间建立Overlay网络),GRE网络(使用GRE协议在计算节点之间建立Overlay网络)。Mechanism Drivers可以对接各种二层网络技术和物理交换设备。Neutron支持在一个虚拟网络中同时使用多种Type Driver和Mechanism Drivers。
- Agents:向虚拟机提供二层和三层的网络联通,处理逻辑网络和物理网络之间的转换、同时也提供一些拓展服务。Agents包括提供二层网络联通服务的Layer 2 agents,比如Linux Bridge和OVS;提供三层IP和路由服务的Layer 3 agents,比如L3和DHCP;提供一些杂项服务的Miscellaneous agents,比如Metadata;
- Service:提供高级网络服务,包括提供三层路由功能的Routing Service;提供VPN功能的VPNaaS;提供负载均衡器功能的LBaas,一般是基于HAProxy实现;提供防火墙服务的FWaas,一般是基于iptables实现。
Neutron源码目录详解
上图所示为neutron源码的目录结构,这里主要讲解一下plugins、agent,里面包含了neutron中plugins和agent实现源码。plugins目录如下所示,在Neutron中,实现一个插件包括两部分内容,一部分是与数据库db打交道的,称为plugin,另一部分是调用具体的网络设备真正干活的,称为agent。与db交互的plugin在功能上有很多重复,所以在代码上有很多重复,因此ml2目录下提供了一个与数据库交互的公共plugin,即plugins/ml2/db.py,部分代码截图如下所示
ml目录下还有一部分代码能够实现支持多种plugin(即既能使用Linux bridge,又能使用OpenvSwitch),这部分功能通过plugins/ml2下的linuxbridge和openvswitch来实现,以linuxbridge为例,其目录下下mech_linuxbridge.py代码中可以将agent类型agent_type和vif_type关联,这样vif_type就可以直接通过扩展API进行设置了,如下图所示
ML2目录中还有一部分代码的作用是支持不同的网络拓扑,如Flat、VLAN、GRE等,代码在ml2/drivers下的type_*.py中。
agent在neutron的代码目录如下所示,这部分代码主要定义关于逻辑网络和物理网络处理及相关转化的具体操作,例如agent/l2/l2_agent_extensions_manager.py就定义了保持和删除端口的一些操作,如下图所示。
Neutron启动分析
主启动文件如下:
其中调用的neutron/cmd/eventlet/server的代码如下所示,这里启动了neutron/server/wsgi_eventlet.py,代码则如下所示
# neutron/cmd/eventlet/server/__init__.py
def main():
# 启动服务,读取配置文件并调用 _main_neutron_server
server.boot_server(_main_neutron_server)
def _main_neutron_server():
# neutron有两种api方式,一种是pecan一种是原来的legacy
if cfg.CONF.web_framework == 'legacy':
# 这里我们主要