1.Neutron的介绍
Neutron 为整个 OpenStack 环境提供网络支持,包括二层交换,三层路由,负载均衡,防火墙和 VPN 等。Neutron 提供了一个灵活的框架,通过配置,无论是开源还是商业软件都可以被用来实现这些功能。
Openstack的设计理念是把所有的组件当做服务来注册的。 Neutron就是网络服务。它将网络、子网、端口和路由器抽象化,之后启动的虚拟主机就可以连接到这个虚拟网络上,最大的好处是这些都可视化的在Horizon里得到了实现,部署或者改变一个SDN变得非常简单。
我们先通过如下一个简单的流程来了解客户机如何连接到网络上

  • 租户创建了一个网络,比方说net
  • 租户为此网络分配一个子网,比如192.168.56.0/24
  • 租户启动一个客户机,并指明一个网口连接到net
  • Nova通知Neutron并在net上创建一个端口,如port1
  • Neutron选择并分配一个IP给port1
  • 客户机通过port1就连接到了net上

OpenStack入门修炼之neutron服务(控制节点)的部署与测试(12)

2.Neutron的架构
与 OpenStack 的其他服务的设计思路一样,Neutron 也是采用分布式架构,由多个组件(子服务)共同对外提供网络服务。
OpenStack入门修炼之neutron服务(控制节点)的部署与测试(12)
Neutron 由如下组件构成:

Neutron Server 
对外提供 OpenStack 网络 API,接收请求,并调用 Plugin 处理请求。

Plugin 
处理 Neutron Server 发来的请求,维护 OpenStack 逻辑网络的状态, 并调用 Agent 处理请求。

Agent 
处理 Plugin 的请求,负责在 network provider 上真正实现各种网络功能。

network provider 
提供网络服务的虚拟或物理网络设备,例如 Linux Bridge,Open vSwitch 或者其他支持 Neutron 的物理交换机。

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 设备。

OpenStack入门修炼之neutron服务(控制节点)的部署与测试(12)

3.flat network原理
flat network 是不带 tag 的网络,要求宿主机的物理网卡直接与 linux bridge 连接,这意味着: 
每个 flat network 都会独占一个物理网卡。
OpenStack入门修炼之neutron服务(控制节点)的部署与测试(12)
上图中 eth1 桥接到 brqXXX,为云主机提供 flat 网络。 
如果需要创建多个 flat network,就得准备多个物理网卡,如下图所示。
OpenStack入门修炼之neutron服务(控制节点)的部署与测试(12)

4.neutron服务的部署与测试

(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

OpenStack入门修炼之neutron服务(控制节点)的部署与测试(12)
出现图中的3个笑脸,代表网络服务的成功了!!!

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
以下为网络底层变化原理的介绍:
5.底层网络的变化
执行 brctl show,查看控制节点当前的网络结构。
OpenStack入门修炼之neutron服务(控制节点)的部署与测试(12)
Neutron 自动新建了public 对应的网桥brqc39c1348-5a,以及 dhcp 的 tap 设备tapae04cfac-d0。 
另外,tapae04cfac-d0 和物理网卡 eth0都已经连接到 bridge。
此时,flat network(public)网络结构如图:
OpenStack入门修炼之neutron服务(控制节点)的部署与测试(12)

6.DHCP服务解析

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的进程
OpenStack入门修炼之neutron服务(控制节点)的部署与测试(12)

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。如下图所示:
OpenStack入门修炼之neutron服务(控制节点)的部署与测试(12)