Xen - Networking
Step 0 : Xen底下的網路架構
Step 1 : 虛擬還是實體
Step 2 : network-bridge
Step 3 : network-nat
Step 4 : network-route
Step 5 : 參考網頁

Step 0 : Xen底下的網路架構
在虛擬化下的環境就屬網路裝置最為複雜難懂,不過模式大致可以畫分成 3 種 1.network-bridge , 2.network-nat 和 3.network-route 最主要就是看的懂虛擬與實際的網路裝置是怎麼對應的(Logical NICs <-> Physical NICs).

不管是 Xen 還是 VMware 虛擬化下的網路裝置,主要都是透過這 3 種不同的模式讓 Guest OS 的虛擬網路裝置透過實體的網路接出去.這邊我直接以 RHEL5 Xen 的環境下來做說明.剛開始使用 Xen 的人一定會對於他的網路架構搞不清楚.光是在 Dom0 用 ifconfig 就可以看到好多以前沒看過的裝置出現,因為 Dom0 能直接與 Hypervisor 溝通所以所有 DomU 所產生的虛擬裝置都會在在這裡秀出來.
[root@benjr ~]#ifconfig
eth0 Link encap:Ethernet HWaddr 00:02:B3:9D:87:65
.... 略 ....
lo Link encap:Local Loopback
.... 略 ....
peth0 Link encap:Ethernet HWaddr FE:FF:FF:FF:FF:FF
.... 略 ....
vif0.0 Link encap:Ethernet HWaddr FE:FF:FF:FF:FF:FF
.... 略 ....
vif1.0 Link encap:Ethernet HWaddr FE:FF:FF:FF:FF:FF
.... 略 ....
virbr0 Link encap:Ethernet HWaddr 00:00:00:00:00:00
.... 略 ....
xenbr0 Link encap:Ethernet HWaddr FE:FF:FF:FF:FF:FF
.... 略 ....

一般的 Linux 下的網路裝置名稱為 eth0,eth1...,但是在 Xen 底下許多的硬體裝置都是虛擬出來的(包括 Dom0 下的網路裝置也是). 這裡你會看到 eth0, lo, peth0, vif0.0, vif1.0, virbr0, xenbr0. 這些是什麼東西阿,我們直接來看下面這一張圖你會清楚了解 Xen 底下的網路裝置是怎麼一回事.下面我會針對每一項做說明.



因為使用不同的模式會有不同的虛擬裝置出現,所以上面的圖示是使用 RHEL5 所預設的 network-bridge 模式,上圖我只列出了 eth0, peth0, vif0.0, vif1.0 以及, 其中為例出的 lo 是 Loop device 也就是我們常在使用的 127.0.0.1 至於 virbr0 則是在 QEMU 所提供的 Bridge NAT 模式上來使用請參考 QEMU-Bridge NAT http://benjr.tw/?q=node/520 .

Step 1 : 虛擬還是實體
Xen 主要網路裝置可以分成兩種,一個就是實體 Physical 的(peth0,peth1...)而另一種就是虛擬 Logical 出來的(eth0,eth1...)以及(vif<id#>.0,vif<id#>.1..),實體的可以很清楚的知道是 pethx,但是虛擬的怎麼這麼複雜呢!!!先看看下面這張圖就會很清楚了.

我們先來看目前所有的 Guest OS 有哪一些再來做說明.當然你看到的會和我的不盡相同.系統會依據不同的實體和虛擬的網路裝置以及 Guest OS 的不同做調整的.

#列出所有 domU
[root@benjr ~]# xm list
Name Id    Mem(MB) VCPUs State Time(s)
Domain-0 0    7619 4 r----    43213.6
rhel4 1 512 1 -b--- 9601

規則很簡單:
1.不管是在 Dom0,還是DomU 你會看到 eth0,eth1...這些都是虛擬出來的網路卡裝置.
2.在 Dom0 裡面你可以看到 vif<id#>.0,vif<id#>.1...的裝置存在,因為 Dom0 能直接與 Hypervisor 溝通所以所有 DomU 所產生的虛擬裝置都會在在這裡秀出來.
3.他們的對應也相當簡單, vif<id#>.x 中的 id 就是 DomU 的 id 所以你在 Dom0 底下的 eth0 是對應到 vif0.0, eth1 是對應到 vif0.1 如此依序下去(最多能產生的網路裝置為八個),至於 vif1.0 就是某個 Dom U(ID=1) 的 eth0 我們可以透過 #xm list 看 DomU 所對應的 id 為何!!
目前我的環境只有 Dom0(RHEL5) 以及一個 Guest OS(RHEL4),因為實體的網路卡裝置有 2 個所以我設定的 2 個 Xen Bridge,分別對應到不同的虛擬網卡,所以 Xen 底下整個網路裝置就像下面所示.
Peth0 -> 實體網路卡裝置(Physical NIC)
Peth1 -> 實體網路卡裝置(Physical NIC)
Dom0 -> eth0 -> vif0.0
Dom0 -> eth1 -> vif0.1
Dom1(RHEL4) -> eth0 -> vif1.0
Dom1(RHEL4) -> eth1 -> vif1.1
4.至於這些虛擬的裝置會如何對應到真實的裝置這就跟你所使用的模式有關,還記得剛剛提到的模式(network-bridge)下面的指令可以讓你目前 環境 peth 是如何對應vif

[root@benjr ~]# brctl show
bridge name     bridge id     STP enabled interfaces
virbr0     8000.000000000000       no
xenbr0    8000.feffffffffff no peth0
vif0.0
vif1.0
xenbr1    8000.fefffffffffe no     peth1
vif0.1
vif1.1
[root@benjr scripts]# /etc/xen/scripts/network-bridge status
.... 略 ....
bridge name     bridge id     STP enabled interfaces
virbr0     8000.000000000000       no
xenbr0    8000.feffffffffff no peth0
vif0.0
vif1.0
xenbr1    8000.fefffffffffe no     peth1
vif0.1
vif1.1
.... 略 ....

Dom0    -> eth0 -> vif0.0 -> xenbr0 -> peth0 (實體網路卡裝置 Physical NIC)
Dom1(RHEL4)   -> eth0 -> vif1.0 -> xenbr0 -> peth0 (實體網路卡裝置Physical NIC)
Dom0 -> eth1 -> vif0.1 -> xenbr1 -> peth1 (實體網路卡裝置Physical NIC)
Dom1(RHEL4) -> eth1 -> vif1.1 -> xenbr1 -> peth1 (實體網路卡裝置Physical NIC)

note: 其中的 vif<id#>.x 會隨著 DomU 關機而消失.

因為網卡是虛擬出來的所以 MAC 不太可能跟著網卡一起,所以每當產生新的 Guest Virtula Network(虛擬網卡)就會依據規則來產生:
XEN:
虛擬網路裝置的 mac 是如何產生的,他是有一個規則性的. mac :XY:XX:XX:XX:XX:XX ,mac 使用16進制來顯示 X 可為任何的16進制(0~9,A,B,C,D,E,F), Y 則只能使用 2, 6, A 或 E. 不過 Xen 建議使用的範圍 00:16:3e:xx:xx:xx. 這個區段是保留給 Xen 使用的.
VMware:
mac : 00:0c:29:xx:xx:xx 或是 00:50:56:xx:xx:xx 這個區段是保留給 VMware 使用的,VMware 建議固定 mac address 使用的範圍 00:50:56:[00-3F]:xx:xx . 要不然就讓系統來指定.

Step 2 : network-bridge
要使用哪種模式定義在 /etc/xen/xend-conf.sxp 系統預設使用 Bridge 模式,主要會啟動 network-bridge 與 vif-bridge 這兩個 shell script.在這個模式下會看到一個裝置 xenbr0 ,接下來我會針對 xenbr0 來說明這是什麼東西.要認識 xenbr0 的最好方式是直接看 Networking 啟動時的步驟,當 Dom0 的 xend 啟動時, 首先會執行 /etc/xen/scripts/network-bridge 這個 script, 網路啟動步驟如下:
1.首先產生一個新的 bridge 名稱為 xenbr0
2.此時實體的網路裝置 eth0 會被關閉
3.實體的 eth0 IP 和 MAC addresses 會複製到虛擬的網路裝置中 veth0
4.實體的網路裝置 eth0 名稱會被修改成 peth0
5.虛擬的網路裝置 veth0 名稱會被修改成 eth0
6.peth0 和 vif0.0 會被連接到 bridge xenbr0 (此時的 xenbr0 就如同一個 switch)
7.bridge xenbr0, peth0, eth0 和 vif0.0 都會被啟動.
note: Dom0上的防火牆是不會引響到 DomU 的網路流通的.

當 RHEL5 Xen 安裝完成時系統預設的 Bridge(xenbri0) 只有一個,但是當我們有多張網卡時就需要手動設定多個 Bridge.假設系統沒有經過其他設定,其網路組態就像下面所描述的 Dom0(eth0) -> vif0.0 -> xenbr0 -> peth0.

 

如果我們系統上有多張實體網卡時就可以透過修改設定檔 /etc/xen/xend- config.sxp 讓虛擬的網路裝置可以透過其他實體裝置連接網路.

[root@benjr ~]# vi /etc/xen/xend-config.sxp
...
#(network-script network-bridge)
(network-script my-network-script)
...
#把上面的修改成我自己設定的 網路 script 名稱(my-network-script).接下來將我們的 my-network-script 修改成我們需要的組態即可.
[root@benjr ~]# vi /etc/xen/scripts/my-network-script
#!/bin/sh
/etc/xen/scripts/network-bridge start vifnum=0 netdev=eth0 bridge=xenbr0
/etc/xen/scripts/network-bridge start vifnum=1 netdev=eth1 bridge=xenbr1
[root@benjr ~]# chmod a+x /etc/xen/scripts/my-network-script
#不要忘記修改檔案的屬性.

如果你是要臨時增加一個 Bridge 可用下面的指令.建立一個 Network bridge

[root@benjr ~]#/etc/xen/scripts/network-bridge start vifnum=1 bridge=xenbr1 netdev=eth1
vifnum=1 ;虛擬裝置號碼,系統預設有 8 個 loopback 裝置可以使用,而預設值為 0.可以在開機時指定 loopback 最大到32個 nloopbacks=<N>
bridge=xenbr1 ;設定 Network Bridge 名稱為 xenbr1,預設值為 xenbr${vifnum}.
netdev=eth1 ;設定 Network Bridge xenbr1 透過實體 eth1 連接外部.預設值為 eth$(vifnum}

但是 DomU 啟動時是依據 vif-bridge 這個script 來執行.
當 domU 啟動時, xend (running in dom0) 會來執行這個 vif-bridge script, 虛擬網路啟動步驟如下:
1.將 vif<id#>.0 連接到適當的 xenbr0
2.啟動 vif<id#>.0 .

所有的 scripts 都存放在 /etc/xen/scripts. 而 Bridge 只是 Xen 其中一種的網路模式,其他的還有 NAT's Networking 與 Routed Networking 這些後面會再介紹.

Step 3 : network-nat

RHEL5 Xen 的網路環境預設為 bridge 模式,如果不合你使用時可以選擇其他的模式 network-nat 或是 network-route ,不過這裡先介紹一下 NAT 的模式,先來說說什麼是 NAT ,NAT 的全名就是 network address translation,最常應用在將 Private IP 轉換成 Public IP ,Private IP 只限是用於私人網路,此類的封包無法在 Internet 上傳送,如 10.0.0.0(subnet mask : 10.255.255.255) ,172.16.0.0(subnet mask : 172.31.255.255) 以及 192.168.0.0(subnet mask : 192.168.255.255) 唯有 Public IP 是在 Internet 可以被合法傳遞,所以 NAT 最主要的目的就是為了將內部的 Private IP 透過轉換將資料可以在 Internet 上傳送.使用這種方式的好處是外部無法直接和 Guest OS 相連接,這樣間接的加強的系統的安全性.
還記得設定檔在 Dom0(RHEL 5) Xen 的網路設定目錄 /etc/xen/xend-conf.sxp 將預設的 bridge 改成 NAT 模式.
[root@benjr ~]# vi /etc/xen/xend-config.sxp
(network-script network-nat)
#(network-script network-bridge)
#(network-script network-route)

(vif-script vif-nat)
#(vif-script vif-bridge)
#(vif-script vif-route)

記得將 (network-script network-bridge) ,(vif-script vif-bridge) 做 "#" (把它當成註記).這樣所有的 Guest OS 當將可以使用 NAT 的模式,但是還需要修改一下 Guest OS 的設定檔案.不過先將 xen 的服務重新啟動.

[root@benjr ~]# /etc/init.d/xend restart

修改 Guest OS 的設定檔,目前我系統上面有一個 GuesOS : RHEL4 ID=1,設定檔名稱也為 RHEL4

[root@benjr ~]# vi /etc/xen/rhel4
name = "rhel4"
uuid = "cf67710d-b756-086b-8cde-be61d2faca1b"
maxmem = 512
memory = 512
vcpus = 1
bootloader = "/usr/bin/pygrub"
on_poweroff = "destroy"
on_reboot = "restart"
on_crash = "restart"
vfb = [ "type=vnc,vncunused=1,keymap=en-us" ]
disk = [ "phy:/dev/sda5,xvda,w" ]
vif = [ "mac=00:16:3e:27:95:c0,ip=10.0.0.1" ]
  • name

    這就是 VM 的名稱,虛擬化的環境下其 VM 名稱必須為唯一的.

  • uuid

    通用唯一識別碼(Universally Unique Identifier,UUID),系統會指定一個唯一的 uuid 來給每一台 VM.

  • maxmem

    通常我們在指定記憶體大小給 Guest VM 時可以先指定多一點,但是多指定的時候並不會真的使用到這麼多,先指定的優點是系統可以線上直接增加 VM 記憶體大小.

  • memory

    目前 VM 所真正使用的記體的多寡.

  • vcpus

    在 VM 所使用的邏輯 CPU 數目.

  • bootloader

    /usr/bin/pygrub 是 VM 所使用的 Bootloader 主要也就是將 VM 的 kernel/initrd 載入系統,類似於 GRUB,Xen 主要使用了 paravirtualized 的技術,他並不像是 VMware 使用 full virtualization 還有模擬出 BIOS 的環境.pygrub 還包含了一項 PXEBoot 的功能.

  • on_poweroff/reboot/crash

    當系統在 poweroff/reboot/crash VM 所對應的動作為何,系統在 poweroff 是做 destory 其實也就是 poweroff 主要是將 VM 的記憶體肆放並將硬碟資料確切寫回,而 reboot/crash 則是將 VM 重新開機.

  • vfb

    Xen 底下的 VM 都是透過 VNC 來傳送畫面,所以這裡的 vfb(virtual framebuffer device) 就是設定系統畫面與輸入裝置 Keyboard/Mouse.

  • disk

    虛擬的 VM 所使用的硬碟模式可以為實體 partition 也可以為 p_w_picpath 的方式.

  • vif

    這就是這一次要修改的重點 vif(virtual network devices).也就是和網路裝置相關的設定.vif = [ "mac=00:16:3e:27:95:c0,ip=10.0.0.1" ] 其中的 mac 可以不設定主要就是 IP,必須和 VM OS 所設定的 IP 相同.

回到 DomU 的 Guest OS (RHEL4) 將 IP 設定成跟剛剛在 Dom0 設定的一模一項.

# Xen Virtual Ethernet
[root@DomU ~]# vi /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
IPADDR=10.0.0.1
NETMASK=255.255.255.0
GATEWAY=10.0.0.128

並且將 DomU 網路的服務重新啟動

[root@DomU ~]#service network restart

將 DOMU(RHEL4) 重新啟動,回到DOM0 第一件事情你會發現 xen bridge(xenbr0) 不見了,而且 vif1.0(Guest OS:RHEL4 ID=1) 多了 IP 的設定值,這個是給 Guest OS 所使用的 default gateway.預設 default gateway 為 10.0.0.128 ,如果你的 DomU 的 Guest OS 有很多時,在 Dom0 下的每一個網路裝置 vif(Dom ID).0 都會產生不同的 default gateway 從 10.0.0.128 開始接下來的就會是 10.0.0.129.如此依序下去,不過在 DomU 的 Guest OS 只要隨便指定任何一個 default gateway 都可以. 當你選擇的網路為 NAT 時你的 Dom0 的網路裝置就像是一台 NAT ,所有的 Guest OS(DomU) 都會透過 NAT 來轉送 private IP 的資料.
1. 所有 domU 上的虛擬機器都是在相同的 Private 私人網域.
2. 所有 domU 虛擬機器的封包都必須透過 dom0 的 NAT 去連結到其他的網路.
3. 如同一般的 NAT 所有 domU 上的虛擬機器都是被隱藏在 private 私人網域,所以外部不能直接連接到 DomU 上的虛擬機器.必須透過 Dom0 的 default gateway.

現在回 Dom 0 觀察一下網路環境有什麼改變.使用指令 "ifconfig" 可以很清楚看到 vif1.0 自動得到的 IP 為 10.0.0.128

[root@benjr ~]# ifconfig vif1.0
vif1.0    Link encap:Ethernet HWaddr FE:FF:FF:FF:FF:FF
inet addr:10.0.0.128 Bcast:0.0.0.0 Mask:255.255.255.255
inet6 addr: fe80::fcff:ffff:feff:ffff/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:98 errors:0 dropped:0 overruns:0 frame:0
TX packets:73 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:32
RX bytes:11014 (10.7 KiB) TX bytes:9404 (9.1 KiB)

使用 "iptables -L" 來看目前防火牆 iptables 狀態的確多了 10.0.0.1 的規則.

[root@benjr ~]# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination        
ACCEPT     udp -- anywhere             anywhere            udp dpt:domain
ACCEPT     tcp -- anywhere             anywhere            tcp dpt:domain
ACCEPT     udp -- anywhere             anywhere            udp dpt:bootps
ACCEPT     tcp -- anywhere             anywhere            tcp dpt:bootps

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination        
ACCEPT     all -- anywhere             192.168.122.0/24    state RELATED,ESTABLISHED
ACCEPT     all -- 192.168.122.0/24     anywhere           
ACCEPT     all -- anywhere             anywhere           
REJECT     all -- anywhere             anywhere            reject-with icmp-port-unreachable
REJECT     all -- anywhere             anywhere            reject-with icmp-port-unreachable
ACCEPT     all -- 10.0.0.1             anywhere            PHYSDEV match --physdev-in vif1.0
ACCEPT     udp -- anywhere             anywhere            PHYSDEV match --physdev-in vif1.0 udp spt:bootpc dpt:bootps

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

使用指令 "route" 可以看到只要是傳給 10.0.0.1 (VM:RHEL4) 都是經過 vif1.0

[root@benjr ~]# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.0.0.1        *               255.255.255.255 UH    0      0        0 vif1.0
192.168.122.0   *               255.255.255.0   U     0      0        0 virbr0
192.8.1.0       *               255.255.255.0   U     0      0        0 eth0
169.254.0.0     *               255.255.0.0     U     0      0        0 eth0

如果你要讓 VM 虛擬機透過 dhcp 自動得到 ip,可以參考下列幾篇文章.
http://www.nikhef.nl/pub/projects/grid/gridwiki/index.php/Xen_3.2,_CentO...

Step 4 : network-route
未完成

Step 5 : 參考網頁

http://wiki.xensource.com/xenwiki/XenNetworking
http://wiki.kartbuilding.net/index.php/Xen_Networking