軟件定義網絡(SDN)
主要有以下三個特點:
- 控制與轉發分離:轉發平面就是一個個虛擬或者物理的網絡設備,就像小區里面的一條條路。控制平面就是統一的控制中心,就像小區物業的監控室。它們原來是一起的,物業管理員要從監控室出來,到路上去管理設備,現在是分離的,路就是走人的,控制都在監控室。
- 控制平面與轉發平面之間的開放接口:控制器向上提供接口,被應用層調用,就像總控室提供按鈕,讓物業管理員使用。控制器向下調用接口,來控制網絡設備,就像總控室會遠程控制電梯的速度。這里經常使用兩個名詞,前面這個接口稱為北向接口,后面這個接口稱為南向接口,上北下南嘛。
- 邏輯上的集中控制:邏輯上集中的控制平面可以控制多個轉發面設備,也就是控制整個物理網絡,因而可以獲得全局的網絡狀態視圖,並根據該全局網絡狀態視圖實現對網絡的優化控制,就像物業管理員在監控室能夠看到整個小區的情況,並根據情況優化出入方案
如下圖:
OpenFlow和OpenvSwitch
OpenFlow是SDN控制器和網絡設備之間互通的南向接口協議,OpenvSwitch用於創建軟件的虛擬交換機。OpenvSwitch是支持OpenFlow協議的,當然也有一些硬件交換機也支持OpenFlow
協議。它們都可以被統一的SDN控制器管理,從而實現物理機和虛擬機的網絡連通。
如下圖:
在OpenvSwitch里面,有一個流表規則,任何通過這個交換機的包,都會經過這些規則進行處理,從而接收、轉發、放棄。每個表格好多行,每行都是一條規則。每條規則都有優先級,先看高優先級的規則,再看低優先級的規則。
每一條規則,要看是否滿足匹配條件。這些條件包括,從哪個端口進來的,網絡包頭里面有什么等等。滿足了條件的網絡包,就要執行一個動作,對這個網絡包進行處理。可以修改包頭里的內容,可以跳到任何一個表格,可以轉發到某個網口出去,也可以丟棄。
對於物理層:
- 匹配規則包括由從哪個口進來;
- 執行動作包括從哪個口出去。
對於MAC層:
- 匹配規則包括:源MAC地址是多少?(dl_src),目標MAC是多少?(dl_dst),所屬vlan是多少?(dl_vlan);
- 執行動作包括:修改源MAC(mod_dl_src),修改目標MAC(mod_dl_dst),修改VLAN(mod_vlan_vid),刪除VLAN(strip_vlan),MAC地址學習(learn)。
對於網絡層:
- 匹配規則包括:源IP地址是多少?(nw_src),目標IP是多少?(nw_dst)。
- 執行動作包括:修改源IP地址(mod_nw_src),修改目標IP地址(mod_nw_dst)。
對於傳輸層:
- 匹配規則包括:源端口是多少?(tp_src),目標端口是多少?(tp_dst)。
- 執行動作包括:修改源端口(mod_tp_src),修改目標端口(mod_tp_dst)。
總而言之,對於OpenvSwitch來講,網絡包到了我手里,就是一個Buffer,我想怎么改怎么改,想發到哪個端口就發送到哪個端口。
openvswitch實驗
創建交換機
ovs-vsctl add-br ubuntu_br
實驗一:用OpenvSwitch實現VLAN的功能
下面我們實驗一下通過OpenvSwitch實現VLAN的功能,在OpenvSwitch中端口port分兩種。
第一類是access port:
- 這個端口配置tag,從這個端口進來的包會被打上這個tag;
- 如果網絡包本身帶有的VLAN ID等於tag,則會從這個port發出;
- 從access port發出的包不帶VLAN ID。
第二類是trunk port:
- 這個port不配置tag,配置trunks;
- 如果trunks為空,則所有的VLAN都trunk,也就意味着對於所有VLAN的包,本身帶什么VLAN ID,就是攜帶者什么VLAN ID,如果沒有設置VLAN,就屬於VLAN 0,全部允許通過;
- 如果trunks不為空,則僅僅帶着這些VLAN ID的包通過。
我們通過以下命令創建如下的環境:
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
另外要配置禁止MAC地址學習。
vs-vsctl set bridge ubuntu_br flood-vlans=101,102,103
實驗拓撲:
創建好了環境以后,我們來做這個實驗。
1. 從192.168.100.102來ping 192.168.100.103,然后用tcpdump進行抓包。first_if收到包了,從first_br出來的包頭是沒有VLAN ID的。second_if也收到包了,由於second_br是trunk
port,因而出來的包頭是有VLAN ID的,third_if收不到包。
2. 從192.168.100.100來ping 192.168.100.105, 則second_if和third_if可以收到包,當然ping不通,因為third_if不屬於某個VLAN。first_if是收不到包的。second_if能夠收到包,而且包里
面是VLAN ID=101。third_if也能收到包,而且包頭里面是VLAN ID=101。
3. 從192.168.100.101來ping 192.168.100.104, 則second_if和third_if可以收到包。first_if是收不到包的。second_br能夠收到包,而且包頭里面是VLAN ID=102。third_if也能收到包,而且包頭里面是VLAN ID=102。
實驗二:用OpenvSwitch模擬網卡綁定,連接交換機
在OpenvSwitch里面,有個bond_mode,可以設置為以下三個值:
- active-backup:一個連接是active,其他的是backup,當active失效的時候,backup頂上;
- balance-slb:流量安裝源MAC和output VLAN進行負載均衡;
- balance-tcp:必須在支持LACP協議的情況下才可以,可根據L2, L3, L4進行負載均衡。
拓撲結構:
創建bond
ovs-vsctl add-bond br0 bond0 first_br second_br
ovs-vsctl add-bond br1 bond1 first_if second_if
ovs-vsctl set Port bond0 lacp=active
ovs-vsctl set Port bond1 lacp=active
默認情況下bond_mode是active-backup模式,一開始active的是first_br和first_if
測試192.168.100.100 ping 192.168.100.102,以及從192.168.100.101 ping 192.168.100.103的時候,tcpdump可以看到所有的包都是從first_if通過。
如果把first_if設成down,則包的走向會變,發現second_if開始有流量,對於192.168.100.100和192.168.100.101似乎沒有收到影響。
如果我們通過以下命令,把bond_mode設為balance-slb。然后我們同時在192.168.100.100 ping 192.168.100.102,在192.168.100.101 ping 192.168.100.103,我們通過tcpdump現包已經被分流了。
ovs-vsctl set Port bond0 bond_mode=balance-slb
ovs-vsctl set Port bond1 bond_mode=balance-slb
OpenvSwitch的架構圖
OpenvSwitch包含很多的模塊,在用戶態有兩個重要的進程,也有兩個重要的命令行工具。
- 第一個進程是OVSDB進程。ovs-vsctl命令行會和這個進程通信,去創建虛擬交換機,創建端口,將端口添加到虛擬交換機上,OVSDB會將這些拓撲信息保存在一個本地的文件中。
- 第二個進程是vswitchd進程。ovs-ofctl命令行會和這個進程通信,去下發流表規則,規則里面會規定如何對網絡包進行處理,vswitchd會將流表放在用戶態Flow Table中
在內核態,OpenvSwitch有內核模塊OpenvSwitch.ko,對應圖中的Datapath部分。在網卡上注冊一個函數,每當有網絡包到達網卡的時候,這個函數就會被調用。
在內核的這個函數里面,會拿到網絡包,將各個層次的重要信息拿出來,例如:
- 在物理層,in_port即包進入的網口的ID;
- 在MAC層,源和目的MAC地址;
- 在IP層,源和目的IP地址;
- 在傳輸層,源和目的端口號。
在內核中,有一個內核態Flow Table。接下來內核模塊在這個內核流表中匹配規則,如果匹配上了,則執行操作、修改包,或者轉發或者放棄。如果內核沒有匹配上,則需要進入用戶態,用戶態和內核態之間通過Linux的一個機制Netlink相互通信。
內核通過upcall,告知用戶態進程vswitchd在用戶態Flow Table里面去匹配規則,這里面的規則是全量的流表規則,而內核Flow Table里面的只是為了快速處理,保留了部分規則,內核里面的規則過一陣就會過期。
當在用戶態匹配到了流表規則之后,就在用戶態執行操作,同時將這個匹配成功的流表通過reinject下發到內核,從而接下來的包都能在內核找到這個規則。這里調用openflow協議的,是本地的命令行工具,也可以是遠程的SDN控制器,一個重要的SDN控制器是OpenDaylight。
OpenDaylight拓撲圖
我們可以通過在OpenDaylight里,將兩個交換機之間配置通,也可以配置不通,還可以配置一個虛擬IP地址VIP,在不同的機器之間實現負載均衡等等,所有的策略都可以靈活配置。