Neutron 为整个 OpenStack 环境提供网络支持,包括二层交换,三层路由,负载均衡,防火墙和 *** 等。Neutron 提供了一个灵活的框架,经过配置,不管是开源仍是商业软件均可以被用来实现这些功能。
Openstack的设计理念是把全部的组件当作服务来注册的。 Neutron就是网络服务。它将网络、子网、端口和路由器抽象化,以后启动的虚拟主机就能够链接到这个虚拟网络上,最大的好处是这些均可视化的在Horizon里获得了实现,部署或者改变一个SDN变得很是简单。
咱们先经过以下一个简单的流程来了解客户机如何链接到网络上node
- 租户建立了一个网络,比方说net
- 租户为此网络分配一个子网,好比192.168.56.0/24
- 租户启动一个客户机,并指明一个网口链接到net
- Nova通知Neutron并在net上建立一个端口,如port1
- Neutron选择并分配一个IP给port1
- 客户机经过port1就链接到了net上

与 OpenStack 的其余服务的设计思路同样,Neutron 也是采用分布式架构,由多个组件(子服务)共同对外提供网络服务。mysql

Neutron 由以下组件构成:linux
Neutron Server :对外提供 OpenStack 网络 API,接收请求,并调用 Plugin 处理请求。sql
Plugin:处理 Neutron Server 发来的请求,维护 OpenStack 逻辑网络的状态, 并调用 Agent 处理请求。数据库
Agent :处理 Plugin 的请求,负责在 network provider 上真正实现各类网络功能。vim
network provider :提供网络服务的虚拟或物理网络设备,例如 Linux Bridge,Open vSwitch 或者其余支持 Neutron 的物理交换机。api
Queue :Neutron Server,Plugin 和 Agent 之间经过 Messaging Queue 通讯和调用。安全
Database :存放 OpenStack 的网络状态信息,包括 Network, Subnet, Port, Router 等。网络
案例理解内容:
以建立一个 VLAN100 的 network 为例,假设 network provider 是 linux bridge, 流程以下:架构
①Neutron Server 接收到建立 network 的请求,经过 Message Queue(RabbitMQ)通知已注册的 Linux Bridge Plugin。
②Plugin 将要建立的 network 的信息(例如名称、VLAN ID等)保存到数据库中,并经过 Message Queue 通知运行在各节点上的 Agent。
③Agent 收到消息后会在节点上的物理网卡(好比 eth0)上建立 VLAN 设备(好比 eth0.100),并建立 bridge (好比 brqXXX) 桥接 VLAN 设备。

flat network 是不带 tag 的网络,要求宿主机的物理网卡直接与 linux bridge 链接,这意味着:
每一个 flat network 都会独占一个物理网卡。

上图中 eth1 桥接到 brqXXX,为云主机提供 flat 网络。
若是须要建立多个 flat network,就得准备多个物理网卡,以下图所示。

(1)编辑配置neutron.conf
编辑/etc/neutron/neutron.conf 文件并完成以下操做:
在 [database] 部分,配置数据库访问:
[database]
...
connection = mysql+pymysql://neutron:neutron@192.168.56.11/neutron
在[DEFAULT]部分,启用ML2插件并禁用其余插件:
[DEFAULT]
...
core_plugin = ml2
service_plugins = 在 “[DEFAULT]” 和 “[keystone_authtoken]” 部分,配置认证服务访问:
[DEFAULT]
...
auth_strategy = keystone
[keystone_authtoken]
...
auth_uri = http://192.168.56.11:5000
auth_url = http://192.168.56.11:35357
memcached_servers = 192.168.56.11:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = neutron
password = neutron
在[DEFAULT]部分,配置RabbitMQ消息队列访问权限:
[DEFAULT]
...
transport_url = rabbit://openstack:openstack@192.168.56.11
在[DEFAULT]和[nova]部分,配置网络服务来通知计算节点的网络拓扑变化:
[DEFAULT]
...
notify_nova_on_port_status_changes = True
notify_nova_on_port_data_changes = True
[nova]
...
auth_url = http://192.168.56.11:35357
auth_type = password
project_domain_name = default
user_domain_name = default
region_name = RegionOne
project_name = service
username = nova
password = nova
在 [oslo_concurrency] 部分,配置锁路径:
[oslo_concurrency]
...
lock_path = /var/lib/neutron/tmp
查看neutron全部配置项:
[root@linux-node1 ~]# grep "^[a-z]" /etc/neutron/neutron.conf
auth_strategy = keystone
core_plugin = ml2
service_plugins =
notify_nova_on_port_status_changes = true
notify_nova_on_port_data_changes = true
transport_url = rabbit://openstack:openstack@192.168.56.11
connection = mysql+pymysql://neutron:neutron@192.168.56.11/neutron
auth_uri = http://192.168.56.11:5000
auth_url = http://192.168.56.11:35357
memcached_servers = 192.168.56.11:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = neutron
password = neutron
auth_url = http://192.168.56.11:35357
auth_type = password
project_domain_name = default
user_domain_name = default
region_name = RegionOne
project_name = service
username = nova
password = nova
lock_path = /var/lib/neutron/tmp
(2)配置 Modular Layer 2 (ML2) 插件
编辑/etc/neutron/plugins/ml2/ml2_conf.ini文件并完成如下操做:
在[ml2]部分,启用flat和VLAN网络:
[ml2]
...
type_drivers = flat,vlan
在[ml2]部分,禁用私有网络:
[ml2]
...
tenant_network_types = 在[ml2]部分,启用Linuxbridge机制:
[ml2]
...
mechanism_drivers = linuxbridge
在[ml2] 部分,启用端口安全扩展驱动:
[ml2]
...
extension_drivers = port_security
在[ml2_type_flat]部分,配置公共虚拟网络为flat网络:
[ml2_type_flat]
...
flat_networks = public <==指定普通用户建立的网络类型为 public
在 [securitygroup]部分,启用 ipset 增长安全组的方便性:
[securitygroup]
...
enable_ipset = True
(3)配置Linuxbridge代理
编辑/etc/neutron/plugins/ml2/linuxbridge_agent.ini文件而且完成如下操做:
在[linux_bridge]部分,将公共虚拟网络和公共物理网络接口对应起来:
[linux_bridge]
physical_interface_mappings = public:eth0 <==指明 public 网络与物理网卡的对应关系
在[vxlan]部分,禁止VXLAN覆盖网络:
[vxlan]
enable_vxlan = False
在 [securitygroup]部分,启用安全组并配置 Linux 桥接 iptables 防火墙驱动:
[securitygroup]
...
enable_security_group = True
firewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver
tips:理解此处的public与 eth0 的关系
public是 flat 网络的标识,在建立 flat 时须要指定 label(标识)。label 的名字能够是任意字符串,这里建立的标识为public。只要确保各个节点 ml2_conf.ini 中的 label 命名一致就能够了。
各个节点中 label 与物理网卡的对应关系可能不同。这是由于每一个节点可使用不一样的物理网卡将云主机链接到 flat network。
支持多个flat网络
若是要建立多个 flat 网络,须要定义多个 label,用逗号隔开,固然也须要用到多个物理网卡,以下所示:
[ml2_type_flat]
flat_networks = flat1,flat2
[linux_bridge]
physical_interface_mappings = flat1:eth1,flat2:eth2
(4)配置DHCP代理
编辑/etc/neutron/dhcp_agent.ini文件并完成下面的操做:
在[DEFAULT]部分,配置Linuxbridge驱动接口,DHCP驱动并启用隔离元数据,这样在公共网络上的实例就能够经过网络来访问元数据
[DEFAULT]
...
interface_driver = neutron.agent.linux.interface.BridgeInterfaceDriver <==使用 linux bridge 链接 DHCP namespace interface。
dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq <==使用 dnsmasq 实现 DHCP。
enable_isolated_metadata = True
当建立 network 并在 subnet 上 enable DHCP 时,网络节点上的 DHCP agent 会启动一个 dnsmasq 进程为该 network 提供 DHCP 服务。
(5)配置元数据代理
编辑/etc/neutron/metadata_agent.ini文件并完成如下操做:
在[DEFAULT] 部分,配置元数据主机以及共享密码:
[DEFAULT]
...
nova_metadata_ip = 192.168.56.11
metadata_proxy_shared_secret = nobody
(6)配置计算服务来使用网络服务
编辑/etc/nova/nova.conf文件并完成如下操做:
[root@linux-node1 ~]# vim /etc/nova/nova.conf
在[neutron]部分,配置访问参数,启用元数据代理并设置密码:
[neutron]
...
url = http://192.168.56.11:9696
auth_url = http://192.168.56.11:35357
auth_type = password
project_domain_name = default
user_domain_name = default
region_name = RegionOne
project_name = service
username = neutron
password = neutron
service_metadata_proxy = True
metadata_proxy_shared_secret = nobody
(7)完成安装
①网络服务初始化脚本须要一个超连接 /etc/neutron/plugin.ini指向ML2插件配置文件/etc/neutron/plugins/ml2/ml2_conf.ini。若是超连接不存在,使用下面的命令建立它:
[root@linux-node1 ~]# ln -s /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugin.ini
②同步数据库
[root@linux-node1 ~]# su -s /bin/sh -c "neutron-db-manage --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head" neutron
③重启计算API服务
[root@linux-node1 ~]# systemctl restart openstack-nova-api.service
④当系统启动时,启动Networking服务并配置它启动
[root@linux-node1 ~]# systemctl enable neutron-server.service \
neutron-linuxbridge-agent.service neutron-dhcp-agent.service \
neutron-metadata-agent.service
[root@linux-node1 ~]# systemctl start neutron-server.service \
neutron-linuxbridge-agent.service neutron-dhcp-agent.service \
neutron-metadata-agent.service
(8)建立“neutron”服务实体以及API端点
[root@linux-node1 ~]# openstack service create --name neutron \
--description "OpenStack Networking" network
[root@linux-node1 ~]# openstack endpoint create --region RegionOne \
network public http://192.168.56.11:9696
[root@linux-node1 ~]# openstack endpoint create --region RegionOne \
network internal http://192.168.56.11:9696
[root@linux-node1 ~]# openstack endpoint create --region RegionOne \
network admin http://192.168.56.11:9696
[root@linux-node1 ~]# neutron agent-list

出现图中的3个笑脸,表明网络服务的成功了!!!
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
如下为网络底层变化原理的介绍:
执行 brctl show,查看控制节点当前的网络结构。

Neutron 自动新建了public 对应的网桥brqc39c1348-5a,以及 dhcp 的 tap 设备tapae04cfac-d0。
另外,tapae04cfac-d0 和物理网卡 eth0都已经链接到 bridge。
此时,flat network(public)网络结构如图:

DHCP agent 的配置文件位于 /etc/neutron/dhcp_agent.ini。
dhcp_driver
使用 dnsmasq 实现 DHCP。
interface_driver
使用 linux bridge 链接 DHCP namespace interface。
当建立 network 并在 subnet 上 enable DHCP 时,网络节点上的 DHCP agent 会启动一个 dnsmasq 进程为该 network 提供 DHCP 服务。
dnsmasq 是一个提供 DHCP 和 DNS 服务的开源软件。
dnsmasq 与 network 是一对一关系,一个 dnsmasq 进程能够为同一 netowrk 中全部 enable 了 DHCP 的 subnet 提供服务。
网络建立完成,咱们能够在linux-node1上进行查看dnsmasq的进程

dnsmasq 重要的启动参数:
--dhcp-hostsfile
存放 DHCP host 信息的文件,这里的 host 在咱们这里实际上就是 instance。
dnsmasq 从该文件获取 host 的 IP 与 MAC 的对应关系。
每一个 host 对应一个条目,信息来源于 Neutron 数据库。
--interface
指定提供 DHCP 服务的网络接口。
dnsmasq 会在该网络接口上监听云主机的 DHCP 请求
思考:
从上面能够看到DHCP 的网络接口是tapae04cfac-d0,并不是是ns-ae04cfac-d0,这是怎么一回事?
Neutron 经过 dnsmasq 提供 DHCP 服务,而 dnsmasq 如何独立的为每一个 network 服务呢?
答案:是经过 Linux Network Namespace 隔离
每一个 dnsmasq 进程都位于独立的 namespace, 命名为
qdhcp-<\network id>
[root@linux-node1 ~]# neutron net-list
+--------------------------------------+--------+------------------------------------------------------+
| id | name | subnets |
+--------------------------------------+--------+------------------------------------------------------+
| c39c1348-5a8f-4291-9772-b03a22b085df | public | df82f43f-97fe-41d0-bdbd-933565102598 192.168.56.0/24 |
+--------------------------------------+--------+------------------------------------------------------+
[root@linux-node1 ~]# ip netns list
qdhcp-c39c1348-5a8f-4291-9772-b03a22b085df (id: 0)
ip netns list 命令列出全部的 namespace。
qdhcp-c39c1348-5a8f-4291-9772-b03a22b085df就是public的namespace
其实,宿主机自己也有一个 namespace,叫 root namespace,拥有全部物理和虚拟 interface device。
物理 interface 只能位于 root namespace。
新建立的 namespace 默认只有一个 loopback device。
管理员能够将虚拟 interface,例如 bridge,tap 等设备添加到某个 namespace。
对于 public的 DHCP 设备tapae04cfac-d0,须要将其放到 namespaceqdhcp-c39c1348-5a8f-4291-9772-b03a22b085df 中,但这样会带来一个问题:
tapae04cfac-d0 将没法直接与 root namespace 中的 bridge 设备brqc39c1348-5a链接。
Neutron 使用 veth pair 解决了这个问题。
veth pair 是一种成对出现的特殊网络设备,它们象一根虚拟的网线,可用于链接两个 namespace。向 veth pair 一端输入数据,在另外一端就能读到此数据。
tapae04cfac-d0与ns-ae04cfac-d0 就是一对 veth pair,它们将 qdhcp-c39c1348-5a8f-4291-9772-b03a22b085df 链接到brqc39c1348-5a。以下图所示:
