您的位置:首页 > 其它

Xen半虚拟化的实现及实时迁移

2015-09-24 10:31 417 查看
虚拟化简介
hypervisor

hypervisor是一个虚拟化软件,直接运行在硬件之上,虚拟机搭建在hypervisor之上,多个虚拟机通过hypervisor共享底层的硬件资源。hypervisor的主要功能是对底层的硬件资源进行管理,协调运行在其上的虚拟机对硬件资源的访问,并且保护每一个虚拟机在运行过程中不受其他虚拟机的影响。
完全虚拟化

完全虚拟化即虚拟机运行在模拟的硬件之上。在hypervisor中运行的虚拟机表现为一个运行在用户空间的进程,虚拟机上的进程需要执行特权指令时,即需要对底层的硬件进行访问时,其相关的操作(例如cpu指令)会被hypervisor捕获,由hypervisor完成执行并返回结果。在这个过程中hypervisor会给处理器带来很大的开销。在硬件辅助虚拟化中,这个过程由硬件来辅助完成,大大提升了性能。在完全虚拟化环境中,虚拟机上的操作系统不会意识到自己运行在虚拟化的环境中,客户端的操作系统内核无需修改。对应的实现软件有VMware Workstation,KVM.......
半虚拟化
在半虚拟化环境中,hypervisor将底层硬件资源的功能以API(hyper call)的形式向上输出,虚拟机上的操作系统通过调用这些hyper call来完成特权指令的执行。这减小了hypervisor的开销,但是内核执行相应的操作需要基于hyper call来完成,这需要对内核进行修改,这使得像windows这样的操作系统很难运行在半虚拟化环境中。

Xen基本组件
xen是半虚拟化的一种实现,操作系统的内核需要进行修改才能运行在xen上。Linux的内核中已经集成了这部分代码,能够直接运行在xen的虚拟化平台上。如下是xen的结构图:




xen有3个基本组件:

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
splashimage=(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
选择安装过程使用的语言:



选择使用网络的方式获取安装源:



使用DHCP服务器获取IP地址:



指定安装源,这里指向nginx提供的文件服务器:








接下来的步骤与在图形化界面下系统安装的步骤基本一致,根据提示进行即可........



安装完成后,重启操起操作系统。当然这里不会重启,定义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



如上图所示进入虚拟机的控制台,退出使用“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
.....
完成!!!

虚拟机的相关操作
[b]挂起恢复虚拟机[/b]
在虚拟机运行过程中可以将虚拟机挂起(类似于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通。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  虚拟化 xen 实时迁移