OpenStack組件——Neutron網絡服務(2)

1.虛擬機獲取 ip

1)用 namspace 隔離 DHCP 服務node

Neutron 經過 dnsmasq 提供 DHCP 服務,而 dnsmasq 經過 Linux Network Namespace 獨立的爲每一個 network 服務隔離python

在二層網絡上,VLAN 能夠將一個物理交換機分割成幾個獨立的虛擬交換機。相似地,在三層網絡上,Linux network namespace 能夠將一個物理三層網絡分割成幾個獨立的虛擬三層網絡。mysql

每一個 namespace 都有本身獨立的網絡棧,包括 route table,firewall rule,network interface device 等。linux

Neutron 經過 namespace 爲每一個 network 提供獨立的 DHCP 和路由服務,從而容許租戶建立重疊的網絡。若是沒有 namespace,網絡就不能重疊,這樣就失去了不少靈活性。sql

每一個 dnsmasq 進程都位於獨立的 namespace, 命名爲 qdhcp-<network id>,例如 flat_net:數據庫

    ip netns list         命令列出全部的 namespace

    ip netns exec <network namespace name> <command>        管理 namespace

 

2)root namespacevim

其實,宿主機自己也有一個 namespace,叫 root namespace,擁有全部物理和虛擬 interface device。物理 interface 只能位於 root namespace。api

新建立的 namespace 默認只有一個 loopback device。管理員能夠將虛擬 interface,例如 bridge,tap 等設備添加到某個 namespace。網絡

對於 flat_net 的 DHCP 設備 tap19a0ed3d-fe,須要將其放到 namespace qdhcp-7bf09be4-8653-4869-84f0-33494f238627 中,但這樣會帶來一個問題:tap19a0ed3d-fe 將沒法直接與 root namespace 中的 bridge 設備 brqf153b42f-c3 鏈接。app

Neutron 使用 veth pair 解決了這個問題。

veth pair 是一種成對出現的特殊網絡設備,它們象一根虛擬的網線,可用於鏈接兩個 namespace。向 veth pair 一端輸入數據,在另外一端就能讀到此數據。

tap19a0ed3d-fe 與 ns-19a0ed3d-fe 就是一對 veth pair,它們將 qdhcp-f153b42f-c3a1-4b6c-8865-c09b5b2aa274 鏈接到 brqf153b42f-c3。

以下圖所示:

能夠經過 ip netns exec qdhcp-7bf09be4-8653-4869-84f0-33494f238627 ip a命令查看ns-ba07bb93配置。

 

3)獲取 dhcp IP 過程分析

在建立 instance 時,Neutron 會爲其分配一個 port,裏面包含了 MAC 和 IP 地址信息。這些信息會同步更新到 dnsmasq 的 host 文件。以下圖所示:

同時 nova-compute 會設置虛機 VIF 的 MAC 地址。

 

一切準備就緒,instance 獲取 IP 的過程以下:

(1)vm 開機啓動,發出 DHCPDISCOVER 廣播,該廣播消息在整個 net 中均可以被收到。

(2)廣播到達 veth tap19a0ed3d-fe,而後傳送給 veth pair 的另外一端 ns-19a0ed3d-fe。dnsmasq 在它上面監聽,dnsmasq 檢查其 host 文件,發現有對應項,因而dnsmasq 以  DHCPOFFER 消息將 IP(192.168.254.18)、子網掩碼(255.255.255.0)、地址租用期限等信息發送給 vm。

(3)vm 發送 DHCPREQUEST 消息確認接受此 DHCPOFFER。

(4)dnsmasq 發送確認消息 DHCPACK,整個過程結束。

 

2.VXLAN簡介

1)overlay network概念

overlay network 是指創建在其餘網絡上的網絡。overlay network 中的節點能夠看做經過虛擬(或邏輯)鏈路鏈接起來的。overlay network 在底層可能由若干物理鏈路組成,但對於節點,不須要關心這些底層實現。

例如 P2P 網絡就是 overlay network,隧道也是。vxlan 和 gre 都是基於隧道技術實現的,它們也都是 overlay network。

目前 linux bridge 只支持 vxlan,不支持 gre;

open vswitch 二者都支持。vxlan 與 gre 實現很是相似,並且 vxlan 用得較多,因此本教程只介紹 vxlan。

 

2)VXLAN簡介:

VXLAN 爲 Virtual eXtensible Local Area Network。正如名字所描述的,VXLAN 提供與 VLAN 相同的以太網二層服務,但擁有更強的擴展性和靈活性。與 VLAN 相比,

VXLAN 有下面幾個優點:

(1)支持更多的二層網段。

VLAN 使用 12-bit 標記 VLAN ID,最多支持 4094 個 VLAN,這對大型雲部署會成爲瓶頸。VXLAN 的 ID (VNI 或者 VNID)則用 24-bit 標記,支持 16777216 個二層網段。

(2)能更好地利用已有的網絡路徑。

VLAN 使用 Spanning Tree Protocol 避免環路,這會致使有一半的網絡路徑被 block 掉。VXLAN 的數據包是封裝到 UDP 經過三層傳輸和轉發的,可使用全部的路徑。

(3)避免物理交換機 MAC 表耗盡。

因爲採用隧道機制,TOR (Top on Rack) 交換機無需在 MAC 表中記錄虛擬機的信息。

 

3)VXLAN 封裝和包格式:

VXLAN 是將二層創建在三層上的網絡。經過將二層數據封裝到 UDP 的方式來擴展數據中心的二層網段數量。

VXLAN 是一種在現有物理網絡設施中支持大規模多租戶網絡環境的解決方案。VXLAN 的傳輸協議是 IP + UDP。

VXLAN 定義了一個 MAC-in-UDP 的封裝格式。在原始的 Layer 2 網絡包前加上 VXLAN header,而後放到 UDP 和 IP 包中。經過 MAC-in-UDP 封裝,VXLAN 可以在 Layer 3 網絡上創建起了一條 Layer 2 的隧道。

 

VXLAN 包的格式以下

 

如上圖所示,VXLAN 引入了 8-byte VXLAN header,其中 VNI 佔 24-bit。VXLAN 和原始的 L2 frame 被封裝到 UDP 包中。這 24-bit 的 VNI 用於標示不一樣的二層網段,可以支持 16777216 個 LAN。

 

4)VXLAN Tunnel Endpoint

VXLAN 使用 VXLAN tunnel endpoint (VTEP) 設備處理 VXLAN 的封裝和解封。每一個 VTEP 有一個 IP interface,配置了一個 IP 地址。VTEP 使用該 IP 封裝 Layer 2 frame,並經過該 IP interface 傳輸和接收封裝後的 VXLAN 數據包。

下面是 VTEP 的示意圖

 

VXLAN 獨立於底層的網絡拓撲;反過來,兩個 VTEP 之間的底層 IP 網絡也獨立於 VXLAN。VXLAN 數據包是根據外層的 IP header 路由的,該 header 將兩端的 VTEP IP 做爲源和目標 IP。

VXLAN 封裝和轉發包的過程,以及 Linux 對 VXLAN 的原生支持

VXLAN 包轉發流程

VXLAN 在 VTEP 間創建隧道,經過 Layer 3 網絡傳輸封裝後的 Layer 2 數據。下面例子演示了數據如何在 VXLAN 上傳輸

 (1)圖中 Host-A 和 Host-B 位於 VNI 10 的 VXLAN,經過 VTEP-1 和 VTEP-2 之間創建的 VXLAN 隧道通訊。數據傳輸過程以下:

a)Host-A 向 Host-B 發送數據時,Host-B 的 MAC 和 IP 做爲數據包的目標 MAC 和 IP,Host-A 的 MAC 做爲數據包的源 MAC 和 IP,而後經過 VTEP-1 將數據發送出去。

b)VTEP-1 從本身維護的映射表中找到 MAC-B 對應的 VTEP-2,而後執行 VXLAN 封裝,加上 VXLAN 頭,UDP 頭,以及外層 IP 和 MAC 頭。此時的外層 IP 頭,目標地址爲 VTEP-2 的 IP,源地址爲 VTEP-1 的 IP。同時因爲下一跳是 Router-1,因此外層 MAC 頭中目標地址爲 Router-1 的 MAC。

c)數據包從 VTEP-1 發送出後,外部網絡的路由器會依據外層 IP 頭進行路由,最後到達與 VTEP-2 鏈接的路由器 Router-2。

d)Router-2 將數據包發送給 VTEP-2。VTEP-2 負責解封數據包,依次去掉外層 MAC 頭,外層 IP 頭,UDP 頭 和 VXLAN 頭。VTEP-2 依據目標 MAC 地址將數據包發送給 Host-B。

上面的流程咱們看到 VTEP 是 VXLAN 的最核心組件,負責數據的封裝和解封。隧道也是創建在 VTEP 之間的,VTEP 負責數據的傳送。

(2)VTEP 是如何提早獲知 IP -- MAC -- VTEP 相關信息的呢?

a)Neutron 知道每個 port 的狀態和信息; port 保存了 IP,MAC 相關數據。

b)instance 啓動時,其 port 狀態變化過程爲:down -> build -> active。

c)每當 port 狀態發生變化時,Neutron 都會經過 RPC 消息通知各節點上的 Neutron agent,使得 VTEP 可以更新 VM 和 port 的相關信息。VTEP 能夠根據這些信息判斷出其餘 Host 上都有哪些 VM,以及它們的 MAC 地址,這樣就能直接與之通訊,從而避免了沒必要要的隧道鏈接和廣播。

(3)Linux 對 VXLAN 的支持

VTEP 能夠由專有硬件來實現,也可使用純軟件實現。目前比較成熟的 VTEP 軟件實現包括:

a)帶 VXLAN 內核模塊的 Linux

b)Open vSwitch

咱們先來看 Linux 如何支持 VXLAN

實現方式:

a)Linux vxlan 建立一個 UDP Socket,默認在 8472 端口監聽。

b)Linux vxlan 在 UDP socket 上接收到 vxlan 包後,解包,而後根據其中的 vxlan ID 將它轉給某個 vxlan interface,而後再經過它所鏈接的 linux bridge 轉給虛機。

c)Linux vxlan 在收到虛機發來的數據包後,將其封裝爲多播 UDP 包,從網卡發出。

 

網卡分配示例

 a)控制節點三個網卡(eth0, eth1, eth2),計算節點兩網卡(eth0, eth1)。

b)合併 Management 和 API 網絡,使用 eth0,IP 段爲 192.168.104.0/24。

c)VM 網絡使用 eht1。

d)控制節點的 eth2 與 External 網絡鏈接,IP 段爲 10.10.10.0/24。

 

ML2 mechanism driver: Linux Bridge 和 Open vSwitch 

Linux Bridge

Open vSwitch

 Open vSwitch 中的網絡設備:

br-ex:鏈接外部(external)網絡的網橋。

br-int:集成(integration)網橋,全部 instance 的虛擬網卡和其餘虛擬網絡設備都將鏈接到該網橋。

br-tun:隧道(tunnel)網橋,基於隧道技術的 VxLAN 和 GRE 網絡將使用該網橋進行通訊。

tap interface:命名爲 tapXXXX。

linux bridge:命名爲 qbrXXXX。

veth pair:命名爲 qvbXXXX, qvoXXXX

OVS integration bridge:命名爲 br-int。

OVS patch ports:命名爲 int-br-ethX 和 phy-br-ethX(X 爲 interface 的序號)。

OVS provider bridge:命名爲 br-ethX(X 爲 interface 的序號)。

物理 interface:命名爲 ethX(X 爲 interface 的序號)。

OVS tunnel bridge:命名爲 br-tun。

 

3.三層網絡介紹

1)虛擬機訪問外網:

(1)虛擬機中訪問一個外網地址192.168.253.3,並用 traceroute 命令跟蹤路由查看

(2)根據網絡拓撲,因爲虛機訪問外網要通過本網段的網關192.168.101.1,而後通過路由的外網接口轉發出去,到達192.168.253.3

查看路由命名空間

ip netns list

 

 (3)查看路由命名空間的網絡配置,查到路由鏈接外網的端口和ip

ip netns exec qrouter-176bd7e0-6427-46a5-906a-be6a373a29a1 ip a

路由上的外網端口正好接到外網網橋br-ex上:ovs-vsctl show 查看

 

(4)查看路由iptables NAT 轉發規則,記錄對私網作的SNAT

ip netns exec qrouter-176bd7e0-6427-46a5-906a-be6a373a29a1 iptables -t nat -L

ip netns exec qrouter-176bd7e0-6427-46a5-906a-be6a373a29a1 iptables -t nat -S

規則解釋: -A neutron-l3-agent-snat -o qg-8df29d32-d6 -j SNAT --to-source 192.168.253.65 記錄了流入接口qg-8df29d32-d6 的數據包作SNAT(基於源地址轉發),將源地址修改成192.168.253.65

 

(5)驗證

在虛機 ping 192.168.253.3 時, 能夠經過 tcpdump 分別觀察 router 兩個 interface 的 icmp 數據包來驗證 SNAT 的行爲:

在路由qrouter-176bd7e0-6427-46a5-906a-be6a373a29a1,可查到私有網絡的網關接口qr-7b56f58b-b5,並在路由中抓取網關接口的icmp包:

ip netns exec qrouter-176bd7e0-6427-46a5-906a-be6a373a29a1 tcpdump -i qr-7b56f58b-b5 -n icmp

在路由中,抓取路由的外網接口qg-8df29d32-d6的icmp包:

ip netns exec qrouter-176bd7e0-6427-46a5-906a-be6a373a29a1 tcpdump -i qg-8df29d32-d6 -n icmp

2)外網訪問虛機——floating ip原理

SNAT 讓 instance 可以直接訪問外網,但外網還不能直接訪問 instance。由於 instance 沒有外網 IP。這裏 「直接訪問 instance」 是指通訊鏈接由外網發起,例如從外網 SSH 實例。

(1)首先將實例綁定浮動 ip192.168.253.66, floating IP 是配置在 router 的外網 interface 上的,再查看 router 的 interface 配置:

(2)在實例中ping 192.168.253.3 外網地址,在路由的qr-7b56f58b-b5 接口上,實例訪問外網ip,外網ip將數據包轉發回實例ip;但在路由的qg-8df29d32-d6 接口上,始終是經過 floating IP 192.168.253.66 與外網通訊。

(3) 緣由是在路由中iptables作了DNA T(基於目的地址轉發),查看 router 的 NAT 規則

當 router 接收到從外網發來的包,若是目的地址是 floating IP 192.168.254.66,將目的地址修改成實例的 IP 192.168.101.3。這樣外網的包就能送達到實例;

當實例發送數據到外網,源地址 192.168.101.3 將被修改成 floating IP 192.168.253.66;

 

4.搭建neutron服務

1)環境準備

(1)數據庫準備

    create database neutron;

    grant all privileges on neutron.* to 'neutron'@'localhost' identified by 'NEUTRON_DBPASS';
    grant all privileges on neutron.* to 'neutron'@'%' identified by 'NEUTRON_DBPASS';

 

(2)建立用戶、服務

建立neutron用戶

    openstack user create --domain default --password=neutron neutron
    +---------------------+----------------------------------+
    | Field               | Value                            |
    +---------------------+----------------------------------+
    | domain_id           | default                          |
    | enabled             | True                             |
    | id                  | 99d0fc3a849a4951b92135799fed0673 |
    | name                | neutron                          |
    | options             | {}                               |
    | password_expires_at | None                             |
    +---------------------+----------------------------------+

 

將cinder用戶角色設置爲admin

    openstack role add --project service --user neutron admin

 

建立cinder服務

    openstack service create --name neutron --description "OpenStack Networking" network
    +-------------+----------------------------------+
    | Field       | Value                            |
    +-------------+----------------------------------+
    | description | OpenStack Networking             |
    | enabled     | True                             |
    | id          | 3e79c5a9080043d2b49d06e58affeb76 |
    | name        | neutron                          |
    | type        | network                          |
    +-------------+----------------------------------+

 

(3)建立neutron服務的endpoint

    openstack endpoint create --region RegionOne network public http://node1:9696
    +--------------+----------------------------------+
    | Field        | Value                            |
    +--------------+----------------------------------+
    | enabled      | True                             |
    | id           | 14cf89b4812a44e9ba657bb04f4b058d |
    | interface    | public                           |
    | region       | RegionOne                        |
    | region_id    | RegionOne                        |
    | service_id   | 3e79c5a9080043d2b49d06e58affeb76 |
    | service_name | neutron                          |
    | service_type | network                          |
    | url          | http://node1:9696                |
    +--------------+----------------------------------+
     
     
    openstack endpoint create --region RegionOne network internal http://node1:9696
    +--------------+----------------------------------+
    | Field        | Value                            |
    +--------------+----------------------------------+
    | enabled      | True                             |
    | id           | e521a19f51f44a9a823361cb570b982f |
    | interface    | internal                         |
    | region       | RegionOne                        |
    | region_id    | RegionOne                        |
    | service_id   | 3e79c5a9080043d2b49d06e58affeb76 |
    | service_name | neutron                          |
    | service_type | network                          |
    | url          | http://node1:9696                |
    +--------------+----------------------------------+
     
     
    openstack endpoint create --region RegionOne network admin http://node1:9696
    +--------------+----------------------------------+
    | Field        | Value                            |
    +--------------+----------------------------------+
    | enabled      | True                             |
    | id           | b2a4f6dc0289426291317b80265145fc |
    | interface    | admin                            |
    | region       | RegionOne                        |
    | region_id    | RegionOne                        |
    | service_id   | 3e79c5a9080043d2b49d06e58affeb76 |
    | service_name | neutron                          |
    | service_type | network                          |
    | url          | http://node1:9696                |
    +--------------+----------------------------------+

 

2)配置網絡相關

(1)安裝相關軟件包

    yum install openstack-neutron openstack-neutron-ml2 openvswitch openstack-neutron-openvswitch ebtables -y

 

(2)修改neutron配置文件

vim /etc/neutron/neutron.conf
[DEFAULT]
state_path = /var/lib/neutron
auth_strategy = keystone
core_plugin = ml2
service_plugins = router
dhcp_agent_notification = true
allow_overlapping_ips = True
notify_nova_on_port_status_changes = true
notify_nova_on_port_data_changes = true
transport_url = rabbit://openstack:admin@node1
...
[database]
connection = mysql+pymysql://neutron:NEUTRON_DBPASS@node1/neutron
...
[keystone_authtoken]
auth_uri = http://node1:5000
auth_url = http://node1:35357
memcached_servers = node1:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = neutron
password = neutron
...
[nova]
region_name = RegionOne
auth_url = http://node1:35357
auth_type = password
project_domain_name = default
project_name = service
user_domain_name = default
username = nova
password = nova
...
[oslo_concurrency]
lock_path = $state_path/lock
...

 

(3)修改Modular Layer 2 (ML2) plug-in配置文件

vim /etc/neutron/plugins/ml2/ml2_conf.ini
[ml2]
type_drivers = flat,vxlan
tenant_network_types = vxlan
mechanism_drivers = openvswitch,l2population
extension_drivers = port_security
...
[ml2_type_vxlan]
vni_ranges = 1:1000
...
[securitygroup]
enable_ipset = true

 

(4)修改openvswitch_agent配置文件

vim /etc/neutron/plugins/ml2/openvswitch_agent.ini
...
[agent]
tunnel_types = vxlan
l2_population = True
...
[ovs]
tunnel_bridge = br-tun
local_ip = 192.168.192.134(租戶網的網卡ip)
bridge_mappings =
...
[securitygroup]
firewall_driver = iptables_hybrid
enable_security_group = true
...

 

(5)修改layer-3 agent配置文件

vim /etc/neutron/l3_agent.ini
[DEFAULT]
interface_driver = openvswitch
external_network_bridge = br-ex
...

 

(6)修改metadata_agent配置文件

vim /etc/neutron/metadata_agent.ini
[DEFAULT]
nova_metadata_ip = node1
metadata_proxy_shared_secret = METADATA_SECRET
...

 

(7)修改dhcp_agent配置文件

vim /etc/neutron/dhcp_agent.ini
[DEFAULT]
interface_driver = openvswitch
dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq
enable_isolated_metadata = true
...

 

3)配置計算服務使用網絡服務

vim /etc/nova/nova.conf
...
[neutron]
url = http://node1:9696
auth_url = http://node1: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 = METADATA_SECRET
...

 

4)建立軟鏈接

    ln -s /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugin.ini

 

5)同步數據庫

    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

 

6)啓動服務

    systemctl restart openstack-nova-api.service
     
    systemctl start neutron-server.service neutron-dhcp-agent.service openvswitch \
      neutron-openvswitch-agent neutron-metadata-agent.service
     
    systemctl enable neutron-server.service neutron-dhcp-agent.service openvswitch \
      neutron-openvswitch-agent neutron-metadata-agent.service

 

7)添加一塊網卡並設置禁止獲取IP、創建網橋

vim /etc/sysconfig/network-scripts/ifcfg-ens38
TYPE=Ethernet
NAME=ens38
UUID=be119028-7b80-312f-85cd-ed1ea343254e
ONBOOT=yes
DEVICE=ens38
IPV6INIT=no

 

    ovs-vsctl add-br br-ex
    ovs-vsctl add-port br-ex ens38
     
    ovs-vsctl show
    f6f8d962-bbe0-4dc8-9582-a5d041145cc8
        Manager "ptcp:6640:127.0.0.1"
            is_connected: true
        Bridge br-tun
            Controller "tcp:127.0.0.1:6633"
                is_connected: true
            fail_mode: secure
            Port br-tun
                Interface br-tun
                    type: internal
            Port patch-int
                Interface patch-int
                    type: patch
                    options: {peer=patch-tun}
        Bridge br-int
            Controller "tcp:127.0.0.1:6633"
                is_connected: true
            fail_mode: secure
            Port patch-tun
                Interface patch-tun
                    type: patch
                    options: {peer=patch-int}
            Port br-int
                Interface br-int
                    type: internal
        Bridge br-ex
            Port "ens38"
                Interface "ens38"
            Port br-ex
                Interface br-ex
                    type: internal
        ovs_version: "2.9.0"

 

8)配置計算節點

(1)安裝相關軟件包

    yum install openvswitch openstack-neutron-openvswitch ebtables ipset -y

 

(2)配置neutron配置文件

vim /etc/neutron/neutron.conf
[DEFAULT]
auth_strategy = keystone
transport_url = rabbit://openstack:admin@node1
...
[keystone_authtoken]
auth_uri = http://node1:5000
auth_url = http://node1:35357
memcached_servers = node1:11211
auth_type = password
project_domain_name = default
user_domain_name = default
project_name = service
username = neutron
password = neutron
...
[oslo_concurrency]
lock_path = $state_path/lock
...

 

(3)配置網絡相關服務

vim /etc/neutron/plugins/ml2/openvswitch_agent.ini
...
[agent]
tunnel_types = vxlan
l2_population = True
...
[ovs]
tunnel_bridge = br-tun
local_ip = 192.168.192.135
bridge_mappings =
...
[securitygroup]
firewall_driver = iptables_hybrid
enable_security_group = true

 

(4)配置計算服務使用網絡服務

vim /etc/nova/nova.conf
...
[neutron]
url = http://node1:9696
auth_url = http://node1: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 = METADATA_SECRET
...

 

(5)啓動相關服務

  systemctl restart openstack-nova-compute.service
	 
  systemctl enable openvswitch neutron-openvswitch-agent
  systemctl start openvswitch neutron-openvswitch-agent
相關文章
相關標籤/搜索