雲計算與openstack學習(四)

KVM 網絡虛擬化基礎 


 

網絡虛擬化是虛擬化技術中最複雜的部分,學習難度最大。 但因爲網絡是虛擬化中非常重要的資源,所以再硬的骨頭也必須要把它啃下來。

爲了讓大家對虛擬化網絡的複雜程度有一個直觀的認識,請看下圖

這是 OpenStack 官網上給出的計算節點(可以理解爲 KVM 的宿主機)虛擬網絡的邏輯圖,上面的網絡設備很多,層次也很複雜。
我第一次看到這張圖,也着實被下了一跳。

不過大家也不要怕,萬丈高樓從地起,虛擬網絡再複雜,也是由一些基礎的組件構成的。只要我們將這些基礎組件的概念和它們之間的邏輯關係搞清楚了,就能深刻理解虛擬網絡的架構,那麼雲環境下的虛擬化網絡也就不在話下了。

下面我們來學習網絡虛擬化中最重要的兩個東西:Linux Bridge 和 VLAN

Linux Bridge 基本概念

假設宿主機有 1 塊與外網連接的物理網卡 eth0,上面跑了 1 個虛機 VM1,現在有個問題是: 如何讓 VM1 能夠訪問外網?

至少有兩種方案

  1. 將物理網卡eth0直接分配給VM1,但隨之帶來的問題很多: 宿主機就沒有網卡,無法訪問了; 新的虛機,比如 VM2 也沒有網卡。 下面看推薦的方案

  2. 給 VM1 分配一個虛擬網卡 vnet0,通過 Linux Bridge  br0 將 eth0 和 vnet0 連接起來,如下圖所示

Linux Bridge 是 Linux 上用來做 TCP/IP 二層協議交換的設備,其功能大家可以簡單的理解爲是一個二層交換機或者 Hub。多個網絡設備可以連接到同一個 Linux Bridge,當某個設備收到數據包時,Linux Bridge 會將數據轉發給其他設備。

在上面這個例子中,當有數據到達 eth0 時,br0 會將數據轉發給 vnet0,這樣 VM1 就能接收到來自外網的數據; 反過來,VM1 發送數據給 vnet0,br0 也會將數據轉發到 eth0,從而實現了 VM1 與外網的通信。

現在我們增加一個虛機 VM2,如下圖所示

VM2 的虛擬網卡 vnet1 也連接到了 br0 上。 現在 VM1 和 VM2 之間可以通信,同時 VM1 和 VM2 也都可以與外網通信。

有了上面的基礎知識,下一節將演示如何在實驗環境中實現這套虛擬網絡。

動手實踐虛擬網絡 


 

本節將演示如何在實驗環境中實現下圖所示的虛擬網絡

配置 Linux Bridge br0

編輯 /etc/network/interfaces,配置 br0。

下面用 vmdiff 展示了對 /etc/network/interfaces 的修改

有兩點需要注意: 1. 之前宿主機的 IP 是通過 dhcp 配置在 eth0 上的;創建 Linux Bridge 之後,IP 就必須放到 br0 上了 2. 在 br0 的配置信息中請注意最後一行 “bridge_ports eth0”,其作用就是將 eth0 掛到 br0 上

重啓宿主機,查看 IP 配置,可以看到 IP 已經放到 br0 上了

用 brctl show 查看當前 Linux Bridge 的配置。 eth0 已經掛到 br0 上了

# brctl show bridge

name     bridge id               STP enabled     interfaces

br0             8000.000c298decbe       no                    eth0

virbr0          8000.000000000000       yes

除了 br0,大家應該注意到還有一個 virbr0 的 Bridge,而且 virbr0 上已經配置了 IP 地址 192.168.122.1。

virbr0 的作用我們會在後面介紹。

在宿主機中 CloudMan 已經提前創建好了虛機 VM1 和 VM2,現在都處於關機狀態

# virsh list --all Id    

Name                           State

---------------------------------------------------- -    

VM1                            shut off -     VM2                            shut off

配置 VM1

下面我們在 virt-manager 中查看一下 VM1 的網卡配置(爲了使大家能夠熟練使用命令行工具 virsh 和圖形工具 virt-manager,CloudMan 在演示的時候會同時用到它們,兩個工具都很重要)

可以看到虛擬網卡的 source device 我們選擇的是 br0

下面我們啓動 VM1,看會發生什麼

# virsh start VM1 Domain VM1 started

# brctl show

bridge name     bridge id               STP enabled     interfaces

br0             8000.000c298decbe       no                    eth0

                                                                                 vnet0

virbr0          8000.000000000000       yes

brctl show 告訴我們 br0 下面添加了一個 vnet0 設備,通過 virsh 確認這就是VM1的虛擬網卡。

# virsh domiflist

VM1 Interface  Type       Source     Model       MAC

-------------------------------------------------------

vnet0      bridge     br0        rtl8139     52:54:00:75:dd:1a

VM1 的 IP 是 DHCP 獲得的(設置靜態 IP 當然也可以),通過 virt-manager 控制檯登錄 VM1,查看 IP。

# ifconfig eth0

     Link encap:Ethernet  HWaddr 52:54:00:75:dd:1a

         inet addr:192.168.111.106  Bcast:192.168.111.255  Mask:255.255.255.0

         inet6 addr: fe80::5054:ff:fe75:dd1a/64 Scope:Link

         UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

         RX packets:400 errors:0 dropped:0 overruns:0 frame:0

         TX packets:101 errors:0 dropped:0 overruns:0 carrier:0

         collisions:0 txqueuelen:1000

         RX bytes:41950 (41.9 KB)  TX bytes:12583 (12.5 KB)

VM1 通過 DHCP 拿到的 IP 是 192.168.111.106,與宿主機(IP爲192.168.111.107)是同一個網段。Ping 一下外網

root@VM1:~# ping www.baidu.com

PING www.a.shifen.com (180.97.33.108) 56(84) bytes of data.

64 bytes from 180.97.33.108: icmp_seq=1 ttl=53 time=34.9 ms

64 bytes from 180.97.33.108: icmp_seq=2 ttl=53 time=36.2 ms

64 bytes from 180.97.33.108: icmp_seq=3 ttl=53 time=38.8 ms

沒問題,可以訪問。

另外,在 VM1 中虛擬網卡是 eth0,並不是 vnet0。

vent0 是該虛擬網卡在宿主機中對應的設備名稱,其類型是 TAP 設備,這裏需要注意一下。

配置 VM2

跟 VM1 一樣,VM2 的虛擬網卡也掛在 br0上,啓動 VM1,查看網卡信息

# virsh start VM2 Domain VM2 started

# brctl show

bridge name     bridge id               STP enabled     interfaces

br0             8000.000c298decbe       no                    eth0

                                                                                 vnet0

                                                                                 vnet1

virbr0          8000.000000000000       yes

br0 下面多了 vnet1,通過 virsh 確認這就是 VM2 的虛擬網卡。

# virsh domiflist

VM2 Interface  Type       Source     Model       MAC

-------------------------------------------------------

vnet0      bridge     br0        rtl8139     52:54:00:cf:33:a1

VM2 通過 DHCP 拿到的 IP 是 192.168.111.108,登錄 VM2,驗證網絡的連通性

Ping VM1

root@VM2:~# ping VM1

PING VM1 (192.168.111.106) 56(84) bytes of data.

64 bytes from 192.168.111.106: icmp_seq=1 ttl=64 time=4.54 ms

64 bytes from 192.168.111.106: icmp_seq=2 ttl=64 time=1.63 ms

64 bytes from 192.168.111.106: icmp_seq=3 ttl=64 time=2.16 ms

Ping 宿主機

root@VM2:~# ping 192.168.111.107

PING 192.168.111.107 (192.168.111.107) 56(84) bytes of data.

64 bytes from 192.168.111.107: icmp_seq=1 ttl=64 time=1.02 ms

64 bytes from 192.168.111.107: icmp_seq=2 ttl=64 time=0.052 ms

64 bytes from 192.168.111.107: icmp_seq=3 ttl=64 time=0.064 ms

Ping 外網

root@VM2:~# ping www.baidu.com

PING www.a.shifen.com (180.97.33.107) 56(84) bytes of data.

64 bytes from 180.97.33.107: icmp_seq=1 ttl=53 time=53.9 ms

64 bytes from 180.97.33.107: icmp_seq=2 ttl=53 time=45.0 ms

64 bytes from 180.97.33.107: icmp_seq=3 ttl=53 time=44.2 ms

可見,通過 br0 這個 Linux Bridge,我們實現了 VM1、VM2、宿主機和外網這四者之間的數

理解 virbr0

virbr0 是 KVM 默認創建的一個 Bridge,其作用是爲連接其上的虛機網卡提供 NAT 訪問外網的功能。

virbr0 默認分配了一個IP 192.168.122.1,併爲連接其上的其他虛擬網卡提供 DHCP 服務。

下面我們演示如何使用 virbr0。

在 virt-manager 打開 VM1 的配置界面,網卡 Source device 選擇 “default”,將 VM1 的網卡掛在 virbr0 上。

啓動 VM1,brctl show 可以查看到 vnet0 已經掛在了 virbr0 上。

# brctl show

bridge name     bridge id               STP enabled     interfaces

br0             8000.000c298decbe       no                    eth0

virbr0          8000.fe540075dd1a       yes                   vnet0

用 virsh 命令確認 vnet 就是 VM1 的虛擬網卡。

# virsh domiflist VM1

Interface  Type       Source     Model       MAC

-------------------------------------------------------

vnet0      network    default    rtl8139     52:54:00:75:dd:1a

virbr0 使用 dnsmasq 提供 DHCP 服務,可以在宿主機中查看該進程信息

# ps -elf|grep dnsmasq

5 S libvirt+  2422     1  0  80   0 -  7054 poll_s 11:26 ?        00:00:00 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf

在 /var/lib/libvirt/dnsmasq/ 目錄下有一個 default.leases 文件,當 VM1 成功獲得 DHCP 的 IP 後,可以在該文件中查看到相應的信息

# cat /var/lib/libvirt/dnsmasq/default.leases

1441525677 52:54:00:75:dd:1a 192.168.122.6 ubuntu *

上面顯示 192.168.122.6 已經分配給 MAC 地址爲 52:54:00:75:dd:1a 的網卡,這正是 vnet0 的 MAC。之後就可以使用該 IP 訪問 VM1 了。

# ssh 192.168.122.6

[email protected]'s password:

Welcome to Ubuntu 14.04.2 LTS (GNU/Linux 3.16.0-30-generic x86_64)

Last login: Sun Sep  6 01:30:23 2015

root@VM1:~# ifconfig

eth0      Link encap:Ethernet  HWaddr 52:54:00:75:dd:1a

         inet addr:192.168.122.6  Bcast:192.168.122.255  Mask:255.255.255.0

         inet6 addr: fe80::5054:ff:fe75:dd1a/64 Scope:Link

         UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

         RX packets:61 errors:0 dropped:0 overruns:0 frame:0

         TX packets:66 errors:0 dropped:0 overruns:0 carrier:0

         collisions:0 txqueuelen:1000

         RX bytes:7453 (7.4 KB)  TX bytes:8649 (8.6 KB)

Ping一下外網。

root@VM1:~# ping www.baidu.com

PING www.a.shifen.com (180.97.33.107) 56(84) bytes of data.

64 bytes from 180.97.33.107: icmp_seq=1 ttl=52 time=36.9 ms

64 bytes from 180.97.33.107: icmp_seq=2 ttl=52 time=119 ms

64 bytes from 180.97.33.107: icmp_seq=3 ttl=52 time=88.5 ms

64 bytes from 180.97.33.107: icmp_seq=4 ttl=52 time=38.0 ms

64 bytes from 180.97.33.107: icmp_seq=5 ttl=52 time=122 ms

沒有問題,可以訪問外網,說明 NAT 起作用了。

需要說明的是,使用 NAT 的虛機 VM1 可以訪問外網,但外網無法直接訪問 VM1。 因爲 VM1 發出的網絡包源地址並不是 192.168.122.6,而是被 NAT 替換爲宿主機的 IP 地址了。

這個與使用 br0 不一樣,在 br0 的情況下,VM1 通過自己的 IP 直接與外網通信,不會經過 NAT 地址轉換。

下節我們討論 vlan 在 linux bridge 中的實現

Linux 如何實現 VLAN 

LAN 表示 Local Area Network,本地局域網,通常使用 Hub 和 Switch 來連接 LAN 中的計算機。
一般來說,兩臺計算機連入同一個 Hub 或者 Switch 時,它們就在同一個 LAN 中。

一個 LAN 表示一個廣播域。 其含義是:LAN 中的所有成員都會收到任意一個成員發出的廣播包。

VLAN 表示 Virtual LAN。一個帶有 VLAN 功能的switch 能夠將自己的端口劃分出多個 LAN。
計算機發出的廣播包可以被同一個 LAN 中其他計算機收到,但位於其他 LAN 的計算機則無法收到。 簡單地說,VLAN 將一個交換機分成了多個交換機,限制了廣播的範圍,在二層將計算機隔離到不同的 VLAN 中。

比方說,有兩組機器,Group A 和 B。
我們想配置成 Group A 中的機器可以相互訪問,Group B 中的機器也可以相互訪問,但是 A 和 B 中的機器無法互相訪問。
一種方法是使用兩個交換機,A 和 B 分別接到一個交換機。 另一種方法是使用一個帶 VLAN 功能的交換機,將 A 和 B 的機器分別放到不同的 VLAN 中。

請注意,VLAN 的隔離是二層上的隔離,A 和 B 無法相互訪問指的是二層廣播包(比如 arp)無法跨越 VLAN 的邊界。
但在三層上(比如IP)是可以通過路由器讓 A 和 B 互通的。概念上一定要分清。

現在的交換機幾乎都是支持 VLAN 的。 通常交換機的端口有兩種配置模式: Access 和 Trunk。看下圖

Access 口
這些端口被打上了 VLAN 的標籤,表明該端口屬於哪個 VLAN。 不同 VLAN 用 VLAN ID 來區分,VLAN ID 的 範圍是 1-4096。 Access 口都是直接與計算機網卡相連的,這樣從該網卡出來的數據包流入 Access 口後就被打上了所在 VLAN 的標籤。 Access 口只能屬於一個 VLAN。

Trunk 口
假設有兩個交換機 A 和 B。 A 上有 VLAN1(紅)、VLAN2(黃)、VLAN3(藍);B 上也有 VLAN1、2、3 那如何讓 AB 上相同 VLAN 之間能夠通信呢?

辦法是將 A 和 B 連起來,而且連接 A 和 B 的端口要允許 VLAN1、2、3 三個 VLAN 的數據都能夠通過。
這樣的端口就是Trunk口了。 VLAN1、2、3 的數據包在通過 Trunk 口到達對方交換機的過程中始終帶着自己的 VLAN 標籤。

瞭解了 VLAN 的概念之後,我們來看 KVM 虛擬化環境下是如何實現 VLAN 的。還是先看圖,

eth0 是宿主機上的物理網卡,有一個命名爲 eth0.10 的子設備與之相連。 eth0.10 就是 VLAN 設備了,其 VLAN ID 就是 VLAN 10。 eth0.10 掛在命名爲 brvlan10 的 Linux Bridge 上,虛機 VM1 的虛擬網卡 vent0 也掛在 brvlan10 上。

這樣的配置其效果就是: 宿主機用軟件實現了一個交換機(當然是虛擬的),上面定義了一個 VLAN10。 eth0.10,brvlan10 和 vnet0 都分別接到 VLAN10 的 Access口上。而 eth0 就是一個 Trunk 口。
VM1 通過 vnet0 發出來的數據包會被打上 VLAN10 的標籤。

eth0.10 的作用是:定義了 VLAN10 brvlan10 的作用是:Bridge 上的其他網絡設備自動加入到 VLAN10 中

我們再增加一個 VLAN20,見下圖

p_w_picpath38.png

這樣虛擬交換機就有兩個 VLAN 了,VM1 和 VM2 分別屬於 VLAN10 和 VLAN20。 對於新創建的虛機,只需要將其虛擬網卡放入相應的 Bridge,就能控制其所屬的 VLAN。

VLAN 設備總是以母子關係出現,母子設備之間是一對多的關係。 一個母設備(eth0)可以有多


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章