上一節我們說到,使用原生的 VLAN 和 Linux 網橋的方式來進行云平臺的管理,但是這樣在靈活性、隔離性方面都顯得不足,而且整個網路缺少統一的視圖、統一的管理,
可以這樣比喻,云計算就像大家一起住公寓,要共享小區里面的基礎設施,其中網路就相當于小區里面的電梯、樓道、路、大門等,大家都走,往往會常出現問題,尤其在上班高峰期,出門的人太多,對小區的物業管理就帶來了挑戰,
物業可以派自己的物業管理人員,到每個單元的樓梯那里,將電梯的上下行速度調快一點,可以派人將隔離健身區、景色區的柵欄門暫時打開,讓大家可以橫穿小區,直接上地鐵,還可以派人將多個小區出入口,改成出口多、入口少等等,等過了十點半,上班高峰過去,再派人都改回來,
軟體定義網路(SDN)
這種模式就像傳統的網路設備和普通的 Linux 網橋的模式,配置整個云平臺的網路通路,你需要登錄到這臺機器上配置這個,再登錄到另外一個設備配置那個,才能成功,
如果物業管理人員有一套智能的控制系統,在物業監控室里就能看到小區里每個單元、每個電梯的人流情況,然后在監控室里面,只要通過遠程控制的方式,撥弄一個手柄,電梯的速度就調整了,柵欄門就打開了,某個入口就改出口了,
這就是軟體定義網路(SDN)software define network,它主要有以下三個特點,

- 控制與轉發分離:轉發平面就是一個個虛擬或者物理的網路設備,就像小區里面的一條條路,控制平面就是統一的控制中心,就像小區物業的監控室,它們原來是一起的,物業管理員要從監控室出來,到路上去管理設備,現在是分離的,路就是走人的,控制都在監控室,
- 控制平面與轉發平面之間的開放介面:控制器向上提供介面,被應用層呼叫,就像總控室提供按鈕,讓物業管理員使用,控制器向下呼叫介面,來控制網路設備,就像總控室會遠程控制電梯的速度,這里經常使用兩個名詞,前面這個介面稱為北向介面,后面這個介面稱為南向介面,上北下南嘛,
- 邏輯上的集中控制:邏輯上集中的控制平面可以控制多個轉發面設備,也就是控制整個物理網路,因而可以獲得全域的網路狀態視圖,并根據該全域網路狀態視圖實作對網路的優化控制,就像物業管理員在監控室能夠看到整個小區的情況,并根據情況優化出入方案,
OpenFlow 和 OpenvSwitch
SDN 有很多種實作方式,我們來看一種開源的實作方式,
OpenFlow 是 SDN 控制器和網路設備之間互通的南向介面協議,OpenvSwitch 用于創建軟體的虛擬交換機,OpenvSwitch 是支持 OpenFlow 協議的,當然也有一些硬體交換機也支持 OpenFlow 協議,它們都可以被統一的 SDN 控制器管理,從而實作物理機和虛擬機的網路連通,

SDN 控制器是如何通過 OpenFlow 協議控制網路的呢?

在 OpenvSwitch 里面,有一個流表規則,任何通過這個交換機的包,都會經過這些規則進行處理,從而接收、轉發、放棄,
那流表長啥樣呢?其實就是一個個表格,每個表格好多行,每行都是一條規則,每條規則都有優先級,先看高優先級的規則,再看低優先級的規則,

對于每一條規則,要看是否滿足匹配條件,這些條件包括,從哪個埠進來的,網路包頭里面有什么等等,滿足了條件的網路包,就要執行一個動作,對這個網路包進行處理,可以修改包頭里的內容,可以跳到任何一個表格,可以轉發到某個網口出去,也可以丟棄,
通過這些表格,可以對收到的網路包隨意處理,

具體都能做什么處理呢?通過上面的表格可以看出,簡直是想怎么處理怎么處理,可以覆寫 TCP/IP 協議堆疊的四層,
對于物理層:
- 匹配規則包括從哪個口進來;
- 執行動作包括從哪個口出去,
對于 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 有本地的命令列可以進行配置,能夠實驗咱們前面講過的一些功能,我們可以通過 OpenvSwitch 的命令創建一個虛擬交換機,然后可以將多個虛擬埠 port 添加到這個虛擬交換機上,
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 地址學習,
ovs-vsctl set bridge ubuntu_br flood-vlans=101,102,103

創建好了環境以后,我們來做這個實驗,
- 從 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 收不到包,
- 從 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,
- 從 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,不用買一個支持 VLAN 的交換機,你也能學習 VLAN 的作業模式了,
實驗二:用 OpenvSwitch 模擬網卡系結,連接交換機
接下來,我們來做另一個實驗,在前面,我們還說過,為了高可用,可以使用網卡系結,連接到交換機,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,你不用買兩臺支持 bond 的交換機,也能看到 bond 的效果,
那 OpenvSwitch 是怎么做到這些的呢?我們來看 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,在不同的機器之間實作負載均衡等等,所有的策略都可以靈活配置,
如何在云計算中使用 OpenvSwitch?
OpenvSwitch 這么牛,如何用在云計算中呢?

我們還是討論 VLAN 的場景,
在沒有 OpenvSwitch 的時候,如果一個新的用戶要使用一個新的 VLAN,還需要創建一個屬于新的 VLAN 的虛擬網卡,并且為這個租戶創建一個單獨的虛擬網橋,這樣用戶越來越多的時候,虛擬網卡和虛擬網橋會越來越多,管理非常復雜,
另一個問題是虛擬機的 VLAN 和物理環境的 VLAN 是透傳的,也即從一開始規劃的時候,就需要匹配起來,將物理環境和虛擬環境強系結,本來就不靈活,
而引入了 OpenvSwitch,狀態就得到了改觀,
首先,由于 OpenvSwitch 本身就是支持 VLAN 的,所有的虛擬機都可以放在一個網橋 br0 上,通過不同的用戶配置不同的 tag,就能夠實作隔離,例如上面的圖,用戶 A 的虛擬機都在 br0 上,用戶 B 的虛擬機都在 br1 上,有了 OpenvSwitch,就可以都放在 br0 上,只是設定了不同的 tag,
另外,還可以創建一個虛擬交換機 br1,將物理網路和虛擬網路進行隔離,物理網路有物理網路的 VLAN 規劃,虛擬機在一臺物理機上,所有的 VLAN 都是從 1 開始的,由于一臺機器上的虛擬機不會超過 4096 個,所以 VLAN 在一臺物理機上如果從 1 開始,肯定夠用了,
例如在圖中,上面的物理機里面,用戶 A 被分配的 tag 是 1,用戶 B 被分配的 tag 是 2,而在下面的物理機里面,用戶 A 被分配的 tag 是 7,用戶 B 被分配的 tag 是 6,
如果物理機之間的通信和隔離還是通過 VLAN 的話,需要將虛擬機的 VLAN 和物理環境的 VLAN 對應起來,但為了靈活性,不一定一致,這樣可以實作分別管理物理機的網路和虛擬機的網路,好在 OpenvSwitch 可以對包的內容進行修改,例如通過匹配 dl_vlan,然后執行 mod_vlan_vid 來改進進出出物理機的網路包,
盡管租戶多了,物理環境的 VLAN 還是不夠用,但是有了 OpenvSwitch 的映射,將物理和虛擬解耦,從而可以讓物理環境使用其他技術,而不影響虛擬機環境,這個我們后面再講,
小結
- 用 SDN 控制整個云里面的網路,就像小區保安從總控室管理整個物業是一樣的,將控制面和資料面進行了分離;
- 一種開源的虛擬交換機的實作 OpenvSwitch,它能對經過自己的包做任意修改,從而使得云對網路的控制十分靈活;
- 將 OpenvSwitch 引入了云之后,可以使得配置簡單而靈活,并且可以解耦物理網路和虛擬網路,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/195994.html
標籤:其他
