覺得OpenStack的網絡復雜?其實你家里就有同樣一個網絡


當你想了解OpenStack的Neutron網絡,打開下面這張圖的時候,心里一定是崩潰的,看起來這些模塊連在一起很復雜,但其實和你家里的網絡很像,看不出來?看我來慢慢解析。

 

 

其實這個網絡的樣子更像是我上大學的時候的寢室里面的網絡。

 

作為一個已到中年的80后,在兩千年初上大學的時候,當時家用路由器的價格還很高,所以我們寢室買不起家用路由器,只好買一個hub,將整個寢室的四台電腦連接起來,整個寢室只有一個對外網口,於是寢室長的電腦需要買兩張網卡(當時買另外一張網卡是需要整個寢室分攤錢的),一張連接外網網口,一張連接Hub,其實是充當路由器的作用,其他的室友的網線都插到Hub上,任何一個人要上外網,必須把寢室長的電腦打開才可以。

 

整個寢室的網絡拓撲結構如下:

 

 

如果是現在家里有路由器的,拓撲架構如下:

 

 

家里的路由器一般都會有DHCP功能,家里的設備只要連接到路由器,就會自動被分配一個IP地址,家里的路由器會有一個內網IP地址192.168.1.1,

家里的電腦的網關一般就設置為這個地址,當家里的電腦上網的時候,也是通過路由器,從公網口出去到互聯網上訪問。

 

 

接下來,我們將整個寢室放在一台物理機里面,虛擬機是你的電腦,路由器和DHCP Server相當於家用路由器或者寢室長的電腦,外網網口訪問互聯網,所有的電腦都通過內網網口連接到一個Hub上,名為br-int,虛擬機要想訪問互聯網,需要通過Hub br-int連到路由器上,然后通過路由器將請求轉發到公網。

 

接下來的事情就慘了,你和你的寢室長鬧矛盾了,你們要分開宿舍住,分成兩個宿舍,對應上面的圖,路由器和VM分在兩台物理機上,這下把一個完整的br-int一刀兩斷,一半放在寢室長宿舍,一半放在你的宿舍。

 

可是只有你的寢室長有公網口可以上網,於是你偷偷的在兩個宿舍中間打了一個隧道,用網線通過隧道將兩個宿舍的兩個br-int連接起來,讓你的電腦和你寢室長的電腦感覺上,還是連到同一個br-int上,其實中間通過你的隧道中的網線做了轉發。

 

 

為什么要多一個br-tun這個虛擬交換機呢?主要通過br-int這一層將虛擬機之間的互聯和主機之間的互聯分成兩層來設計,tun的意思就是tunnel,就是隧道,隧道可以各種挖法,GRE,VXLAN都可以。

 

如果兩個寢室之間的互聯是通過VLAN,則結構如下:

 

 

這兩個加起來,是不是最上面的那張圖了。

 

接下來我們詳細解讀各個部分:

 

一、tap/tun設備

 

將guest system的網絡和host system的網絡連在一起

 

Tun/tap驅動程序中包含兩個部分,一部分是字符設備驅動,還有一部分是網卡驅動部分

 

 

二、Openvswitch的基本概念

 

br-int & br-tun由Openvswitch實現

 

Openvswitch是一個virutal switch, 支持Open Flow協議,當然也有一些硬件Switch也支持Open Flow協議,他們都可以被統一的Controller管理,從而實現物理機和虛擬機的網絡聯通。

 

 

Openvswitch創建出來的虛擬交換機會保存很多Flow Table包含許多entry,每個entry是對packet進行處理的規則

 

 

Match Field涵蓋TCP/IP協議各層:

  • Layer 1 – Tunnel ID, In Port, QoS priority, skb mark

  • Layer 2 – MAC address, VLAN ID, Ethernet type

  • Layer 3 – IPv4/IPv6 fields, ARP

  • Layer 4 – TCP/UDP, ICMP, ND

Action也主要包含下面的操作:

  • Output to port (port range, flood, mirror)

  • Discard, Resubmit to table x

  • Packet Mangling (Push/Pop VLAN header, TOS, ...)

  • Send to controller, Learn

 

 

這些Flow Table可以通過OpenFlow協議進行增刪查改。

 

 

這些FlowTable里面的規則執行順序安裝Table的優先級來,高優先級的先執行,低優先級的后執行,執行過程中可任意修改網絡包的內容,修改完畢后,可以扔給另一個Table,也可以直接output從一個虛擬口將包發出來。

 

三、解析br-int

 

br-int主要使用openvswitch中port的vlan功能

 

Port的一個重要的方面就是VLAN Configuration,有兩種模式:

 

模式一:trunk port

  • 這個port不配置tag,配置trunks

  • 如果trunks為空,則所有的VLAN都trunk,也就意味着對於所有的VLAN的包,本身帶什么VLAN ID,就是攜帶者什么VLAN ID,如果沒有設置VLAN,就屬於VLAN 0,全部允許通過。

  • 如果trunks不為空,則僅僅帶着這些VLAN ID的包通過。

模式二:access port

  • 這個port配置tag,從這個port進來的包會被打上這個tag

  • 如果從其他的trunk port中進來的本身就帶有VLAN ID的包,如果VLAN ID等於tag,則會從這個port發出

  • 從其他的access port上來的包,如果tag相同,也會被forward到這個port

  • 從access port發出的包不帶VLAN ID

  • 如果一個本身帶VLAN ID的包到達access port,即便VLAN ID等於tag,也會被拋棄。

 

例如要創建如下的虛擬網絡和虛擬交換機

 

 

執行以下的命令

 

ovs-vsctl add-br ubuntu_br

 

ip link add first_br type veth peer name first_if

ip link add second_br type veth peer name second_if

ip link add third_br type veth peer name third_if

 

ovs-vsctl add-port ubuntu_br first_br

ovs-vsctl add-port ubuntu_br second_br

ovs-vsctl add-port ubuntu_br third_br

ovs-vsctl set Port vnet0 tag=101

ovs-vsctl set Port vnet1 tag=102

ovs-vsctl set Port vnet2 tag=103

ovs-vsctl set Port first_br tag=103

ovs-vsctl clear Port second_br tag

ovs-vsctl set Port third_br trunks=101,102

需要監聽ARP,所以禁止MAC地址學習

ovs-vsctl set bridge ubuntu_br flood-vlans=101,102,103

 

實驗結果如下:

 

從192.168.100.102來ping 192.168.100.103,應該first_if和second_if能夠收到包

從192.168.100.100在ping 192.168.100.105, 則second_if和third_if可以收到包

從192.168.100.101來ping 192.168.100.104, 則second_if和third_if可以收到包

 

四、解析br-tun

 

br-tun主要使用openvswitch的tunnel功能和Flow功能。

 

Openvswitch支持三類Tunnel:gre,vxlan,ipsec_gre。

 

命令分別如下:

 

ovs-vsctl add-br testbr

 

ovs-vsctl add-port testbr gre0 -- set Interface gre0 type=gre options:local_ip=192.168.100.100 options:remote_ip=192.168.100.101

 

ovs-vsctl add-port testbr vxlan0 -- set Interface vxlan0 type=vxlan options:local_ip=192.168.100.100 options:remote_ip=192.168.100.102

 

ovs-vsctl add-port testbr ipsec0 -- set Interface ipsec0 type=ipsec_gre options:local_ip=192.168.100.101 options:remote_ip=192.168.100.102 options:psk=password

 

對於Flow Table的管理,由ovs-ofctl來控制

  • add−flow switch flow

  • mod−flows switch flow

  • del−flows switch [flow]

主要控制兩類

  • Match Field

  • Actions

 

對於Match Field,不同網絡層的表示方式不同,如下:

 

Actions有以下幾類:

  • output:port 和 output:NXM_NX_REG0[16..31]

  • enqueue:port:queue

  • mod_vlan_vid:vlan_vid

  • strip_vlan

  • mod_dl_src:mac 和 mod_dl_dst:mac

  • mod_nw_src:ip 和 mod_nw_dst:ip

  • mod_tp_src:port 和 mod_tp_dst:port

  • set_tunnel:id

  • resubmit([port],[table])

  • move:src[start..end]−>dst[start..end]

  • load:value−>dst[start..end]

  • learn(argument[,argument]...)

 

我們模擬創建一個如下的網絡拓撲結構,模擬OpenStack里面的行為

 

 

Flow Table的設計如下:

 

 

下面詳細描述FlowTable的添加過程,OpenStack也是這樣一個個規則添加進去的。

 

(1) 刪除所有的Flow

 

ovs-ofctl del-flows br-tun

 

(2) Table 0

 

從port 1進來的,由table 1處理

 

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0 priority=1 in_port=1 actions=resubmit(,1)"

 

從port 2/3進來的,由Table 3處理

 

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0 priority=1 in_port=2 actions=resubmit(,3)"

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0 priority=1 in_port=3 actions=resubmit(,3)"

 

默認丟棄

 

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0 priority=0 actions=drop"

 

(3) Table 1

 

對於單播,由table 20處理

 

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0 priority=1 table=1 dl_dst=00:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,20)"

 

對於多播,由table 21處理

 

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0 priority=1 table=1 dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=resubmit(,21)"

 

(4) Table 2

 

默認丟棄

 

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0 priority=0 table=2 actions=drop"

 

(5) Table 3

 

默認丟棄

 

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0 priority=0 table=3 actions=drop"

 

Tunnel ID -> VLAN ID

 

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0 priority=1 table=3 tun_id=0x1 actions=mod_vlan_vid:1,resubmit(,10)"

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0 priority=1 table=3 tun_id=0x2 actions=mod_vlan_vid:2,resubmit(,10)"

 

(6) Table 10

 

MAC地址學習

 

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0 priority=1 table=10  actions=learn(table=20,priority=1,hard_timeout=300,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:0->NXM_OF_VLAN_TCI[],load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],output:NXM_OF_IN_PORT[]),output:1"

 

 

  • Table 10是用來學習MAC地址的,學習的結果放在Table 20里面,Table20被稱為MAC learning table

  • NXM_OF_VLAN_TCI這個是VLAN Tag,在MAC Learning table中,每一個entry都是僅僅對某一個VLAN來說的,不同VLAN的learning table是分開的。在學習的結果的entry中,會標出這個entry是對於哪個VLAN的。

  • NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[]這個的意思是當前包里面的MAC Source Address會被放在學習結果的entry里面的dl_dst里面。這是因為每個switch都是通過Ingress包來學習,某個MAC從某個port進來,switch就應該記住以后發往這個MAC的包要從這個port出去,因而MAC source address就被放在了Mac destination address里面,因為這是為發送用的。

  • load:0->NXM_OF_VLAN_TCI[]意思是發送出去的時候,vlan tag設為0,所以結果中有actions=strip_vlan

  • load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[]意思是發出去的時候,設置tunnel id,進來的時候是多少,發送的時候就是多少,所以結果中有set_tunnel:0x3e9

  • output:NXM_OF_IN_PORT[]意思是發送給哪個port,由於是從port2進來的,因而結果中有output:2

 

(7) Table 20

 

這個是MAC Address Learning Table,如果不空就按照規則處理

如果為空,就使用默認規則,交給Table 21處理

 

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0 priority=0 table=20 actions=resubmit(,21)"

 

(8) Table 21

 

默認丟棄

 

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0 priority=0 table=21 actions=drop"

 

VLAN ID -> Tunnel ID

 

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0 priority=1table=21dl_vlan=1 actions=strip_vlan,set_tunnel:0x1,output:2,output:3"

ovs-ofctl add-flow br-tun "hard_timeout=0 idle_timeout=0 priority=1table=21dl_vlan=2 actions=strip_vlan,set_tunnel:0x2,output:2,output:3"

 

五、解析Router

 

使用namespace中的routing table

 

ip netns exec qrouter-5a74908c-712c-485c-aa9f-6c1e8b57e3e1 route -n

Kernel IP routing table

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

0.0.0.0         16.158.164.1    0.0.0.0         UG    0      0        0 qg-52de6441-db

10.0.0.0        0.0.0.0         255.255.255.0   U     0      0        0 qr-e0967604-78

16.158.164.0    0.0.0.0         255.255.252.0   U     0      0        0 qg-52de6441-db

 

Floating IP使用namespace中的iptables的nat

 

ip netns exec qrouter-5a74908c-712c-485c-aa9f-6c1e8b57e3e1 iptables -t nat -nvL

 

 

六、解析br-ex

 

將namespace中的網絡和namespace外的網絡連接起來

 

歡迎關注微信公眾號

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM