天天看點

openstack neutron介紹

http://www.aboutyun.com/thread-13568-1-1.html

openstack的Neutron中虛拟網絡裝置介紹

http://www.aboutyun.com/thread-13596-1-1.html

Neutron使用openvswitch網絡通信的基本原理

http://www.aboutyun.com/thread-13526-1-1.html

openstack網絡(neutron)模式之GRE的基本原理

http://www.aboutyun.com/thread-11999-1-1.html

一.前言

本文主要介紹了如何分析Neutron下的VM網絡資料流,并結合這些方法如何去進行網絡分析和故障解決。限于篇幅、環境,這裡并未提及Flow Table、br-tun等。我們将在下次見面。

總所周知,OpenStack Neutron的高度複雜性和抽象性,讓衆多學習和使用者望而生畏,不知所雲。盡管如此,但我們不能選擇逃避。

其實,暫且抛開具體細節不談,從全局和宏觀上了解Neutron的整個運作流程,也是不複雜、抽象的。

無非就是将傳統的實體硬體裝置(如網線、網卡、伺服器、交換機、路由器等)按照TCP/IP的四個層次架構(資料鍊路層、網絡層、傳輸層、應用層),通過軟體程式設計的方式,予以全部虛拟化、軟體化和抽象化。

其虛拟實作的1層到3層(TCP/IP)整個流程是:

一層的伺服器及其VM(由Linux Kernel建立的qbr、tap/tun、veth、iptables這些裝置分别實作相應功能)——》 二層的網絡裝置(由OpenvSwitch、dnsmasq建立的qvo、br-int、br-tun、br-ex、qrouter、qdhcp等裝置分别實作相應功能)——》 再到,三層的傳輸程式(由patch-int/patch-tun等分别實作相應的功能)。

在Neutron虛拟網絡中,除了Neutron本身指令外,還包括了Linux Bridge的brctl指令;OpenvSwitch的ovs-vsctl、ovs-ofctl指令和L3的NameSpace的ip netns等指令。

提到Neutron的虛拟網絡功能實作,不得不先提基于Linux核心級的虛拟裝置。

TAP/TUN/VETH是Linux核心實作的一對虛拟網絡裝置,TAP工作在二層,收發的是 MAC 層資料幀;TUN工作在三層,收發的是 IP 層資料包。Linux 核心通過TAP/TUN裝置向綁定該裝置的使用者程式發送資料,反之,使用者程式也可以像操作硬體網絡裝置一樣,通過TAP/TUN裝置接收資料。

基于TAP裝置,實作的是虛拟網卡的功能,當一個TAP裝置被建立時,在Linux的裝置檔案目錄下将會生成一個對應的字元裝置檔案(/dev/tapX檔案),而運作其上的使用者程式便可以像使用普通檔案一樣打開這個檔案進行讀寫。

VETH裝置總是成對出現的,接收資料的一端會從另一端發送出去,了解為一根虛拟的網線即可。

至于,DVR、NFV、SDN等這些和Neutron挂鈎的高大上名詞,也無非是借鑒了傳統的網絡架構,予以虛拟化和創新罷了。最後,怎麼去具體實作,那就是架構設計和軟體編碼的事兒了。

下面,我們将以實踐且非常實用的方法來走進Neutron的虛拟網絡世界中,化抽象為形象。

二.OpenStack Neutron網絡連接配接測試

OpenStack Neutron網絡連接配接測試,說到底是VM的網絡連接配接測試,即與外網的網絡連接配接情況、網絡診斷和故障排錯等。方法如下:

注意

由于執行的指令輸出資訊太多,這裡予以了省略,但并不影響了解和學習。在必要處,會給出資訊。

實驗環境如下:

Host Server/VM:CentOS 7

OpenStack Juno Neutron:VLAN模式

Provider Network:Vlan 102、網段 172.16.102.0/24、 網關172.16.102.254

VM IP:172.16.102.5

需要注意的是,在vlan模式下,vlan tag的轉換是在br-int和br-ethx兩個網橋上進行。即br-int負責從int-br-ethX過來的包(帶外部vlan)轉換為内部vlan,而br-ethx負責從phy-br-ethx過來的包(帶内部vlan)轉化為外部的vlan。

同時,在VLAN模式下,沒有br-tun通道網橋。

我們将根據下面這張圖的流程(VM資料到外網),予以分析:

1.計算存儲節點上

1)執行nova list 檢視VM對應的名稱和VM_UUID。

VM預設存放于路徑:/var/lib/nova/instances/

# nova list

2)執行nova show $VM_UUID,檢視VM所在的openstack compute node資訊和instance name。

# nova show  $VM_UUID

3)檢視VM在哪個計算節點上。

# nova-manage vm list | grep vm-name

4)執行virsh list 檢視VM狀态,執行virsh dumpxml instance-XXXX查找檔案中關于“Bridge”資訊,查找tap的ID和網橋 qbrXXXX。

# virsh dumpxml instance-00000052

</controller>

    <interface type=’bridge’>

      <mac address=’fa:16:3e:3e:da:f1′/>

      <source bridge=’qbrc08d85da-69′/>   #OVS實作安全組的網橋

      <target dev=’tapc08d85da-69′/>      #虛拟網卡裝置

      <model type=’virtio’/>              #虛拟網卡驅動

      <alias name=’net0′/>               #虛拟網卡别名

      <address type=’pci’ domain=’0×0000′ bus=’0×00′ slot=’0×03′ function=’0×0′/>

這裡,我們結合一張官網的圖,來予以剖析。

從圖中,我們可以知道:

eth0連接配接的目的裝置是:tapc08d85da-69,别名為net0。

TAP裝置橋接到網橋qbrXX上(都由Linux kernel建立)。qbr裝置是因為不能在TAP裝置上配置iptables實作安全組(Secur Group)而增加的裝置。

eth0對應的tapc08d85da-69,橋接到的網橋為qbrc08d85da-69。

5)執行brctl show檢視網橋qbr上的接口資訊,找到tap裝置和qvbXXXX接口。

備注:由于這些網橋均由Linux Kernel建立,是以使用brctl指令

# brctl show

qbrc08d85da-69  8000.3a04f8f4bda2 no  qvbc08d85da-69

tapc08d85da-69

這裡,可以看到網橋qbrc08d85da-69,上面有接口qvbc08d85da-69和tapc08d85da-69。

這裡出現的qvbXXX和qvoXXX是一對veth pair devices,是一對虛拟的網卡裝置或虛拟的網線,用來連接配接Linux bridge網橋和Open vSwitch裝置。名字的涵義是q-quantum、v-veth、b-bridge;o-open、vswitch(quantum年代的遺留)。

6)檢視qvb裝置的驅動是否是veth類型。

# lshw -class network|more

7)檢視qvb接口的對端peer_ifindex:number。

# ethtool -S qvbc08d85da-69

NIC statistics:

     peer_ifindex: 15

8)找到peer_ifindex:number對應的接口qvoXXX。

# ip link | grep 15:

15: qvoc08d85da-69: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master ovs-system state UP mode DEFAULT qlen 1000

    link/ether 4e:99:15:01:1b:07 brd ff:ff:ff:ff:ff:ff

qvbXXX和qvoXXX是一對veth裝置,成對出現的。可以根據ethtool -S 檢視對端的number,并且根據ip link|number:檢視到對應的veth裝置名稱(即qvo)。

qvb是quamtum veth bridge

qvo是quamtum veth open vswitch

qvoXXX裝置連接配接到了Open vSwitch裝置的br-int內建網橋上

9)通過Open vSwitch 中的指令ovs-vsctl port-to-br qvoXXX檢視qvoXXX裝置所屬的bridge。

# ovs-vsctl port-to-br qvoc08d85da-69

br-int

10)檢視所有的網橋

# ovs-vsctl list-br

bond-br

br-int

11)檢視OVS Bridge上面有哪些端口

# ovs-vsctl list-ports br-int

int-bond-br

qvo077eac35-ed

qvo1ee66407-69

qvo40816622-cf

qvo849c4847-1e

qvoace90c57-d3

qvob0b730ab-79

qvob32e78ae-7f

qvoc08d85da-69

qvodec9ff3a-92

qvoe2028755-37

qvofb9c19ea-6a

tap52a2315f-19

tap63754766-e1

# ovs-vsctl list-ports bond-br

eth3

phy-bond-br

br-int和phy-bond-br端口是用來連接配接Open Vswitch裝置的br-int和bond-br

(即br-ethX)網橋。另外,VLAN ID的轉換是發生在br-int和bond-br網橋的端口br-int和phy-bond-br上面的。

從br-int進來的資料包,其VLAN ID 會被轉換為内部的VLAN ID。同理,從網絡出去的資料包,經過phy-bond-br,VLAN ID會将内部VLAN ID 轉化為外部VLAN ID。

12)通過ethtool -S 指令檢視br-int的對端裝置number;并通過ip link |grep number檢視br-int的對端裝置(即phy-bond-br)。

# ethtool -S br-int

# ip link | grep number

13)檢視phy-bond-br連接配接到的虛拟外部網橋。

# ovs-vsctl port-to-br phy-bond-br

bond-br

14)檢視外部網橋bond-br(即br-ethX橋)上的端口:

# ovs-vsctl list-ports bond-br

eth3

phy-bond-br

關于本例子中的bond-br外部網橋和實體網口ethX的關系是:VM資料包要到外部實體網絡中,必須依靠真正的實體網卡。

這種關聯,需要通過手動方式建立,這裡是:

# ovs-vsctl add-port bond-br eth3。

2. 小結

基于上述資料通信流程,這樣整個VM的資料鍊路便完全打通了。從VM的端口到qvoXXX接口的資訊及網橋和端口的連接配接情況,再結合tcpdump 指令檢視網絡流量和OVS OpenFlow協定能夠清楚的掌握和梳理Neutron網絡的連接配接架構,作為網絡分析的依據,為故障排除提供堅實的基礎。

一、分析經典的三個節點的Havana的OpenStack中網絡

`

圖1:三節點opens網絡 分為三個網絡: 1、External Network/API Network,這個網絡是連結外網的,無論是使用者調用OpenStack的API,還是建立出來的虛拟機要通路外網,或者外網要ssh到虛拟機,都需要通過這個網絡 2、Data Network,資料網絡,虛拟機之間的資料傳輸通過這個網絡來進行,比如一個虛拟機要連接配接到另一個虛拟機,虛拟機要連接配接虛拟路由都是通過這個網絡來進行 3、Management Network,管理網絡,OpenStack各個子產品之間的互動,連接配接資料庫,連接配接Message Queue都是通過這個網絡來進行。 将這三個網絡隔離,一方面是安全,在虛拟機裡面,無論采用什麼手段,幹擾的都僅僅是Data Network,都不可能通路到我的資料庫。一方面是流量分離,Management Network的流量不是很大的,而且一般都會比較優雅的使用,而Data Network和External Network就需要有流量控制政策。 這個網絡結構有點奇怪,除了Controlller節點是兩張網卡之外,其他的都多了一張網卡連接配接到External Network。這個網卡是用來做apt-get的,因為Compute Node按說是沒有網卡連接配接到外網的,為了apt-get添加了eth0;NetWork Node雖然有一個網卡eth1是連接配接外網的,而在neutron配置好之前,這個網卡通常是沒有IP的,為了apt-get也添加了eth0;有人說可以通過route規則都通過Controller連接配接到外網,但是對于初學者,這樣比較容易操作。

二、neutron三個節點簡介 neutron是用來建立虛拟網絡的,所謂虛拟網絡,就是虛拟機啟動的時候會有一個虛拟網卡,虛拟網卡會連接配接到虛拟switch上,虛拟交換機連接配接到虛拟router上,虛拟路由器最終和實體網卡聯通,進而虛拟網絡和實體網絡聯通起來。 neutron分成多個子產品分布在三個節點上。

1.Controller節點: neutron-server,用于接受API請求建立網絡,子網,路由器等,然而建立的這些東西僅僅是一些資料結構在資料庫裡面

2.Network節點: neutron-l3-agent,用于建立和管理虛拟路由器,當neutron-server将路由器的資料結建構立好,neutron-l3-agent是做具體事情的,真正的調用指令行将虛拟路由器,路由表,namespace,iptables規則全部建立好。 neutron-dhcp-agent,用于建立和管理虛拟DHCP server,每個虛拟網絡都會有一個DHCP server,這個DHCP server為這個虛拟網絡裡面的虛拟機提供IP。 neutron-openvswitch-plugin-agent,這個是用于建立L2的switch的,在Network節點上,Router和DHCP Server都會連接配接到二層的switch上

3.Compute節點: neutron-openstackvswitch-plugin-agent,這個是用于建立L2層switch的,在compute節點上,虛拟機的網卡也是連接配接到二層的switch上。

三、租戶網絡建立過程 當我們搭建好了OpenStack,然後建立好了tenant後,我們會為這個tenant建立一個網絡。

圖2:租戶網絡建立過程 結合上圖說明給一個租戶建立網絡的流程: 1、為這個Tenant建立一個private network,不同的private network是需要通過VLAN tagging進行隔離的,互相之間廣播(broadcast)不能到達,這裡我們我們用的是GRE模式,也需要一個類似VLANID的東西,稱為Segment ID 2、為private network建立一個subnet,subnet才是真正配置IP網段的地方,對于私網,我們常常用192.168.0.0/24這個網段 3、為這個Tenant建立一個Router,才能夠通路外網 4、将private network連接配接到Router上 5、建立一個External Network 6、建立一個External Network的Subnet,這個外網邏輯上代表了我們資料中心的實體網絡,通過這個實體網絡,我們可以通路外網。因而PUBLIC_GATEWAY應該設為資料中心裡面的Gateway,PUBLCI_RANGE也應該和資料中心的實體網絡的CIDR一緻,否則連不通。之是以設定PUBLIC_START和PUBLIC_END,是因為在資料中心中,不可能所有的IP位址都給OpenStack使用,另外的可能搭建了VMware Vcenter,可能有實體機,是以僅僅配置設定一個區間給OpenStack來用。 7、将Router連接配接到External Network 經過這個流程,從虛拟網絡到實體網絡即邏輯上聯通了。 openstack網絡(neutron)模式之GRE的基本原理

neutron網絡目的是為OpenStack雲更靈活的劃分網絡,在多租戶的環境下提供給每個租戶獨立的網絡環境。

neutron混合實施了第二層的VLAN和第三層的路由服務,它可為支援的網絡提供防火牆,負載均衡以及IPSec VPN等擴充功能。

neutron是openstack中一個重要子產品,也是比較難了解和debug的子產品之一。

一、分析經典的三個節點的Havana的OpenStack中網絡

圖1:三節點opens網絡

分為三個網絡:

1、External Network/API Network,這個網絡是連結外網的,無論是使用者調用OpenStack的API,還是建立出來的虛拟機要通路外網,或者外網要ssh到虛拟機,都需要通過這個網絡

2、Data Network,資料網絡,虛拟機之間的資料傳輸通過這個網絡來進行,比如一個虛拟機要連接配接到另一個虛拟機,虛拟機要連接配接虛拟路由都是通過這個網絡來進行

3、Management Network,管理網絡,OpenStack各個子產品之間的互動,連接配接資料庫,連接配接Message Queue都是通過這個網絡來進行。

将這三個網絡隔離,一方面是安全,在虛拟機裡面,無論采用什麼手段,幹擾的都僅僅是Data Network,都不可能通路到我的資料庫。一方面是流量分離,Management Network的流量不是很大的,而且一般都會比較優雅的使用,而Data Network和External Network就需要有流量控制政策。

這個網絡結構有點奇怪,除了Controlller節點是兩張網卡之外,其他的都多了一張網卡連接配接到External Network。這個網卡是用來做apt-get的,因為Compute Node按說是沒有網卡連接配接到外網的,為了apt-get添加了eth0;NetWork Node雖然有一個網卡eth1是連接配接外網的,而在neutron配置好之前,這個網卡通常是沒有IP的,為了apt-get也添加了eth0;有人說可以通過route規則都通過Controller連接配接到外網,但是對于初學者,這樣比較容易操作。

二、neutron三個節點簡介

neutron是用來建立虛拟網絡的,所謂虛拟網絡,就是虛拟機啟動的時候會有一個虛拟網卡,虛拟網卡會連接配接到虛拟switch上,虛拟交換機連接配接到虛拟router上,虛拟路由器最終和實體網卡聯通,進而虛拟網絡和實體網絡聯通起來。

neutron分成多個子產品分布在三個節點上。

1.Controller節點:

neutron-server,用于接受API請求建立網絡,子網,路由器等,然而建立的這些東西僅僅是一些資料結構在資料庫裡面

2.Network節點:

neutron-l3-agent,用于建立和管理虛拟路由器,當neutron-server将路由器的資料結建構立好,neutron-l3-agent是做具體事情的,真正的調用指令行将虛拟路由器,路由表,namespace,iptables規則全部建立好。

neutron-dhcp-agent,用于建立和管理虛拟DHCP server,每個虛拟網絡都會有一個DHCP server,這個DHCP server為這個虛拟網絡裡面的虛拟機提供IP。

neutron-openvswitch-plugin-agent,這個是用于建立L2的switch的,在Network節點上,Router和DHCP Server都會連接配接到二層的switch上。

3.Compute節點:

neutron-openstackvswitch-plugin-agent,這個是用于建立L2層switch的,在compute節點上,虛拟機的網卡也是連接配接到二層的switch上。

三、租戶網絡建立過程

當我們搭建好了OpenStack,然後建立好了tenant後,我們會為這個tenant建立一個網絡。

圖2:租戶網絡建立過程

結合上圖說明給一個租戶建立網絡的流程:

1、為這個Tenant建立一個private network,不同的private network是需要通過VLAN tagging進行隔離的,互相之間廣播(broadcast)不能到達,這裡我們我們用的是GRE模式,也需要一個類似VLANID的東西,稱為Segment ID

2、為private network建立一個subnet,subnet才是真正配置IP網段的地方,對于私網,我們常常用192.168.0.0/24這個網段

3、為這個Tenant建立一個Router,才能夠通路外網

4、将private network連接配接到Router上

5、建立一個External Network

6、建立一個External Network的Subnet,這個外網邏輯上代表了我們資料中心的實體網絡,通過這個實體網絡,我們可以通路外網。因而PUBLIC_GATEWAY應該設為資料中心裡面的Gateway,PUBLCI_RANGE也應該和資料中心的實體網絡的CIDR一緻,否則連不通。之是以設定PUBLIC_START和PUBLIC_END,是因為在資料中心中,不可能所有的IP位址都給OpenStack使用,另外的可能搭建了VMware Vcenter,可能有實體機,是以僅僅配置設定一個區間給OpenStack來用。

7、将Router連接配接到External Network

經過這個流程,從虛拟網絡到實體網絡即邏輯上聯通了。

代碼流程如下:

#!/bin/bash 

TENANT_NAME="openstack"   

TENANT_NETWORK_NAME="openstack-net"   

TENANT_SUBNET_NAME="${TENANT_NETWORK_NAME}-subnet"   

TENANT_ROUTER_NAME="openstack-router"   

FIXED_RANGE="192.168.0.0/24"   

NETWORK_GATEWAY="192.168.0.1"


PUBLIC_GATEWAY="172.24.1.1"  

PUBLIC_RANGE="172.24.1.0/24"   

PUBLIC_START="172.24.1.100"     

PUBLIC_END="172.24.1.200" 

TENANT_ID=$(keystone tenant-list | grep " $TENANT_NAME " | awk '{print $2}')


(1) TENANT_NET_ID=$(neutron net-create --tenant_id $TENANT_ID 
$TENANT_NETWORK_NAME --provider:network_type gre 
--provider:segmentation_id 1 | grep " id " | awk '{print $4}')   

(2) TENANT_SUBNET_ID=$(neutron subnet-create --tenant_id $TENANT_ID 
--ip_version 4 --name $TENANT_SUBNET_NAME $TENANT_NET_ID $FIXED_RANGE 
--gateway $NETWORK_GATEWAY --dns_nameservers list=true 8.8.8.8 | grep " 
id " | awk '{print $4}')  

(3) ROUTER_ID=$(neutron router-create --tenant_id 
$TENANT_ID $TENANT_ROUTER_NAME | grep " id " | awk '{print $4}')

(4) neutron router-interface-add $ROUTER_ID $TENANT_SUBNET_ID

(5) neutron net-create public --router:external=True

(6) neutron subnet-create --ip_version 4 --gateway $PUBLIC_GATEWAY 
public $PUBLIC_RANGE --allocation-pool 
start=$PUBLIC_START,end=$PUBLIC_END --disable-dhcp --name public-subnet

(7) neutron router-gateway-set ${TENANT_ROUTER_NAME} public      

四、GRE模式下網絡細節

建立完網絡,如果不建立虛拟機,我們發現neutron的agent還是做了很多工作的,建立了很多虛拟網卡和switch。

在compute節點上:

[email protected]:~# ip addr 【顯示所有接口的IP資訊】

1: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000    
    link/ether 08:00:27:49:5c:41 brd ff:ff:ff:ff:ff:ff    
    inet 172.24.1.124/22 brd 16.158.167.255 scope global eth0    
2: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000    
    link/ether 08:00:27:8e:42:2c brd ff:ff:ff:ff:ff:ff    
    inet 192.168.56.124/24 brd 192.168.56.255 scope global eth2    
3: eth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000    
    link/ether 08:00:27:68:92:ce brd ff:ff:ff:ff:ff:ff    
    inet 10.10.10.124/24 brd 10.10.10.255 scope global eth3    
4: br-int: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN     
    link/ether d6:2a:96:12:4a:49 brd ff:ff:ff:ff:ff:ff    
5: br-tun: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN     
    link/ether a2:ee:75:bd:af:4a brd ff:ff:ff:ff:ff:ff    
6: qvof5da998c-82: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000    
    link/ether c2:7e:50:de:8c:c5 brd ff:ff:ff:ff:ff:ff    
7: qvbf5da998c-82: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000    
    link/ether c2:33:73:40:8f:e0 brd ff:ff:ff:ff:ff:ff         

[email protected]:~# ovs-vsctl show 【檢視open vswitch網橋】

39f69272-17d4-42bf-9020-eecc9fe8cde6    
    Bridge br-int    
        Port patch-tun    
            Interface patch-tun    
                type: patch    
                options: {peer=patch-int}    
        Port br-int    
            Interface br-int    
                type: internal    
    Bridge br-tun    
        Port patch-int    
            Interface patch-int    
                type: patch    
                options: {peer=patch-tun}    
        Port "gre-1"    
            Interface "gre-1"    
                type: gre    
                options: {in_key=flow, local_ip="10.10.10.124", out_key=flow, remote_ip="10.10.10.121"}    
        Port br-tun    
            Interface br-tun    
                type: internal    
    ovs_version: "1.10.2"      

在Network 節點上:

[email protected]:~# ip addr 【顯示所有接口的IP資訊】

1: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000    
    link/ether 08:00:27:22:8a:7a brd ff:ff:ff:ff:ff:ff    
    inet 172.24.1.121/22 brd 172.24.1.255 scope global eth0    
2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000    
    link/ether 08:00:27:f1:31:81 brd ff:ff:ff:ff:ff:ff    
3: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000    
    link/ether 08:00:27:56:7b:8a brd ff:ff:ff:ff:ff:ff    
    inet 192.168.56.121/24 brd 192.168.56.255 scope global eth2    
4: eth3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000    
    link/ether 08:00:27:26:bc:84 brd ff:ff:ff:ff:ff:ff    
    inet 10.10.10.121/24 brd 10.10.10.255 scope global eth3    
5: br-ex: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN     
    link/ether 08:00:27:f1:31:81 brd ff:ff:ff:ff:ff:ff    
    inet 172.24.1.8/24 brd 172.24.1.255 scope global br-ex    
6: br-int: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN     
    link/ether 22:fe:f1:9b:29:4b brd ff:ff:ff:ff:ff:ff    
7: br-tun: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN     
    link/ether c6:ea:94:ff:23:41 brd ff:ff:ff:ff:ff:ff         

[email protected]:~# ip netns 【列出網絡命名空間】

qrouter-b2510953-1ae4-4296-a628-1680735545ac    
qdhcp-96abd26b-0a2f-448b-b92c-4c98b8df120b      

[email protected]:~# ip netns exec qrouter-b2510953-1ae4-4296-a628-1680735545ac ip addr 【利用網絡命名空間進行操作】

8: qg-97040ca3-2c: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN     
    link/ether fa:16:3e:26:57:e3 brd ff:ff:ff:ff:ff:ff    
    inet 172.24.1.100/24 brd 172.24.1.255 scope global qg-97040ca3-2c    
11: qr-e8b97930-ac: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN 
    link/ether fa:16:3e:43:ef:16 brd ff:ff:ff:ff:ff:ff    
    inet 192.168.0.1/24 brd 192.168.0.255 scope global qr-e8b97930-ac         

[email protected]:~# ip netns exec qdhcp-96abd26b-0a2f-448b-b92c-4c98b8df120b ip addr 【利用網絡命名空間進行操作】

9: tapde5739e1-95: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN     
    link/ether fa:16:3e:19:8c:67 brd ff:ff:ff:ff:ff:ff    
    inet 192.168.0.2/24 brd 192.168.0.255 scope global tapde5739e1-95    
    inet 169.254.169.254/16 brd 169.254.255.255 scope global tapde5739e1-95         

[email protected]:~# ovs-vsctl show 【檢視open vswitch的網絡狀态】

d5d5847e-1c9e-4770-a68c-7a695b7b95cd    
    Bridge br-ex    
        Port "qg-97040ca3-2c"    
            Interface "qg-97040ca3-2c"    
                type: internal    
        Port "eth1"    
            Interface "eth1"    
        Port br-ex    
            Interface br-ex    
                type: internal    
    Bridge br-int    
        Port patch-tun    
            Interface patch-tun    
                type: patch    
                options: {peer=patch-int}    
        Port "tapde5739e1-95"    
            tag: 1    
            Interface "tapde5739e1-95"    
                type: internal    
        Port br-int    
            Interface br-int    
                type: internal    
        Port "qr-e8b97930-ac"    
            tag: 1    
            Interface "qr-e8b97930-ac"    
                type: internal    
    Bridge br-tun    
        Port patch-int    
            Interface patch-int    
                type: patch    
                options: {peer=patch-tun}    
        Port "gre-2"    
            Interface "gre-2"    
                type: gre    
                options: {in_key=flow, local_ip="10.10.10.121", out_key=flow, remote_ip="10.10.10.124"}    
        Port br-tun    
            Interface br-tun    
                type: internal    
    ovs_version: "1.10.2"      

這時如果我們在這個網絡裡建立一個虛拟機,在Compute Node多了下面的網卡:

13: qvof5da998c-82: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000   
    link/ether c2:7e:50:de:8c:c5 brd ff:ff:ff:ff:ff:ff    
14: qvbf5da998c-82: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 
    link/ether c2:33:73:40:8f:e0 brd ff:ff:ff:ff:ff:ff    
15: qbr591d8cc4-df: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP     
    link/ether f2:d9:f0:d5:48:c8 brd ff:ff:ff:ff:ff:ff    
16: qvo591d8cc4-df: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000    
    link/ether e2:58:d4:dc:b5:16 brd ff:ff:ff:ff:ff:ff    
17:
qvb591d8cc4-df: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 
1500 qdisc pfifo_fast master qbr591d8cc4-df state UP qlen 1000    
    link/ether f2:d9:f0:d5:48:c8 brd ff:ff:ff:ff:ff:ff    
18:
tap591d8cc4-df: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc 
pfifo_fast master qbr591d8cc4-df state UNKNOWN qlen 500    
    link/ether fe:16:3e:6e:ba:d0 brd ff:ff:ff:ff:ff:ff         

如果我們按照ovs-vsctl show的網卡橋接關系,便可以畫出下面的圖

圖3:GRE網絡

GRE網絡原理:

假設虛拟機VM0網卡eth0有網絡資料包向外網發送,那麼資料會依次經過qbr Linux Bridge裝置,qvb和qvo虛拟網絡裝置,到達OVS網橋br-int上,br-int将資料包attach到OVS網橋br-tun上,資料包再從compute節點OVS網橋的br-tun和network節點OVS網橋br-tun構成的GRE隧道穿過,傳遞到Network節點的OVS網橋br-int上;網絡節點的br-int通過qr裝置借助Linux命名空間qrouter連通到br-ex上的qg裝置,将資料包傳遞到OVS網橋br-ex上,最後br-ex通過網絡節點的外部武力端口eth1把資料包傳送到外部路由器的網關。

五、通過例子了解GRE網絡

openstack為什麼要建立這麼多的虛拟網卡?

這些網卡看起來複雜,卻是各有用處,這種虛拟網絡拓撲,正是我們經常使用的實體網絡的拓撲結構。

下面通過一個非常容易了解的例子來逐漸分析gre網絡。

我們先來回到一個最最熟悉不過的場景,我們的大學寝室,當時我們還買不起路由器,是以一般采取的方法如下圖所示:

寝室長的機器上弄兩張網卡,寝室買一個HUB,其他人的電腦都接到HUB上,寝室長的電腦的兩張網卡一張對外連接配接網絡,一張對内連接配接HUB。寝室長的電腦其實充當的便是路由器的作用。

後來條件好了,路由器也便宜了,是以很多家庭也是類似的拓撲結構,隻不過将Computer1和switch合起來,變成了一個路由器,路由器也是有多個口一個連接配接WLAN,一個連接配接LAN。

圖4

現在我們想象一個寝室變成了一台Hypervisor,所有的電腦都變成了虛拟機,就變成了下面的樣子:

圖5:單節點的openstack的網絡結構

我們先忽略qbr和DHCP Server,以及namespace。

br-int就是寝室裡的HUB,所有虛拟機都會連接配接到這個switch上,虛拟機之間的互相通信就是通過br-int來的。

Router就是寝室長的電腦,一邊連接配接在br-int上,一邊連接配接在對外的網口上,br-ex/eth0外面就是我們的實體網絡。

圖5其實就是單節點的openstack的網絡結構,雖然複雜,但是就是把我們家裡的,或者寝室裡面的實體機搬到一個Hypervisor上了,其結構就不難了解了。

當然單節點的openstack不過是個測試環境,compute節點和network節點也是要分開的,如圖3,每個機器上都有了自己的br-int。

六、GRE網絡原理進一步了解

以下内容可對比圖3來了解

(1)DHCP

為什麼會有個DHCP Server呢,是同一個private network裡的虛拟機得到IP都是通過這個DHCP Server來的,這個DHCP Server也是連接配接到br-int上和虛拟機進行通信的。

(2)qbr

既然qbr和br-int都是網橋,為什麼不直接連到br-int,還要通過qbr,qvb,qvo豈不是多餘,為什麼會有qbr呢?這是和security group的概念有關。簡單說就是OVS網橋br-int沒有設定iptables規則的功能,但openstack又要提供安全組服務,就借助了Linux bridge(qbr)的功能,雖然OVS的br-int和linux bridge (qbr)都是二層網橋,但是為了功能互補就同時出現了。具體了解,openstack中的security group開通哪些端口,屏蔽哪些端口是用iptables來實作的,然而br-int這些虛拟bridge都是openvswitch建立的,openstack的Kernel mode和netfilter的kernel mode不相容。一個IP包進來要麼走iptables規則進行處理,要麼走openvswitch的規則進行處理,br-int上有很多openvswitch的規則,比如vlan tag等,是以iptables必須要另外建立一個linux bridge(qbr)來做,因而就有了qbr,在了解拓撲結構的時候,可以将qbr忽略,看到VM直接連接配接到br-int上就可以了。

(3)namespace

為什麼會有namespace呢,java的namespace是為了在不同namespace下有相同類名,openstack也想做到這一點。不同Tenant都建立自己的router和private network,彼此不知道别人指定了哪些網段,很有可能兩個tenant都指定了192.168.0.0/24,這樣不同的private network的路由表,DHCP Server就需要隔離,不然就亂了,因而就有了namespace。

(4)OVS一體化網橋br-int

每個機器上都有了自己的br-int,但是對于虛拟機和虛拟router來說,它們仍然覺得自己連接配接到了一個大的L2的br-int上,通過這個br-int互相通信的,它們感受不到br-int下面的虛拟網卡br-tun。是以對于多節點結構,我們可以想象br-int是一個大的,橫跨所有compute和network節點的二層switch,虛拟機之間的通信以及虛拟機和Router的通信,就像在一個寝室一樣的。這是一種很重要的抽象思維,好像openstack環境中所有虛拟機都連接配接到了一個巨型的虛拟交換機上。

然而br-int畢竟被實體的割開了,需要有一種方式将他們串聯起來,openstack提供了多種方式,可以用GRE tunnel将不同機器的br-int連接配接起來,也可以通過VLAN将br-int連接配接起來,當然還可以使用vxlan。

這就是為什麼openstack有了br-int這個bridge,但是不把所有的openvswitch的規則都在它上面實作。就是為了提供這種靈活性,對于虛拟機來講,看到的是一大整個br-int,不同機器的br-int可以有多種方式連接配接,這在br-int下面的網卡上面實作。

(5)OVS通道網橋br-tun

br-tun也是OVS建立的虛拟網橋,它是一個中間層,接收br-int的網絡資料,然後在通過特定網絡協定與各個節點的br-tun相連構成一個通道層。如果所有的br-int構成的抽象層定義為虛拟二層網絡,那麼所有的br-tun構成的抽象層邊上虛拟三層網絡了。

(6)網絡資料包隔離

如果有不同的Tenant,建立了不同的private network,為了在data network上對包進行隔離,建立private network的時候,需要指定vlanid或者segmentid。

從ovs-vsctl show我們可以看到,不同的tenant的private network上建立的虛拟機,連接配接到br-int上的時候是帶tag的,是以不同tenant的虛拟機,即便連接配接到同一個br-int上,因為tag不同,也是不能互相通信的。然而同一個機器上的tag的計數是僅在本機有效的,并不使用我們建立private network的時候指定的全局唯一的vlanid或者segmentid,一個compute節點上的br-int上的tag 1和另一台compute節點上的br-int的tag1很可能是兩碼事。全局的vlanid和segmentid僅僅在br-int以下的虛拟網卡和實體網絡中使用,虛拟機所有能看到的東西,到br-int為止,看不到打通br-int所要使用的vlanid和segmentid。

從局部有效的taging到全局有效的vlanid或者segmentid的轉換,都是通過openvswitch的規則,在br-tun或者br-eth1上實作。

繼續閱讀