1.Neutron的介绍
Neutron 为整个 OpenStack 环境提供网络支持,包括二层交换,三层路由,负载均衡,防火墙和 *** 等。Neutron 提供了一个灵活的框架,通过配置,无论是开源还是商业软件都可以被用来实现这些功能。
Openstack的设计理念是把所有的组件当做服务来注册的。 Neutron就是网络服务。它将网络、子网、端口和路由器抽象化,之后启动的虚拟主机就可以连接到这个虚拟网络上,最大的好处是这些都可视化的在Horizon里得到了实现,部署或者改变一个SDN变得非常简单。
我们先通过如下一个简单的流程来了解客户机如何连接到网络上
- 租户创建了一个网络,比方说net
- 租户为此网络分配一个子网,比如192.168.56.0/24
- 租户启动一个客户机,并指明一个网口连接到net
- Nova通知Neutron并在net上创建一个端口,如port1
- Neutron选择并分配一个IP给port1
- 客户机通过port1就连接到了net上
2.Neutron的架构
与 OpenStack 的其他服务的设计思路一样,Neutron 也是采用分布式架构,由多个组件(子服务)共同对外提供网络服务。
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 设备。
3.flat network原理
flat network 是不带 tag 的网络,要求宿主机的物理网卡直接与 linux bridge 连接,这意味着:
每个 flat network 都会独占一个物理网卡。
上图中 eth1 桥接到 brqXXX,为云主机提供 flat 网络。
如果需要创建多个 flat network,就得准备多个物理网卡,如下图所示。
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:
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:
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个笑脸,代表网络服务的成功了!!!
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
以下为网络底层变化原理的介绍:
5.底层网络的变化
执行 brctl show,查看控制节点当前的网络结构。
Neutron 自动新建了public 对应的网桥brqc39c1348-5a,以及 dhcp 的 tap 设备tapae04cfac-d0。
另外,tapae04cfac-d0 和物理网卡 eth0都已经连接到 bridge。
此时,flat network(public)网络结构如图:
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的进程
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---b03a22b085df | public | df82f43f-97fe-41d0-bdbd- 192.168.56.0/ |
+--------------------------------------+--------+------------------------------------------------------+ [root@linux-node1 ~]# ip netns list
qdhcp-c39c1348-5a8f---b03a22b085df (id: ) ip netns list 命令列出所有的 namespace。
qdhcp-c39c1348-5a8f---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。如下图所示: