1. 1.7 OpenStack网络服务Neutron
上一章我们讲到Nova服务提供了OpenStack平台计算资源池,实现了计算即服务。那么仅仅有一台孤立的云主机是无法正常使用的,我们需要把它接入网络,才能正常对外提供服务。
1.1.1. Neutron概述
OpenStack Networking Services(Neutron),OpenStack 网络服务,OpenStack核心项目之一,由早期的nova-network独立成一个子项目后演变而来,它为OpenStack提供了云计算环境下的虚拟网络功能。
在OpenStack世界中,网络组件最初叫nova-network,nova-network实现简单,直接采用基于Linux内核的Linux网桥。由于少了很多层抽象,所以比较简单稳定算。但是它的不足之处是支持的插件少(只支持Linux网桥),支持的网络拓扑少(只支持flat, vlan)。
为了支持更多的插件,支持更多的网络拓扑,于是有了quantum工程。quantum插件不仅支持Linux网桥,也支持OpenvSwitch,以及一些SDN的插件和其他商业公司的插件。在网络拓扑上,除了支持flat,vlan外,还支持gre, vxlan。quantum因为和一家公司的名称冲突,于是,改名为neutron。
- Neutron Server
这一部分包含守护进程neutron-server和各种插件neutron-*-plugin。neutron-server提供API接口,并把对API的调用请求传给已经配置好的插件进行后续处理。插件需要访问数据库来维护各种配置数据和对应关系,例如路由器、网络、子网、端口、浮动IP、安全组等等。
- ML2(Module Layer2)plugin
上述整体框架中提到Neutron组件内部有很多个不同的插件(plugin),而在Neutron中,实现一个插件包括两个部分的内容:一部分与数据库db打交道称之为plugin(虽然都是plugin,但是这个是具体实现中的plugin),一部分是调用具体的网络设备真正干活的称之为agent。 与db进行交互的plugin在功能上有很多重复,所以在代码上有很多重复,因此在Neutron中提供了一个公共的plugin叫ML2(ModuleLayer2) plugin。所以ML2 plugin的第一个作用就是:提供与数据库交互的公共plugin。 ML2的第二个作用就是实现支持多种pulgin(原先使用linux bridge,就不能用openvswitch),ML2通过MechanismDriver实现。MechanismDriver的作用是将agent的类型agent_type和vif_type关联,这样vif_type就可以直接通过扩展api设置了。 ML2的第三个作用就是支持不同的网络拓扑,如flat, vlan, gre, vxlan,直接在ml2_conf.ini这个配置文件里都配上即可。
L3-Agent
上面的ml2解决的只是网络中L2层的问题,对于L3层的路由功能,neturon单独用l3-agent实现,为客户机访问外部网络提供3层转发服务。 L3 层的路由分静态路由和动态路由两种: 在 Linux 中,通过打开 ipv4 forward 特性可以让数据包从一块网卡路由到另外一块网卡上。 动态路由,如内部网关协议 RIP,OSPF;如外部网关协议 BGP。能够自动地学习建立路由表。
目前 Neutron 只支持静态路由,要点如下: 对于不同 tenant 子网通过 namespace 功能进行隔离,在 Linux 中,一个命名空间 namespace 您可以简单理解成 linux 又启动了一个新的 TCP/IP 栈的进程。多个 tenant 意味着多个 namespace,也意味着多个 TCP/IP 栈。 对于同一tenant 中的不同子网的隔离通过 iptables 来做,也意味着,同一tenant中的相同子网的两个虚机不用走 L3 层,直接走 L2 层能通,没问题;但如果同一tenant中的不同子网的两个虚机要通讯的话,必须得绕道 L3-agent 网络节点,这是影响性能的。
- dhcp-agent
Dhcp-agent主要负责为各个租户网络提供DHCP服务。 L4-L7的Agent 至于再之上的L4-L7层的FwaaS,VPNaaS, DNATaaS, DNSaaS的内容,在neutron又出来一个新的服务框架用于将所有这些除L2层以外的网络服务类似于上述ml2的思想在数据库这块一网打尽。 下面我们通过一个单一扁平的提供者网络FLAT来部署neutron。为虚拟机提供网络资源。
1.1.2. Neutron控制节点部署
- Neutron安装
[root@linux-node1 ~]# yum install -y openstack-neutron openstack-neutron-ml2 \
openstack-neutron-linuxbridge ebtables
Neutron配置
- Neutron数据库配置
[root@linux-node1 ~]# vim /etc/neutron/neutron.conf
[database]
connection = mysql+pymysql://neutron:neutron@192.168.56.11:3306/neutron
- Keystone连接配置
[DEFAULT]
…
#注意:该配置默认不存在,需要添加
auth_strategy = keystone
[keystone_authtoken]
www_authenticate_uri = http://192.168.56.11:5000
auth_url = http://192.168.56.11:5000
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
- RabbitMQ相关设置
[root@linux-node1 ~]# vim /etc/neutron/neutron.conf
[DEFAULT]
transport_url = rabbit://openstack:openstack@192.168.56.11
#请注意是在DEFAULT配置栏目下,因为该配置文件有多个transport_url的配置
- Neutron网络基础配置
#注意:该配置默认不存在,需要添加
[DEFAULT]
core_plugin = ml2
# 这个配置没有错,就是设置为空
service_plugins =
- 网络拓扑变化Nova通知配置
[DEFAULT]
# 这两行配置需要新增
notify_nova_on_port_status_changes = True
notify_nova_on_port_data_changes = True
# 在配置文件最后增加以下配置段
[nova]
auth_url = http://192.168.56.11:5000
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 ML2配置
还是在控制节点上,我们需要配置Neutron ML2。ML2使用Linux桥接机制为实例创建Layer-2的虚拟网络基础设施。
[root@linux-node1 ~]# vim /etc/neutron/plugins/ml2/ml2_conf.ini
#以下所有配置目前均需要新增,默认配置文件已经移除,注意删除注释。
[ml2]
type_drivers = flat,vlan,gre,vxlan,geneve #支持多选,所以把所有的驱动都选择上。
tenant_network_types = flat,vlan,gre,vxlan,geneve #支持多项,所以把所有的网络类型都选择上。
mechanism_drivers = linuxbridge,openvswitch,l2population #选择插件驱动,支持多选,开源的有linuxbridge和openvswitch
#启用端口安全扩展驱动
extension_drivers = port_security,qos
[ml2_type_flat]
#设置网络提供
flat_networks = provider
[securitygroup]
#启用ipset
enable_ipset = True
- Neutron Linuxbridge配置
[root@linux-node1 ~]# vim /etc/neutron/plugins/ml2/linuxbridge_agent.ini
#以下所有配置目前均需要新增,默认配置文件已经移除,注意删除注释。
[linux_bridge]
#映射虚拟网络接口和实际网络接口的对应
physical_interface_mappings = provider:eth0
[vxlan]
#禁止vxlan网络
enable_vxlan = False
[securitygroup]
#设置使用Linux Bridge桥接的防火墙驱动和安全组
firewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver
enable_security_group = True
- Neutron DHCP-Agent配置
Neutron中的dhcp-agent用来为云主机动态分配IP地址,DHCP Agent默认是通过调用dnsmasq来实现DHCP的分配工作。默认情况下dhcp-agent和后面要介绍的Lbaas-agent都需要依赖namespace,所以开始之前我们需要先介绍下linux的namespache。
什么是namespace Namespace(命名空间),简单的说就是不同的名字空间,打个简单的比方,进程在a空间是叫a进程,在b空间也就可能叫b进程。为什么要有命名空间呢?主要是满足虚拟化的一些需求。试想,如果有一台机器,不管它是个人pc还是服务器,或是 网络交换机,路由器,一般情况下,它也就被一个用户使用。但是如果某一天,另外一个用户也要使用同样的机器,一种方法是再买一个机器,装上同样的 linux系统,但是还有一种更好的方法,就是使用容器(container),每个用户有属于自己的容器,而且容器之间相互隔离,而namespace 就是实现容器的一种手段。Namespace可以实现pid、net、ipc、mnt、uts、user等namespace将容器的进程、网络、消息、文件系统、UTS("UNIX Time-sharing System")和用户空间隔离开。在Docker中,我们会详解讲解namespace。
[root@linux-node1 ~]# vim /etc/neutron/dhcp_agent.ini
[DEFAULT]
interface_driver = linuxbridge
dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq
enable_isolated_metadata = True
- Neutron metadata配置
metadata agent为实例提供诸如凭证的配置信息。需要设置Keystone的链接和nova的连接参数。
[root@linux-node1 ~]# vim /etc/neutron/metadata_agent.ini
[DEFAULT]
nova_metadata_host = 192.168.56.11
#注意这个是为元数据代理设置的密码,需要和nova的配置相对应。
metadata_proxy_shared_secret = unixhot.com
- Neutron相关配置在nova.conf
Neutron的配置,需要修改nova的配置文件,因为默认大多数OpenStack发行版里nova.conf里面的网络相关的配置都是比较老的,使用的最早的nova-network的配置。所以需要进行修改。
[root@linux-node1 ~]# vim /etc/nova/nova.conf
[neutron]
auth_url = http://192.168.56.11:5000
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 = unixhot.com
#注意这里设置的共享秘钥需要和之前的对应上。
- 配置完毕后,我们需要设置一个软连接,因为默认服务会读取plugin.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
- 启动网络服务并配置他们开机自启动。
# systemctl enable neutron-server.service \
neutron-linuxbridge-agent.service neutron-dhcp-agent.service \
neutron-metadata-agent.service
# systemctl start neutron-server.service \
neutron-linuxbridge-agent.service neutron-dhcp-agent.service \
neutron-metadata-agent.service
- Neutron服务注册
创建service
# openstack service create --name neutron --description "OpenStack Networking" network
创建endpoint
# openstack endpoint create --region RegionOne network public http://192.168.56.11:9696
# openstack endpoint create --region RegionOne network internal http://192.168.56.11:9696
# openstack endpoint create --region RegionOne network admin http://192.168.56.11:9696
- 测试Neutron安装**
[root@openstack-compute-node1 neutron]# openstack network agent list
WARNING: Failed to import plugin orchestration.
WARNING: Failed to import plugin data_processing.
+--------------------------------------+--------------------+-------------------------------------+-------------------+-------+-------+---------------------------+
| ID | Agent Type | Host | Availability Zone | Alive | State | Binary |
+--------------------------------------+--------------------+-------------------------------------+-------------------+-------+-------+---------------------------+
| c4a78188-a3ad-4cda-8c47-41f854aad375 | Linux bridge agent | openstack-compute-node1.dianjoy.com | None | :-) | UP | neutron-linuxbridge-agent |
| e2325b10-281b-447c-b46f-7875c0eda1fc | Metadata agent | openstack-compute-node1.dianjoy.com | None | :-) | UP | neutron-metadata-agent |
| fb73fabc-2825-42c4-ae24-ea50bb1d37b8 | DHCP agent | openstack-compute-node1.dianjoy.com | nova | :-) | UP | neutron-dhcp-agent |
+--------------------------------------+--------------------+-------------------------------------+-------------------+-------+-------+---------------------------+
如果可以正常输出,基本上Neutron的安装就没有问题。
1.1.3. Neutron计算节点部署
- 安装软件包
[root@linux-node2 ~]# yum install -y openstack-neutron openstack-neutron-linuxbridge ebtables
配置计算节点Neutron
- Keystone连接配置
[root@linux-node2 ~]# vim /etc/neutron/neutron.conf
[DEFAULT]
auth_strategy = keystone
[keystone_authtoken]
www_authenticate_uri = http://192.168.56.11:5000
auth_url = http://192.168.56.11:5000
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
- RabbitMQ相关设置
[root@linux-node1 ~]# vim /etc/neutron/neutron.conf
[DEFAULT]
transport_url = rabbit://openstack:openstack@192.168.56.11
#请注意是在DEFAULT配置栏目下,因为该配置文件有多个transport_url的配置
- 锁路径
[oslo_concurrency]
lock_path = /var/lib/neutron/tmp
- 配置LinuxBridge配置
[root@linux-node1 ~]# scp /etc/neutron/plugins/ml2/linuxbridge_agent.ini 192.168.56.12:/etc/neutron/plugins/ml2/
- 设置计算节点的nova.conf
[root@linux-node2 ~]# vim /etc/nova/nova.conf
[neutron]
auth_url = http://192.168.56.11:5000
auth_type = password
project_domain_name = default
user_domain_name = default
region_name = RegionOne
project_name = service
username = neutron
password = neutron
- 重启计算服务
[root@linux-node2 ~]# systemctl restart openstack-nova-compute.service
- 启动计算节点linuxbridge-agent
[root@linux-node2 ~]# systemctl enable neutron-linuxbridge-agent.service
[root@linux-node2 ~]# systemctl start neutron-linuxbridge-agent.service
- 在控制节点上测试Neutron安装
[root@linux-node1 ~]# source admin-openstack.sh
[root@linux-node1 ~]# openstack network agent list
+--------------------------------------+--------------------+-----------------------------+-------------------+-------+-------+---------------------------+
| ID | Agent Type | Host | Availability Zone | Alive | State | Binary |
+--------------------------------------+--------------------+-----------------------------+-------------------+-------+-------+---------------------------+
| 11f1de57-836f-412f-b9b4-51dcdc9ae931 | Metadata agent | linux-node1.example.com | None | :-) | UP | neutron-metadata-agent |
| 197b84cd-7d6e-4ed2-9fa0-46499fe7cdb7 | Linux bridge agent | linux-node2.example.com | None | :-) | UP | neutron-linuxbridge-agent |
| 531afd6d-ee81-4b64-a0f4-ec5fd523eff8 | DHCP agent | linux-node1.example.com | nova | :-) | UP | neutron-dhcp-agent |
| dfc431ff-dede-4a54-8371-653c6e72ffd9 | Linux bridge agent | linux-node1.example.com | None | :-) | UP | neutron-linuxbridge-agent |
+--------------------------------------+--------------------+-----------------------------+-------------------+-------+-------+---------------------------+
看是否有linux-node2.example.com的Linux bridge agent
1.1.4. Bug解决
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent [req-68a7936c-2bbc-454e-bee4-6785cd3dce7b - - - - -] Error in agent loop. Devices info: {'current': set(['tap07dc4c9c-f3']), 'timestamps': {'tap07dc4c9c-f3': 7}, 'removed': set([]), 'added': set(['tap07dc4c9c-f3']), 'updated': set([])}: KeyError: 'gateway'
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent Traceback (most recent call last):
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent File "/usr/lib/python2.7/site-packages/neutron/plugins/ml2/drivers/agent/_common_agent.py", line 465, in daemon_loop
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent sync = self.process_network_devices(device_info)
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent File "/usr/lib/python2.7/site-packages/osprofiler/profiler.py", line 160, in wrapper
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent result = f(*args, **kwargs)
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent File "/usr/lib/python2.7/site-packages/neutron/plugins/ml2/drivers/agent/_common_agent.py", line 214, in process_network_devices
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent resync_a = self.treat_devices_added_updated(devices_added_updated)
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent File "/usr/lib/python2.7/site-packages/osprofiler/profiler.py", line 160, in wrapper
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent result = f(*args, **kwargs)
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent File "/usr/lib/python2.7/site-packages/neutron/plugins/ml2/drivers/agent/_common_agent.py", line 231, in treat_devices_added_updated
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent self._process_device_if_exists(device_details)
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent File "/usr/lib/python2.7/site-packages/neutron/plugins/ml2/drivers/agent/_common_agent.py", line 258, in _process_device_if_exists
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent device, device_details['device_owner'])
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent File "/usr/lib/python2.7/site-packages/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py", line 585, in plug_interface
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent network_segment.mtu)
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent File "/usr/lib/python2.7/site-packages/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py", line 521, in add_tap_interface
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent return False
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent File "/usr/lib/python2.7/site-packages/oslo_utils/excutils.py", line 220, in __exit__
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent self.force_reraise()
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent File "/usr/lib/python2.7/site-packages/oslo_utils/excutils.py", line 196, in force_reraise
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent six.reraise(self.type_, self.value, self.tb)
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent File "/usr/lib/python2.7/site-packages/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py", line 513, in add_tap_interface
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent tap_device_name, device_owner, mtu)
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent File "/usr/lib/python2.7/site-packages/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py", line 546, in _add_tap_interface
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent mtu):
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent File "/usr/lib/python2.7/site-packages/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py", line 497, in ensure_physical_in_bridge
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent physical_interface)
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent File "/usr/lib/python2.7/site-packages/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py", line 286, in ensure_flat_bridge
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent if self.ensure_bridge(bridge_name, physical_interface):
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent File "/usr/lib/python2.7/site-packages/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py", line 455, in ensure_bridge
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent self.update_interface_ip_details(bridge_name, interface)
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent File "/usr/lib/python2.7/site-packages/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py", line 417, in update_interface_ip_details
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent gateway)
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent File "/usr/lib/python2.7/site-packages/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py", line 401, in _update_interface_ip_details
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent dst_device.route.add_gateway(gateway=gateway['gateway'],
2020-01-29 14:09:22.599 6346 ERROR neutron.plugins.ml2.drivers.agent._common_agent KeyError: 'gateway'
分别修改控制节点和计算节点上的Neutron源码,并重启服务
- 将priority修改为metric
[root@openstack-compute-node3 ~]# vim +1503 /usr/lib/python2.7/site-packages/neutron/agent/linux/ip_lib.py
#'priority': get_attr(route, 'RTA_PRIORITY'),
'metric': get_attr(route, 'RTA_PRIORITY'),
- 将gateway修改为via
[root@openstack-compute-node3 ~]# vim +402 /usr/lib/python2.7/site-packages/neutron/plugins/ml2/drivers/linuxbridge/agent/linuxbridge_neutron_agent.py
#dst_device.route.add_gateway(gateway=gateway['gateway'],
dst_device.route.add_gateway(gateway=gateway['via'],
metric=metric)
#src_device.route.delete_gateway(gateway=gateway['gateway'])
src_device.route.delete_gateway(gateway=gateway['via'])
计算节点重启服务
[root@openstack-compute-node3 ~]# systemctl restart neutron-linuxbridge-agent
控制节点重启服务
[root@openstack-compute-node1 ~]# systemctl restart neutron-server.service neutron-linuxbridge-agent.service neutron-dhcp-agent.service neutron-metadata-agent.service