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。以下圖所示: