Xen半虛擬化的實現及實時遷移

虛擬化簡介html

hypervisor
前端

hypervisor是一個虛擬化軟件,直接運行在硬件之上,虛擬機搭建在hypervisor之上,多個虛擬機經過hypervisor共享底層的硬件資源。hypervisor的主要功能是對底層的硬件資源進行管理,協調運行在其上的虛擬機對硬件資源的訪問,而且保護每個虛擬機在運行過程當中不受其餘虛擬機的影響。node

徹底虛擬化
linux

徹底虛擬化即虛擬機運行在模擬的硬件之上。在hypervisor中運行的虛擬機表現爲一個運行在用戶空間的進程,虛擬機上的進程須要執行特權指令時,即須要對底層的硬件進行訪問時,其相關的操做(例如cpu指令)會被hypervisor捕獲,由hypervisor完成執行並返回結果。在這個過程當中hypervisor會給處理器帶來很大的開銷。在硬件輔助虛擬化中,這個過程由硬件來輔助完成,大大提高了性能。在徹底虛擬化環境中,虛擬機上的操做系統不會意識到本身運行在虛擬化的環境中,客戶端的操做系統內核無需修改。對應的實現軟件有VMware Workstation,KVM.......nginx

半虛擬化vim

在半虛擬化環境中,hypervisor將底層硬件資源的功能以API(hyper call)的形式向上輸出,虛擬機上的操做系統經過調用這些hyper call來完成特權指令的執行。這減少了hypervisor的開銷,可是內核執行相應的操做須要基於hyper call來完成,這須要對內核進行修改,這使得像windows這樣的操做系統很難運行在半虛擬化環境中。windows


Xen基本組件後端

xen是半虛擬化的一種實現,操做系統的內核須要進行修改才能運行在xen上。Linux的內核中已經集成了這部分代碼,可以直接運行在xen的虛擬化平臺上。以下是xen的結構圖:
centos

wKioL1YDPNXB0Cu4AALTJtvlHvk109.jpg

xen有3個基本組件:
bash

Xen Hypervisor:直接運行在硬件之上,主要爲運行在上方的虛擬機分配cpu和內存資源。虛擬機須要訪問cpu和內存資源時經過調用Xen Hypervisor提供的API完成。

Domain 0:運行在Xen Hypervisor上,Dom0本地有IO設備的驅動,可以直接訪問底層的IO設備,全部DomU上的IO處理都須要通過Dom0完成對IO設備的訪問。在啓動時,須要先啓動Dom0,而後再啓動DomU。Linux-2.6.37以後版本的內核可直接運行在Dom0上。

DomainU:運行在Xen Hypervisor上的客戶虛擬機,可以並行運行多個,DomU對硬件資源的訪問須要經過Xen Hypervisor和Dom0完成。


Xen的安裝部署

安裝部署在centOS6上完成。

配置yum源,安裝xen的軟件包。(使用搜狐的源)

[root@node1 ~]# vim /etc/yum.repos.d/xen.repo
[xen]
name=xen
baseurl=http://mirrors.sohu.com/centos/6/xen4/x86_64/
gpgcheck=0
enabled=1
cost=100

####################
[root@node1 ~]# yum install xen

這裏使用3.4版本的內核來部署(centos官方提供的最新版本內核3.18貌似存在點問題)

[root@node1 xen4]# ls
kernel-3.4.68-9.el6.centos.alt.x86_64.rpm           xen-libs-4.2.4-30.el6.centos.alt.x86_64.rpm
kernel-firmware-3.4.68-9.el6.centos.alt.noarch.rpm  xen-licenses-4.2.4-30.el6.centos.alt.x86_64.rpm
xen-4.2.4-30.el6.centos.alt.x86_64.rpm              xen-runtime-4.2.4-30.el6.centos.alt.x86_64.rpm
xen-hypervisor-4.2.4-30.el6.centos.alt.x86_64.rpm
[root@node1 xen4]# yum install ./*


修改grub.conf文件:

default=0
timeout=5
splashp_w_picpath=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (3.4.68-9.el6.centos.alt.x86_64)
        root (hd0,0)
        kernel /xen.gz dom0_mem=512M cpureq=xen dom0_max_vcpus=1 dom0_vcpus_pin
        module /vmlinuz-3.4.68-9.el6.centos.alt.x86_64 ro root=/dev/mapper/vg_node1-lv_root rd_NO_LUKS LANG=en_US.UTF-8 rd_LVM_LV=vg_node1/lv_swap rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_LVM_LV=vg_node1/lv_root  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
        module /initramfs-3.4.68-9.el6.centos.alt.x86_64.img
title CentOS (2.6.32-431.el6.x86_64)
        root (hd0,0)
        kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=/dev/mapper/vg_node1-lv_root rd_NO_LUKS LANG=en_US.UTF-8 rd_LVM_LV=vg_node1/lv_swap rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_LVM_LV=vg_node1/lv_root  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
        initrd /initramfs-2.6.32-431.el6.x86_64.img

dom0_mem:dom0使用的內存。

cpufreq:cpu的工做頻率由xen管理。

dom0_max_vcpus:使用虛擬cpu的個數。

dom0_vcpus_pin:把Dom0的虛擬化cpu直接綁定運行在某個物理cpu的核心上。


配置完成以後重啓操做系統,啓動完成以後,當前的系統就運行在Dom0上。

[root@node1 ~]# reboot
........
[root@node1 ~]# uname -r
3.4.68-9.el6.centos.alt.x86_64

查看當前運行的全部Domain:

[root@node1 ~]# xl list
Name                                        ID   Mem VCPUs	State	Time(s)
Domain-0                                     0   512     1     r-----      20.3


添加網橋設備,橋設備不支持使用NetworkManager來管理,使用network來管理。橋設備的添加可使用程序包brctl-utils中的工具來完成,也能夠手動添加。

[root@node1 ~]# vim /etc/sysconfig/network-scripts/ifcfg-br0
DEVICE=br0
TYPE=Bridge
ONBOOT=yes
NM_CONTROLLED=no
BOOTPROTO=none
IPADDR=192.168.1.106
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
STP=on
DNS1=61.153.81.74
DNS1=202.96.104.27
USERCTL=no

[root@node1 ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
NM_CONTROLLED=no
BOOTPROTO=none
BRIDGE=br0
USERCTL=no

而後重啓網卡:

[root@node1 ~]# service network restart
[root@node1 ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
br0		8000.000c293331f2	yes		eth0


Xen的環境已經部署完成,接下來開始安裝虛擬機。虛擬機操做系統的安裝經過網絡的方式完成。

提供nginx文件服務器(192.168.1.127),部署安裝源。

[root@node2 ~]# yum install nginx -y
[root@node2 ~]# vim /etc/nginx/conf.d/default.conf 
....
location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        autoindex on;
    }
    

[root@node2 ~]# mount /dev/cdrom /usr/share/nginx/html/
[root@node2 ~]# service nginx start


在Dom0(192.168.1.106)上爲虛擬機提供啓動過程當中使用的內核及引導文件:

[root@node1 ~]# mkdir /mnt/flash
[root@node1 ~]# mount /dev/cdrom1 /mnt/flash
[root@node1 ~]# cp /mnt/flash/isolinux/{initrd.img,vmlinuz} /xen/

建立磁盤鏡像文件:

[root@node1 ~]# qemu-img create -f qcow2 -o size=30G,preallocation=metadata /xen/xen1_disk.qcow2
[root@node1 ~]# ll -h /xen/xen1_disk.qcow2 
-rw-r--r-- 1 root root 31G Sep 23 11:44 /xen/xen1_disk.qcow2

編輯Xen虛擬機的配置文件:

[root@node1 ~]# vim /etc/xen/xen1
kernel = "/xen/vmlinuz"
ramdisk = "/xen/initrd.img"
vcpus = 1
memory = 512
name = "xen1"
disk = ['file:/xen/xen1_disk.qcow2,xvda,w']
vif = ["bridge=br0"]
on_reboot = "destroy"
on_crash = "destroy"


啓動虛擬機,開始安裝操做系統。

這裏使用xl命令完成對虛擬機的管理,xl命令使用時最好關閉xend服務。

[root@node1 ~]# xl create -f /etc/xen/xen1
Parsing config from /etc/xen/xen1
libxl: notice: libxl_numa.c:451:libxl__get_numa_candidate: NUMA placement failed, performance might be affected
DEBUG libxl__blktap_devpath 37 aio:/xen/xen1_disk.qcow2
DEBUG libxl__blktap_devpath 40 /dev/xen/blktap-2/tapdev0
Daemon running with PID 2908

列出當前全部的虛擬機,可你看到xen1已經啓動。

[root@node1 ~]# xl list
Name                                        ID   Mem VCPUs	State	Time(s)
Domain-0                                     0   496     1     r-----      16.5
xen1                                         3   512     1     -b----       4.2

進入虛擬機的控制檯完成安裝:

[root@node1 ~]# xl console xen1

選擇安裝過程使用的語言:

wKioL1YDU2WzLA-pAAE9iCzT3jQ052.jpg

選擇使用網絡的方式獲取安裝源:

wKiom1YDUyvB4QgMAADXzNp5TPU788.jpg

使用DHCP服務器獲取IP地址:

wKioL1YDUzrRvlgxAAE6WdvCmmg878.jpg

指定安裝源,這裏指向nginx提供的文件服務器:

wKioL1YDU1aBih5sAAEszd3Mz2Y163.jpg


wKiom1YDVGLSgmgmAACC75v8L60720.jpg

接下來的步驟與在圖形化界面下系統安裝的步驟基本一致,根據提示進行便可........

wKiom1YDVLPxySIgAAGdwLqkm8M006.jpg

安裝完成後,重啓操起操做系統。固然這裏不會重啓,定義domain時,設定on_reboot = "destroy",因此這裏的reboot會使虛擬機關機。

系統關機後,修改配置文件,這時系統的啓動不須要再依賴Dom0上的內核和ramfs文件,由於虛擬機自身上已經有內核和ramfs文件了。加上bootloader這一項,來引導虛擬機加載內核。

[root@node1 ~]# vim /etc/xen/xen1 
#kernel = "/xen/vmlinuz"
#ramdisk = "/xen/initrd.img"
bootloader="/usr/bin/pygrub"
vcpus = 1
memory = 512
name = "xen1"
disk = ['file:/xen/xen1_disk.qcow2,xvda,w']
vif = ["bridge=br0"]
on_reboot = "restart"
on_crash = "destroy"


啓動虛擬機,進入虛擬機的控制檯爲其配置網絡環境。

[root@node1 ~]# xl console xen1

wKioL1YDVlfTpaBEAADrVhXk5l0811.jpg

如上圖所示進入虛擬機的控制檯,退出使用「Ctrl+]」。而後配置網絡環境重啓網卡。

[root@localhost ~]# vi /etc/sysconfig/network-scripts/ifcfg-eth0 
DEVICE="eth0"
BOOTPROTO="dhcp"
NM_CONTROLLED="no"
ONBOOT="yes"
TYPE="Ethernet"
UUID="ce31b7c8-9039-4aaa-8b12-3b0e854941d0"

[root@localhost ~]# service network restart
[root@localhost ~]# ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
.....
    inet 192.168.1.152/24 brd 192.168.1.255 scope global eth0
.....

完成!!!


虛擬機的相關操做

掛起恢復虛擬機

在虛擬機運行過程當中能夠將虛擬機掛起(相似於VMware),實現過程以下:

查看當前正在運行的虛擬機:

[root@node1 xen]# xl list
Name                                        ID   Mem VCPUs	State	Time(s)
Domain-0                                     0   496     1     r-----      32.2
xen1                                         5   512     1     -b----       6.4

掛起xen1,將虛擬機的運行數據保存至一個文件上。

[root@node1 xen]# xl save xen1 /tmp/xen1.save
Saving to /tmp/xen1.save new xl format (info 0x0/0x0/251)
DEBUG libxl__device_destroy_tapdisk 66 type=aio:/xen/xen1_disk.qcow2 disk=:/xen/xen1_disk.qcow2

[root@node1 xen]# xl list
Name                                        ID   Mem VCPUs	State	Time(s)
Domain-0                                     0   496     1     r-----      36.0

恢復xen1:

[root@node1 xen]# xl restore /tmp/xen1.save 

[root@node1 xen]# xl list
Name                                        ID   Mem VCPUs	State	Time(s)
Domain-0                                     0   496     1     r-----      38.2
xen1                                         6   512     1     -b----       0.1


有別於真實的物理機,虛擬機運行在虛擬環境下,對其能夠動態地添加和拆除IO設備而不須要重啓系統。

動態添加磁盤

建立一個磁盤鏡像文件:

[root@node1 xen]# qemu-img create -f qcow2 -o size=20G,preallocation=metadata /tmp/test.qcow2

動態添加磁盤,添加時指定xen1上的設備名稱(前端設備),及對應於Dom0上的後端設備和設備的讀寫權限。

[root@node1 ~]# xl block-attach xen1 file:/tmp/test.qcow2 xvdb w

[root@node1 ~]# xl block-list xen1
Vdev  BE  handle state evt-ch ring-ref BE-path                       
51712 0   5      4     8      8        /local/domain/0/backend/vbd/5/51712
51728 0   5      4     10     867      /local/domain/0/backend/vbd/5/51728

拆除剛剛添加的磁盤:

[root@node1 xen]# xl block-detach xen1 51728
DEBUG libxl__device_destroy_tapdisk 66 type=aio:/tmp/test.qcow2 disk=:/tmp/test.qcow2


動態添加網絡設備

添加網卡,添加時指定虛擬機名稱和橋接的設備。

[root@node1 xen]# xl network-attach xen1 bridge=br0

[root@node1 xen]# xl network-list xen1
Idx BE Mac Addr.         handle state evt-ch   tx-/rx-ring-ref BE-path                       
0   0  00:16:3e:10:87:43     0     4      9   768/769         /local/domain/0/backend/vif/5/0
1   0  00:16:3e:4c:5e:1c     1     4     10  1280/1281        /local/domain/0/backend/vif/5/1

拆除網卡:

[root@node1 xen]# xl network-detach xen1 1
[root@node1 xen]# xl network-list xen1
Idx BE Mac Addr.         handle state evt-ch   tx-/rx-ring-ref BE-path                       
0   0  00:16:3e:4d:40:3d     0     4      9   769/768         /local/domain/0/backend/vif/6/0


Xen實時遷移

實驗環境:

node1:192.168.1.106

node2:192.168.1.127

iscsi節點:192.168.1.132

node1上的虛擬機實時遷移至node2上,這時須要將磁盤鏡像文件放在共享存儲上。共享存儲使用iscsi實現。


首先用一樣的方式將node2部署成爲Dom0。

iscsi節點上(192.168.1.132

安裝iscsi服務端程序

[root@node5 ~]# yum install -y scsi-target-utils

編輯配置文件,指定共享的塊設備和容許訪問的地址。

[root@node5 ~]# vim /etc/tgt/targets.conf 
.....
<target iqn.2015-09.com.xiaoxiao:server.target1>
    backing-store /dev/sdb
    initiator-address 192.168.1.0/24
</target>

[root@node5 ~]# service tgtd start


在node1和node2上

安裝iscsi客戶端程序

[root@node1 ~]# yum install -y iscsi-initiator-utils

對於客戶端而言,每個initiator都應該有一個本身的名稱,設置名稱。

[root@node1 ~]# echo "InitiatorName=`iscsi-iname -p iqn.2015-09.com.xiaoxiao`" > /etc/iscsi/initiatorname.iscsi
[root@node1 ~]# cat /etc/iscsi/initiatorname.iscsi
InitiatorName=iqn.2015-09.com.xiaoxiao:25d3444fe940

發現設備,發現設備的同時會啓動客戶端服務。

[root@node1 ~]# iscsiadm -m discovery -t st -p 192.168.1.132
Starting iscsid:                                           [  OK  ]
192.168.1.132:3260,1 iqn.2015-09.com.xiaoxiao:server.target1

創建會話,創建之後會在/var/lib/iscsi/目錄下保存此前發現的targets。下一次啓動時會自動讀取這個目錄,並獲取此前發現的target。

[root@node3 ~]# iscsiadm -m node -T iqn.2015-09.com.xiaoxiao:server.target1 -p 192.168.1.132 -l

[root@node1 ~]# fdisk -l /dev/sdb
 
Disk /dev/sdb: 53.7 GB, 53687091200 bytes
64 heads, 32 sectors/track, 51200 cylinders
Units = cylinders of 2048 * 512 = 1048576 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000


對應設備已經存在,接下來在node1上對其進行分區格式化,並掛載。

[root@node1 ~]# fdisk /dev/sdb
.......
[root@node1 ~]# mke2fs -t ext4 -b 4096 /dev/sdb1
[root@node1 ~]# mount /dev/sdb1 /xen/

將磁盤鏡像文件複製到共享的分區上,/xen目錄下的文件剛剛備份至了/tmp目錄下,在轉移磁盤鏡像文件時,不要忘了關閉虛擬機!!!

[root@node1 ~]# cp /tmp/xen/xen1_disk.qcow2 /xen/

xen1的配置文件/etc/xen/xen1同步至node2,同時在node2上過載共享設備至相同的目錄下:

[root@node1 ~]# scp /etc/xen/xen1 192.168.1.127:/etc/xen/xen1

[root@node2 ~]# mount /dev/sdb1 /xen/


開始遷移過程

node1上啓動虛擬機:

[root@node1 ~]# xl create -f /etc/xen/xen1

###############################
[root@node1 ~]# xl list
Name                                        ID   Mem VCPUs	State	Time(s)
Domain-0                                     0   496     1     r-----     155.7
xen1                                         8   512     1     -b----       3.0

[root@node2 ~]# xl list
Name                                        ID   Mem VCPUs	State	Time(s)
Domain-0                                     0   512     1     r-----     123.8


在node2上執行」xl migrate-receive「,準備好接受來自其餘節點的虛擬機轉移數據。

[root@node2 ~]# xl migrate-receive 
migration target: Ready to receive domain.
xl migration receiver ready, send binary domain data.

在node1上執行」xl migrate xen1 192.168.1.127「將xen1的虛擬機轉移至node2節點上。因爲xl的實時遷移是經過ssh傳輸機制實現的,因此在執行這條命令以後須要輸入對方主機的root密碼,才能開始傳輸。

[root@node1 ~]# xl migrate xen1 192.168.1.127
root@192.168.1.127's password:                           #輸入密碼
migration target: Ready to receive domain.
Saving to migration stream new xl format (info 0x0/0x0/251)
Loading new save file <incoming migration stream> (new xl fmt info 0x0/0x0/251)
 Savefile contains xl domain config
xc: Saving memory: iter 0 (last sent 0 skipped 0): 131072/131072  100%
xc: Saving memory: iter 1 (last sent 130942 skipped 130): 131072/131072  100%
xc: Saving memory: iter 2 (last sent 228 skipped 0): 131072/131072  100%      
xc: Saving memory: iter 3 (last sent 0 skipped 0): 131072/131072  100%   
DEBUG libxl__blktap_devpath 37 aio:/xen/xen1_disk.qcow2
DEBUG libxl__blktap_devpath 40 /dev/xen/blktap-2/tapdev0
migration sender: Target has acknowledged transfer.
migration sender: Giving target permission to start.
migration target: Transfer complete, requesting permission to start domain.
migration target: Got permission, starting domain.
migration target: Domain started successsfully.
migration sender: Target reports successful startup.
DEBUG libxl__device_destroy_tapdisk 66 type=aio:/xen/xen1_disk.qcow2 disk=:/xen/xen1_disk.qcow2
Migration successful.


最下面顯示傳輸完成在各節點上查看虛擬機狀態。

[root@node1 ~]# xl list
Name                                        ID   Mem VCPUs	State	Time(s)
Domain-0                                     0   492     1     r-----     200.7

[root@node2 ~]# xl list
Name                                        ID   Mem VCPUs	State	Time(s)
Domain-0                                     0   512     1     r-----     157.6
xen1                                        13   512     1     -b----       0.5

在傳輸過程當中,對被轉移的虛擬機發起ping操做,僅有一小段時間內沒法ping通。

相關文章
相關標籤/搜索