安装Xen与创建虚拟机

本文记录Xen的安装过程和虚拟机的创建、配置过程,记录过程中遇到的问题,和解决办法。

安装xen

准备工作

此处使用Xen-4.2.0和linux-3.2.30版本的内核。首先在官方网站上下载源码。
linux-3.2.30源码: https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.2.30.tar.gz
xen-4.2.0源码:http://www.xenproject.org/downloads/xen-archives/supported-xen-42-series/xen-420.html

创建一个工作目录,此处为/home/ganqt/xen-4.2。使用wget将源码文件下载到目录下。然后解压。

1
2
3
4
# 下载linux3.2.30源码
wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.2.30.tar.gz
# 下载xen4.2.0源码
wget http://bits.xensource.com/oss-xen/release/4.2.0/xen-4.2.0.tar.gz

安装Dom0的内核

Dom0的内核就是一个普通的linux内核,此处使用上面下载的linux3.2.30。先编译安装内核。

1
2
3
4
5
6
7
8
# 解压linux源码
tar -zxvf linux-3.2.30.tar.gz
# 安装
cd linux-3.2.30
make menuconfig
make all -j16
make modules_install
make install

Notice: 此处存在一个问题,make menuconfigure之后,生成的.config文件中,一共只有2000+行配置内容,而一个正常的./config文件一般是5000+行内容。使用这个配置编译后,产生的内核模块只有4个(使用make modules_install可以看到)。这回导致重新安装了内核之后,很多功能无法使用。
导致这个问题的原因是,执行make menuconfig的时候,配置程序会基于当前系统的配置情况生成默认的配置,而新的内核是基于xen的内核进行编译的,这可能导致配置程序无法识别当前的系统有哪些模块选项,从而使得配置程序没有选中任何模块选项。
解决办法有三种:1.使用现有的.config文件进行配置和编译;2.选择一个没有安装xen的正常内核启动,然后再从上面配置和编译;3.在一台没有安装xen的正常linux上先执行make menuconfig操作,再将.config文件拷贝到当前源码目录下进行编译。
此处我的解决办法是:1. 在一台linux-2.6.26版本的机器上先执行make menuconfig操作,可以什么都不修改,直接退出保存;2.将.config文件scp拷贝到当前的源码目录来;3.执行make oldconfig命令,对输出的选项全部选默认值;4.执行make menuconfig命令,选中自己想要编译进内核的模块;
然后再继续上面的编译和安装操作,即完成。

安装完成后,将会在/etc/grub.conf中新增一个启动项,留待有用。

编译安装xen

xen-4.2.0的安装过程参照了此处:https://www.rsreese.com/installing-xen-on-centos-6-from-source/
过程如下:

1
2
3
4
5
6
7
8
# 在configure过程中可能会提示一些依赖包没有安装,需要先安装

yum -y install python-devel dev86 iasl yajl-devel uuid-devel libuuid-devel libaio-devel SDL-devel pciutils-devel texinfo

cd ./xen-4.2.0
./configure --libdir=/lib64
make xen -j16 && make tools -j16 && make stubdom -j16
make install xen && make install xen-tools && make install stubdom

这些操作会在/boot目录下生成xen-4.2.0文件,和几个软连接。如图:
xen编译结果

添加启动项

现在需要利用前面编译好的linux内核,和安装的xen,添加一个启动项,使得系统启动后进入xen虚拟化模式。
/etc/grub.conf文件中前面编译安装新内核产生的启动项复制一份,然后修改成如下的样子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
default=0
timeout=5
splashimage=(hd0,0)/boot/grub/splash.xpm.gz

title CentOS (3.2.30-Xen-4.2.0)
root (hd0,0)
kernel /boot/xen-4.2.0.gz dummy=dummy dom0_mem=2048M
module /boot/vmlinuz-3.2.30 ro root=UUID=316e07dc-bc9e-4003-bb49-7a4a76f690a9 rd_NO _LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD quiet SYSFONT=latarcyrheb-sun16 rhgb crashkernel= 128M KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM
module /boot/initramfs-3.2.30.img

title CentOS (3.2.30-kvm)
root (hd0,0)
kernel /boot/vmlinuz-3.2.30-kvm ro root=UUID=316e07dc-bc9e-4003-bb49-7a4a76f690a9 r d_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD quiet SYSFONT=latarcyrheb-sun16 rhgb crashker nel=128M KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM
initrd /boot/initramfs-3.2.30-kvm.img

修改并保存后,重启系统,如果顺利,将自动进入xen虚拟化模式的linux。

创建虚拟机

xen可以使用virt-manager虚拟机管理器安装虚拟机,但此处直接创建一个镜像,从宿主机拷贝必要的文件后, 直接从创建的镜像启动。具体步骤如下:

创建镜像文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cd /home/ganqt
mkdir img
cd img
touch node1.vmdisk
dd if=/dev/zero of=node1.vmdisk bs=1M seek=20000 count=1
# 格式化虚拟磁盘
mkfs.ext3 node1.vmdisk
# 挂载虚拟磁盘
mount -o loop node1.vmdisk /mnt
# 拷贝必须的系统文件,这个过程可能有点耗时
cp -ax /{root,dev,var,etc,usr,bin,sbin,lib,boot} /mnt
# 拷贝/lib64目录
cp -rf /lib64 /mnt/lib64
echo "/dev/xvda1 / ext3 defaults 1 1" > /mnt/etc/fstab
# 创建/sys,/opt目录和/proc目录,否则可能无法启动系统
mkdir /mnt/{sys,proc,opt}
# 卸载虚拟磁盘
umount /mnt

编写配置文件

在相同目录下创建配置文件node1.cfg,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
kernel = "/boot/vmlinuz-3.2.30-kvm"
ramdisk = "/boot/initramfs-3.2.30-kvm.img"
memory = 2048
name = "node1"
vcpus = 4
ip = "192.168.226.220"
netmask = "255.255.255.0"
gateway = "192.168.226.218"
vif = [ '' ]
disk = [ 'file:/home/ganqt/img/node1.vmdisk,xvda1,w' ]
root = "/dev/xvda1 ro"
extra = "4 console=hvc0"

上面的配置文件中,指定了使用/boot/vmlinuz-3.2.30-kvm位置的内核,这个就是上面编译安装的内核。使用/home/ganqt/img/node1.vmdisk指定的虚拟磁盘镜像文件启动系统。

启动虚拟机

上面安装完xen并重启进入xen虚拟化模式后,可以使用xen相关的命令测试是否正常;

1
2
3
xm --help   #查看命令使用帮助
xm list # 查看虚拟机列表
xm info # 查看

如果xen相关命令无法使用,提出错误,请参考这篇博客:http://www.oserror.com/usage/204.html

1
2
# 驱动虚拟机的命令为
xm create -c node1.cfg

一些问题

  1. 启动虚拟机后,其实找不到root = "/dev/xvda1"设备,大概的错误提示如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    dracut: dracut-004-303.el6
    udev: starting version 147
    dracut: Starting plymouth daemon
    dracut Warning: No root device "block:/dev/xvda1" found
    dracut Warning: Boot has failed. To debug this issue add "rdshell" to the kernel command line.
    dracut Warning: Signal caught!
    dracut Warning: Boot has failed. To debug this issue add "rdshell" to the kernel command line.
    Kernel panic - not syncing: Attempted to kill init!
    Pid: 1, comm: init Not tainted 2.6.32-358.2.1.el6.x86_64 0000001
    Call Trace:
    [<ffffffff8150d248>] ? panic+0xa7/0x16f
    [<ffffffff81073ae2>] ? do_exit+0x862/0x870
    [<ffffffff81182965>] ? fput+0x25/0x30
    [<ffffffff81073b48>] ? do_group_exit+0x58/0xd0
    [<ffffffff81073bd7>] ? sys_exit_group+0x17/0x20
    [<ffffffff8100b072>] ? system_call_fastpath+0x16/0x1b

搜了一圈后,在这篇博客里找到了解决办法,解决办法是如下:

1
2
# mkinitrd -f -v --preload xenblk /boot/initramfswithxenblk.img $(uname -r)
mkinitrd -f -v --preload xenblk /boot/initramfswithxenblk.img 3.2.30-kvm

  1. 上述问题解决了,但是接着提示了一个Selinux的问题,问题提示如下:
    1
    2
    3
    4
    dracut Warning: Initial SELinux policy load failed.
    dracut: FATAL: Initial SELinux policy load failed. Machine in enforcing mode. To disable selinux, add selinux=0 to the kernel command line.
    dracut: Refusing to continue
    dracut Warning: Signal caught!

这是selinux的相关问题导致的。解决办法如下:

1
2
mount -o loop ./node1.vmdisk /mnt
vim /mtn/etc/selinux/config

SELINUX=xxx一样改成SELINUX=0
然后

1
2
umount /mnt
xm create -c node1.cfg