在 Xen VPS 上安装 Kloxo 可能遇到的问题

昨天有位客户在 VPS 上安装 Kloxo 后重启导致错误而不能登录,VPSee 用控制台登录后发现客户的 VPS 启动后就 kernel panic 了,这是由客户安装 Kloxo 后错误设置 selinux 造成的,这个问题好办,关闭 selinux 就可以了。然后紧接着第二个问题来了,系统启动到快结束的时候报错:

init: no more processes left in this runlevel

Google 了一下发现其他人在 VPS 上安装 Kloxo 时也遇到同样的问题,Getting: init: no more processes left in this runlevel after installing Kloxo,但是没人给出解决方案。VPSee 不懂 Kloxo,不知道在安装 Kloxo 时,Kloxo 的安装脚本修改了哪些配置,不过看了错误提示后第一反应就是检查 /etc/inittab 文件,打开 /etc/inittab 后发现缺少一行,Xen domU 的默认控制台设备是 xvc0,如果缺少这一行在服务器终端输入 xm console 输入后就会报以上错误,因为没有指定 xvc0 的话 xm console 将无法 attache 到 domU 的控制台。知道了原因,解决办法就容易了,直接在 /etc/inittab 文件末尾加上下面这行就可以了:

# vi /etc/inittab
...
xvc0:2345:respawn:/sbin/mingetty xvc0

我们不推荐 VPS 用户安装 cPanel/DirectAdmin/ISPConfig/Webmin/Kloxo 这类控制面板,原因是:

  • 玩 VPS 的目的就是能自己控制和管理服务器、自由定制、压榨 VPS 以取得最大性能,如果在自己 VPS 上安装了各种笨重的控制面板,就和 shared hosing(共享主机)没有区别了,那就没有必要花更多的钱购买 VPS 了;
  • 对于 256MB VPS 来说,最小系统启动后就占据了 80MB 左右的内存,通常安装控制面板都会附带安装一堆没用的东西或者自己不需要的东西,比如有的甚至还带上 Clam AntiVirus 杀毒软件,这样安装完控制面板和启动 mysql/apache/php 后又消耗了120 MB 左右的内存,剩下几十 MB 怎么用呢?花钱买了 256MB,到最后自己只用了 40MB,不划算啊;
  • 控制面板的安装脚本通常会修改一些系统配置文件以便达到 “一键安装” 的目的,但是事实上不是那么简单,使用控制面板安装 mysql 安装到哪里了呢?配置文件在哪里呢?更糟糕的是不同的控制面板配置文件也都是不同的。安装控制面板很容易,安装完后想删除就不容易了,因为不知道控制面板在安装过程中到底装了哪些软件、增加和修改了哪些配置;
  • 安装控制面板会引入新的 bug 和安全隐患,控制面板是软件,其开发人员也是普通人,做软件开发就一定会有 bug,所以引入控制面板就实际上给自己的系统引入 bug 和麻烦,这样其实是增加了复杂度,而不是变得容易了;
  • 过度依赖控制面板不利于 Linux 的学习和使用,如果自己维护的 VPS 出现问题不利于排错,因为控制面板装了一堆东西把事情搞复杂了,出错机会也增大了,排错更困难了。

在 Ubuntu 上源码安装 Xen

这篇文章是在写 在 Debian 上源码安装 Xen 的时候一起写的,原本以为 Ubuntu 和 Debian 很相似、差别不大,配置过程可以直接套用而不用大修改,试了才知道其实不是那么简单。Ubuntu 9.10 使用的是 grub 2.0,被证实一些 bug 会导致 Xen 不能在 grub 2.0 的引导下正常启动,所以一种 workaround 的办法就是删除掉 grub 2.0,使用老版本的 grub. VPSee 不喜欢在服务器上使用 Ubuntu 的最新版本就是因为 Ubuntu 更新速度太快,版本发行太频繁,导致很多旧版本的问题还没解决就要开始赶鸭子上架推新版本,对了,今天好像是 Ubuntu 10.04 LTS 的发行日。以下的操作记录使用最新的 Xen 4.0.0 源代码版本和 Ubuntu 9.10,这里还有在 CentOS 下源码安装 Xen 的过程。如果你在 Ubuntu 10.04 上编译安装 Xen 4.0.1 可能会遇到 xend 启动问题

安装需要的软件包

首先最小化安装 Ubuntu,然后安装编译 Xen 和 Linux xen kernel 所需要的软件包:

$ sudo apt-get install gcc g++ make patch libssl-dev bzip2 gettext \
zlib1g-dev python libncurses5-dev libjpeg62-dev libx11-dev \
libgcrypt11-dev pkg-config bridge-utils bcc bin86 libpci-dev \
libsdl-dev python-dev texinfo libc6-dev uuid-dev bison flex fakeroot \
build-essential crash kexec-tools makedumpfile  libncurses5 \
libncurses5-dev iasl gawk

$ sudo apt-get build-dep linux 

安装 Xen hypervisor 和 tools

到 http://www.xen.org/products/xen_source.html 下载最新的 Xen 源代码,然后解开、编译、安装,标准的 Linux 软件源码安装动作:

$ tar zxvf xen-4.0.0.tar.gz
$ cd xen-4.0.0/
$ make xen tools stubdom
$ sudo make install-xen install-tools install-stubdom

上面 make stubdom 的时候会从网上自动下载一些东西,所以如果是用代理上网的话需要在自己根目录下的 .wgetrc 里加上代理服务器,以便 wget 能通过代理正常下载:

$ vi .wgetrc
http_proxy = http://proxy.vpsee.com:3128/
use_proxy = on

加入到自动启动脚本中:

$ sudo update-rc.d xend defaults 20 21
$ sudo update-rc.d xendomains defaults 21 20

安装 Xen 内核

下载 xen 内核,给内核打补丁:

$ cd
$ wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.31.8.tar.bz2
$ tar -xjf linux-2.6.31.8.tar.bz2

$ wget http://gentoo-xen-kernel.googlecode.com/files/xen-patches-2.6.31-10.tar.bz2
$ mkdir xenpatch-2.6.31.8
$ cd xenpatch-2.6.31.8
$ tar -xjf ../xen-patches-2.6.31-10.tar.bz2
$ cd ..

$ cd linux-2.6.31.8
$ for i in `ls ../xenpatch-2.6.31.8/`; do patch -p1 < ../xenpatch-2.6.31.8/"$i"; done

配置内核,直接把系统已经存在的配置文件拷过来然后在此基础上修改:

$ cp /boot/config-2.6.31-14-server .config
$ make menuconfig

Processor type and features --->
  [*] Enable Xen compatible kernel
Networking support --->
  Networking options --->
    <*> 802.1d Ethernet Bridging
Device Drivers --->
  XEN --->
    [*] Privileged Guest (domain 0)
     Backend driver support
       Block-device backend driver
       Block-device tap backend driver
       Block-device tap backend driver 2
       Network-device backend driver
       PCI-device backend driver
       SCSI backend driver
       USB backend driver
    <*> Block-device frontend driver
    <*> Network-device frontend driver
     SCSI frontend driver
     USB frontend driver
    <*> Framebuffer-device frontend driver
    <*>   Keyboard-device frontend driver
    [*] Disable serial port drivers
    <*> Export Xen attributes in sysfs
        Xen version compatibility (3.3.0 and later) --->
           3.3.0 and later

配置好内核参数以后,保存配置文件、退出配置界面就可以开始编译 Linux 内核了:

$ make
$ sudo make install
$ sudo make modules_install
$ sudo update-initramfs -c -k 2.6.31.8
$ sudo depmod 2.6.31.8

如果 Xen 加了内核模块的话加入 /etc/modules 文件以便启动时候自动加载:

$ sudo vi /etc/modules
...
netbk
blkbk

Ubuntu 9.10 默认用的是 grub 2.0,被证实一些 bug 会导致 Xen 不能正常启动,删除 grub 2.0 换成老版本的 grub:

$ sudo apt-get purge grub-pc
$ sudo rm /boot/grub/*
$ sudo apt-get install grub
$ sudo grub-install --recheck /dev/sda
$ sudo update-grub
$ sudo vi /boot/grub/menu.lst

重新启动系统,就应该可以进入 dom0 了:

$ sudo reboot

Troubleshooting

如果重新启动系统能正常进入 dom0 但是执行 xm 命令时报错:

$ sudo xm list
Error: Unable to connect to xend: No such file or directory. Is xend running?

检查 Xen 日志,发现 'Permission denied' 问题,这也是常见问题,是因为 xen tools 和内核不搭配:

$ vi /var/log/xen/xend.log
...
[2010-04-16 11:55:57 2320] INFO (SrvDaemon:219) Xend exited with status 1.
[2010-04-16 13:56:04 13207] INFO (SrvDaemon:331) Xend Daemon started
[2010-04-16 13:56:04 13207] INFO (SrvDaemon:335) Xend changeset: unavailable.
[2010-04-16 13:56:04 13207] ERROR (SrvDaemon:347) Exception starting xend ((13, 'Permission denied'))
...

$ vi /var/log/xen/xend-debug.log
...
Xend started at Fri Apr 16 13:56:04 2010.
domctl operation failed -- need to rebuild the user-space tool set?
sysctl operation failed -- need to rebuild the user-space tool set?
Exception starting xend: (13, 'Permission denied')
...

所以解决办法就是下载对应的 xen 内核版本和 xen 工具。

RedHat 发布 RHEL 6 Beta 版本

开会回来,会议只用了1天,剩下3天都在休息,会议地点在度假胜地,没有 wifi,环山靠海,所以手机信号也不好,很艰难的用 iPhone 3G 开通了几个 VPS,还好客户都很有耐心,回来需要进一步把客户资料整理一下。

上个星期 RedHat 发布了他们下一代旗舰产品 RedHat Enterprise Linux 6 的 Beta 版本,下载地址可以在这里找到。RHEL 6 去掉了 Xen,只保留了 KVM,KVM 自从2009年9月被引入到 RHEL 5.4 以后在 RedHat 的大力支持下发展迅猛。我们以前分析过目前 KVM 的稳定性和 Xen 比起来还有待提高,工业界应用不广,Amazon, Rackspace Cloud, Linode, SliceHost, GoGrid, Right Scale 等业界一批领先的云计算和 VPS 服务商都是采用成熟的 Xen 虚拟技术, IBM/HP/Dell/Intel 都有在 Xen 上投资,并都开发了针对 Citrix XensServer 的服务器和完整的企业虚拟解决方案。Hosting 行业只有少数几个规模很小的 KVM VPS 服务商,不知道 RHEL 6 正式推出后,KVM 的状况会不会得到大的改善,能得到大厂商的支持很重要。

VPSee 对 KVM 比较看好的一点就是,以后任何运行 Linux 的设备(电脑、手机、阅读器、路由器等)都可以作为 host 来做虚拟平台,应用范围将比 Xen 大很多,现在 Xen 只限在服务器领域,如果要移植到手机上,不但手机操作系统内核要改,而且 Xen 也要改,当然,KVM 也不这么乐观,如果想运行 KVM,必须有支持 Intel VT 或 AMD SVM 的 CPU,目前手机等设备都不支持这类 CPU.

RHEL 6 Beta 的下载很火爆,RedHat 的 FTP 服务器经常 “too many connections”,VPSee 挤了半天才挤进去,下面是两张在 VMware 上的安装截图:

my mac sys info

my mac sys info

在 CentOS 下源码安装 Xen

在 CentOS 源码编译安装 Xen 的过程和在 Debian 上编译安装 Xen 的过程差不多,只是第一步安装编译所需要的工具和软件包有所不同,后续步骤有点小差别,不过方法都是一样的,这也说明各个 Linux 发行版之间的区别真的不大,没有必要为选择 Linux 发行版而发愁。编译一个 Xen 内核和编译一个普通 Linux 内核没有什么不同,如果发现编译后的内核启动不了,出现 kernel panic 的情况,多半是内核与机器的硬件没有配置好的原因,和 Xen 没有关系,比如常见的 switchroot: mount failed: No such file or directory 就可能是因为内核配置的时候忘了加上 root 的硬盘驱动,也可能找到驱动了但是挂载的时候发现文件系统类型不对,等等。VPSee 在一台 Intel(R) Core(TM) i3 CPU 540 @ 3.07GHz, 4GB 机器上使用最新的 Xen 4.0.0 源代码和 CentOS 5.4 完成以下操作。这里还有在 Ubuntu 上源码安装 Xen 的详细过程。如果觉得源码安装很麻烦的话,这里有 在 CentOS 上安装和配置 Xen 的二进制安装过程。

安装需要的软件包

首先最小化安装 CentOS,然后安装编译 Xen 和 Linux xen kernel 所需要的软件包:

# yum groupinstall "Development Tools" 
# yum install hmaccalc ncurses-devel zlib-devel openssl-devel python-devel \
bridge-utils  libtool-ltdl iasl xorg-x11-drv-evdev xorg-x11-drv-fbdev \
xorg-x11-drv-i810-devel xorg-x11-drv-via-devel xorg-x11-proto-devel \
xorg-x11-server-sdk xorg-x11-xtrans-devel

安装完以上软件包后,剩下的操作就和在 Debian 上编译和安装 Xen 差不多了。

安装 Xen hypervisor 和 tools

到 http://www.xen.org/products/xen_source.html 下载最新的 Xen 源代码,然后解开、编译、安装,标准的 Linux 软件源码安装动作:

$ tar zxvf xen-4.0.0.tar.gz
$ cd xen-4.0.0/
$ make xen tools stubdom
# make install-xen install-tools install-stubdom

上面 make stubdom 的时候会从网上自动下载一些东西,所以如果是用代理上网的话需要在自己根目录下的 .wgetrc 里加上代理服务器,以便 wget 能通过代理正常下载:

$ vi .wgetrc
http_proxy = http://proxy.vpsee.com:3128/
use_proxy = on

加入到启动脚本:

# /sbin/chkconfig --add xend
# /sbin/chkconfig --add xendomains
# /sbin/chkconfig xend on
# /sbin/chkconfig xendomains on

安装 Xen 内核

下载 Linux 内核后给内核打 xen 补丁:

$ cd
$ wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.31.8.tar.bz2
$ tar -xjf linux-2.6.31.8.tar.bz2

$ wget http://gentoo-xen-kernel.googlecode.com/files/
xen-patches-2.6.31-10.tar.bz2
$ mkdir xenpatch-2.6.31.8
$ cd xenpatch-2.6.31.8
$ tar -xjf ../xen-patches-2.6.31-10.tar.bz2
$ cd ..

$ cd linux-2.6.31.8
$ for i in `ls ../xenpatch-2.6.31.8/`; \
do patch -p1 < ../xenpatch-2.6.31.8/"$i"; done

配置带 xen 的 Linux 内核:

$ make menuconfig

Processor type and features --->
  [*] Enable Xen compatible kernel
Networking support --->
  Networking options --->
    <*> 802.1d Ethernet Bridging
Device Drivers --->
  XEN --->
    [*] Privileged Guest (domain 0)
     Backend driver support
       Block-device backend driver
       Block-device tap backend driver
       Block-device tap backend driver 2
       Network-device backend driver
       PCI-device backend driver
       SCSI backend driver
       USB backend driver
    <*> Block-device frontend driver
    <*> Network-device frontend driver
     SCSI frontend driver
     USB frontend driver
    <*> Framebuffer-device frontend driver
    <*>   Keyboard-device frontend driver
    [*] Disable serial port drivers
    <*> Export Xen attributes in sysfs
        Xen version compatibility (3.3.0 and later) --->
           3.3.0 and later

配置好内核参数以后,保存并退出,开始编译 Linux 内核:

$ make
$ make modules
# make modules_install
# make install
# /sbin/depmod 2.6.31.8

更新 grub:

#  vi /boot/grub/menu.lst
...
title CentOS (2.6.31.8-xen)
        root (hd0,0)
        kernel /xen-4.0.0.gz
        module /vmlinuz-2.6.31.8 ro root=/dev/VolGroup00/LogVol00
        module /initrd-2.6.31.8.img
...

重启系统,确认 Xen 安装成功:

# reboot

# uname -a
Linux localhost.localdomain 2.6.31.8 #2 SMP Tue Apr 20 11:19:19 SAST 2010 x86_64 GNU/Linux

# xm list
Name                                        ID   Mem VCPUs      State   Time(s)
Domain-0                                     0  3713     4     r-----     36.0

在 Debian 上源码安装 Xen

博客上有位网友遇到源代码安装的问题,留了不少评论。源代码安装不难就是麻烦,如果不是特别需要还是选择二进制安装比较方便,直接用 yum install,apt-get install 或者 emerge 轻松搞定。源代码安装有两个好处,一个是可以定制 Linux 内核,这样可以删除网卡、无线、USB、蓝牙、多余的文件系统等 n 多服务器不需要的硬件驱动和模块,得到一个最小而且针对硬件编译过的内核,性能会好很多;第二个就是二进制发布往往滞后,所以如果想尝鲜新功能的话就只能源码安装。安装服务器前对每台服务器的硬件都做记录是个好习惯,特别是服务器多的时候,方便以后需要的时候查阅,VPSee 在内部使用 Wiki 记录服务器硬件信息,用源代码控制工具来追踪系统配置文件的更改。以下的操作记录使用最新的 Xen 4.0.0 源代码版本和 Debian 5.04,这里有在 CentOS 下源码安装 Xen 和 在 Ubuntu 上源码安装 Xen 的过程。

安装需要的软件包

首先最小化安装 Debian,然后安装编译 Xen 和 Linux xen kernel 所需要的软件包:

# apt-get install bcc bin86 gawk bridge-utils iproute libcurl3 \
libcurl4-openssl-dev bzip2 module-init-tools transfig tgif texinfo \
pciutils-dev mercurial build-essential make gcc libc6-dev \
zlib1g-dev python python-dev python-twisted libncurses5-dev \
patch libvncserver-dev libsdl-dev libjpeg62-dev uuid-dev iasl

# apt-get build-dep linux

如果是64位系统的话,还需要安装:

# apt-get install gcc-multilib

安装 Xen hypervisor 和 tools

到 http://www.xen.org/products/xen_source.html 下载最新的 Xen 源代码,然后解开、编译、安装,标准的 Linux 软件源码安装动作:

$ tar zxvf xen-4.0.0.tar.gz
$ cd xen-4.0.0/
$ make xen tools stubdom
# make install-xen install-tools install-stubdom

上面 make stubdom 的时候会从网上自动下载一些东西,所以如果是用代理上网的话需要在自己根目录下的 .wgetrc 里加上代理服务器,以便 wget 能通过代理正常下载:

$ vi .wgetrc
http_proxy = http://proxy.vpsee.com:3128/
use_proxy = on

加入到自动启动脚本中:

# update-rc.d xend defaults 20 21
# update-rc.d xendomains defaults 21 20

安装 Xen 内核

下载 xen 内核,给内核打补丁:

$ cd
$ wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.31.8.tar.bz2
$ tar -xjf linux-2.6.31.8.tar.bz2

$ wget http://gentoo-xen-kernel.googlecode.com/files/
xen-patches-2.6.31-10.tar.bz2
$ mkdir xenpatch-2.6.31.8
$ cd xenpatch-2.6.31.8
$ tar -xjf ../xen-patches-2.6.31-10.tar.bz2
$ cd ..

$ cd linux-2.6.31.8
$ for i in `ls ../xenpatch-2.6.31.8/`; \
do patch -p1 < ../xenpatch-2.6.31.8/"$i"; done

配置内核,直接把系统已经存在的配置文件拷过来然后在此基础上修改:

$ cp /boot/config-2.6.31-14-server .config
$ make menuconfig

Processor type and features --->
  [*] Enable Xen compatible kernel
Networking support --->
  Networking options --->
    <*> 802.1d Ethernet Bridging
Device Drivers --->
  XEN --->
    [*] Privileged Guest (domain 0)
     Backend driver support
       Block-device backend driver
       Block-device tap backend driver
       Block-device tap backend driver 2
       Network-device backend driver
       PCI-device backend driver
       SCSI backend driver
       USB backend driver
    <*> Block-device frontend driver
    <*> Network-device frontend driver
     SCSI frontend driver
     USB frontend driver
    <*> Framebuffer-device frontend driver
    <*>   Keyboard-device frontend driver
    [*] Disable serial port drivers
    <*> Export Xen attributes in sysfs
        Xen version compatibility (3.3.0 and later) --->
           3.3.0 and later

配置好内核参数以后,保存配置文件、退出配置界面就可以开始编译 Linux 内核了:

$ make
# make install
# make modules_install
# update-initramfs -c -k 2.6.31.8
# depmod 2.6.31.8

如果 Xen 加了内核模块的话加入 /etc/modules 文件以便启动时候自动加载:

# vi /etc/modules
...
netbk
blkbk

更新 grub:

#  update-grub
#  vi /boot/grub/menu.lst

重新启动系统,就应该可以进入 dom0 了:

# reboot

# uname -a
Linux debian 2.6.31.8 #1 SMP Sat Apr 17 09:26:20 SAST 2010 x86_64 GNU/Linux

# xm list
Name                                        ID   Mem VCPUs      State   Time(s)
Domain-0                                     0   3713     4     r-----     48.7

如何把 File-based 的 Xen 虚拟机转化成 LVM-based 的

今天 SUN(还是习惯叫 SUN)做了一个 workshop,他们做了一个 ppt,宣传了一下他们的产品,提到了 SUN VDI, VMware VDI 应用到 SunRay 上的一些东西。VPSee 关心的不是他们的 ppt,是上个月从他们那里 “骗” 来的设备到了没有。今天收获不错,收到 4台 SUN Fire V20z,1台 SUN Fire X2200 M2,10几个 SunRay 客户机。SUN Fire V20z 是很老的机型,现在已经停产,不过硬件配置还是蛮强劲的,2颗双核 AMD Opteron 2.2 GHz,8GB RAM,2个 73 GB Ultra320 SCSI 硬盘。现在还没有想好服务器做什么用,先玩玩再说~~

sun fire v20z

说正题⋯⋯

Xen 支持多种存储方式,大致可分三类:最普通最直接的文件存储(file storage),本地物理硬盘或者 LVM 存储(physical devices/LVM storage),更高级一点的 NFS、NAS、GNBD、SAN、AoE、iSCSI 网咯存储(network storage)等。这三类存储介质和方法都被我们用到了生产环境,各有各的优点,VPSee 偏向混合使用,有助于我们了解不同技术的特性。

先扫描一下系统,看看系统上的 LVM 是怎么分配的:

# vgscan 
  Reading all physical volumes.  This may take a while...
  Found volume group "vpseexen" using metadata type lvm2

# lvscan 
  ACTIVE            '/dev/vpseexen/root' [6.52 GB] inherit
  ACTIVE            '/dev/vpseexen/swap_1' [9.25 GB] inherit
  ACTIVE            '/dev/vpseexen/home' [116.88 GB] inherit

假设我们要转化的虚拟机镜像是 xen01.img(对应的交换分区文件是 xen01.swap)。首先我们需要在卷组上创建一个逻辑卷用来复制虚拟机镜像(xen01.img),逻辑卷大小和 xen01.img 一样,还需要一个逻辑卷用来复制 swap 文件(xen01.swap):

# lvcreate -L10G -n xen01_root vpseexen
# lvcreate -L512M -n xen01_swap vpseexen

创建成功后就会出现2个新的逻辑卷:

# lvscan 
  ACTIVE            '/dev/vpseexen/root' [6.52 GB] inherit
  ACTIVE            '/dev/vpseexen/swap_1' [9.25 GB] inherit
  ACTIVE            '/dev/vpseexen/home' [116.88 GB] inherit
  ACTIVE            '/dev/vpseexen/xen01_root' [10.00 GB] inherit
  ACTIVE            '/dev/vpseexen/xen01_swap' [512 MB] inherit

接着把虚拟机的镜像内容 dd 到逻辑卷上:

# dd if=/home/vpsee/xen/xen01.img of=/dev/vpseexen/xen01_root
# dd if=/home/vpsee/xen/xen01.swap of=/dev/vpseexen/xen01_swap

修改虚拟机的 Xen 配置文件,guest 和 host 使用相同的 Xen 内核启动:

# vi /etc/xen/xen01

kernel = "/boot/vmlinuz-2.6.26-2-xen-amd64"
ramdisk = "/boot/initrd.img-2.6.26-2-xen-amd64"
vcpus = 1
memory = 256
name = "xen01"
vif = [ '' ]
disk = [
'phy:/dev/vpseexen/xen01_root,sda1,w',
'phy:/dev/vpseexen/xen01_swap,sda2,w' ]
root = "/dev/sda1"
extra = "fastboot"

最后启动拷贝成功的基于 LVM 的虚拟机就可以了:

# xm create xen01

在 Xen 下运行 Openfiler

在我们的 IT 环境中用到了大量 NAS,有专业的 Sun StorageTek NAS 也有淘汰下来的 PC 做的 NAS,我们几乎虚拟化了所有的服务器,唯一没有虚拟化的部分可能就是存储系统,因为虚拟机的 IO(包括磁盘 IO 和网络 IO)性能目前还达不到裸机的水平。Openfiler 是一个的网络存储管理系统,其功能和 FreeNAS 类似,不同的是 Openfiler 基于 Linux 2.6,支持64位,而 FreeNAS 基于 FreeBSD 的(直到最近才支持64位),Openfiler 的功能和 FreeNAS 差不多,都能支持 NAS, SAN, CIFS, NFS, HTT/DAV, FTP, SIMBA, RSYNC, iSCSI 等,Openfiler 能更好的支持 RAID, LVM,不过 FreeNAS 能支持 ZFS(VPSee 对 ZFS 文件系统非常感兴趣,如果 Linux 上有类似的克隆就好了)。

VPSee 想对虚拟机运行存储系统和真实机器运行存储做个对比,看看性能上到底有多大的损失。Openfiler 官方网站上有 VMware ESX Virtual Appliance, XenServer XVA Virtual Appliance, Xen domU Filesystem 等多个预装好的虚拟镜像可以下载。我们选择 Xen 作为运行 Openfiler 的虚拟环境,本来以为 Openfiler 的镜像和 stacklet.com 上面的 Xen 镜像一样直接下载下来就可以用,结果不是这么简单,下载的只是一个文件系统,要自己做一些配置,和徒手安装 Xen domU 的过程差不多。

下载 Openfiler 的 Xen tar 包:

# mkdir -p /xen/openfiler
# cd /xen/openfiler
# wget http://www.rpath.org/rbuilder/downloadImage?fileId=26670

创建一个 LVM 区来存放 Openfiler:

# lvcreate -L 10G -n openfiler XenGroup

在新建的 LVM 上创建 Ext3 文件系统,并作为 Openfiler 虚拟机的 root 根系统:

# mkfs.ext3 /dev/XenGroup/openfiler
# e2label /dev/XenGroup/openfiler root

挂载 root 文件系统后,把下载下来的 openfiler-2.3-x86_64.tar.gz 解压到 /mnt 里面去:

# mount /dev/XenGroup/openfiler /mnt/
# cd /mnt/
# tar xzpvf /xen/openfiler/openfiler-2.3-x86_64.tar.gz

解开 openfiler-2.3-x86_64.tar.gz 后会在 /mnt 下产生一个完整的 Linux 系统,我们需要把这个 Linux 的内核拷贝出来以便加到 Xen 虚拟机配置文件中:

# mkdir -p /xenboot/
# cp /mnt/boot/config-2.6.21.7-3.20.smp.gcc3.4.x86_64.xen.domU /xenboot/
# cp /mnt/boot/initrd-2.6.21.7-3.20.smp.gcc3.4.x86_64.xen.domU.img /xenboot/
# cp /mnt/boot/System.map-2.6.21.7-3.20.smp.gcc3.4.x86_64.xen.domU /xenboot/
# cp /mnt/boot/vmlinuz-2.6.21.7-3.20.smp.gcc3.4.x86_64.xen.domU /xenboot/

解除挂载:

# cd 
# umount /mnt

创建启动 Openfiler 虚拟机需要的 Xen 配置文件:

# vi /etc/xen/openfiler

name = 'openfiler'
memory = '512'
kernel = '/xenboot/vmlinuz-2.6.21.7-3.20.smp.gcc3.4.x86_64.xen.domU'
ramdisk = '/xenboot/initrd-2.6.21.7-3.20.smp.gcc3.4.x86_64.xen.domU.img'
disk = [ 'phy:/dev/XenGroup/openfiler,xvda1,w' ]
root = "/dev/xvda1 ro"
vif = [ "mac=00:16:3e:38:76:22,bridge=xenbr0" ]
on_reboot = 'restart'
on_crash = 'restart'

启动 Openfiler 虚拟机:

# xm create openfiler

启动成功后就可以通过 https://172.16.39.1:446 来访问和管理 Openfiler 了,默认用户名和密码为 openfiler/password,登录后界面如下:

openfiler

在 Debian 上安装和配置 Xen

SUN 每隔一段时间都会有一些服务器捐给大学、实验室、研究机构等。我们项目组就刚 “骗” 了几台免费的 Sun Fire 服务器,当然也和我们是 SUN(也许现在应该叫 Oracle)的长期客户有关,我们的服务器基本都是 SUN 的。现在只要新机器一进来就先虚拟化,虚拟化后才能上机柜,技术变化太快了,记得几年前我们买机器一上来首先装的是操作系统,现在 hypervisor 代替了操作系统。

首先最小化安装64位的 Debian,下面的安装步骤和配置过程基于 Debian 5.04 版本,CentOS 版本可以参看:在 CentOS 上安装和配置 Xen,Ubuntu 版本可以参看:在 Ubuntu 上安装和配置 Xen,OpenSolaris 版本参看:在 OpenSolaris 上安装和配置 Xen,NetBSD 版本参看:在 NetBSD 上安装和配置 Xen.

安装 Xen

检查一下 source list:

# vi /etc/apt/sources.list

deb http://http.us.debian.org/debian stable main contrib non-free
#deb http://non-us.debian.org/debian-non-US stable/non-US main contrib non-free
deb http://security.debian.org stable/updates main contrib non-free

安装 Xen 及相关工具:

# apt-get install xen-hypervisor-3.2-1-amd64 \
xen-linux-system-2.6.26-2-xen-amd64 xen-utils-3.2-1 \
xenstore-utils xenwatch xen-shell xen-tools

我们需要很多 loop devices 来挂载基于文件的虚拟机,所以需要把 loop device 的数目限制设成最大

# vi /etc/modules

loop max_loop=64

安装完 Xen 后,Debian 上的 Xen 的默认网络配置用的是 network-dummy,和 CentOS 上有点不一样,我们需要修改成 bridge 以便每个虚拟机都像一个独立机器一样运行在网络上:

# vi /etc/xen/xend-config.sxp

#(network-script network-dummy)
(network-script network-bridge)

安装成功后,检查 Xen 内核是否已经装好,并给内核加上 dom0_mem=256M 限制 Xen Dom0 的内存,防止 dom0 把内存耗光:

# vi /boot/grub/menu.lst

...
title           Xen 3.2-1-amd64 / Debian GNU/Linux, kernel 2.6.26-2-xen-amd64
root            (hd0,0)
kernel          /xen-3.2-1-amd64.gz dom0_mem=256M
module          /vmlinuz-2.6.26-2-xen-amd64 root=/dev/mapper/vpsee-root ro console=tty0
module          /initrd.img-2.6.26-2-xen-amd64
...

重启系统后检查一下是否是 Xen 的内核以及 Xen 是否启动:

# reboot

# uname -r
2.6.26-2-xen-amd64

# xm list
Name                                        ID   Mem VCPUs      State   Time(s)
Domain-0                                     0   256     2     r-----      9.3

创建和安装 guest

如果把正在运行的 Xen 内核的操作系统看成 host 的话,那么运行在 host 上面的操作系统就可以看成 guest。先建一个目录用来存放所有的 guest 操作系统的 image,vm01.img,vm02.img 等,1个 guest 对应1个 image。

# mkdir /vm

# xen-create-image --hostname=vm01 --size=10Gb --swap=512Mb --ide \
--ip=172.16.39.121 --netmask=255.255.254.0 --gateway=172.16.38.1 --force \
--dir=/vm --memory=512Mb --arch=i386 \
--kernel=/boot/vmlinuz-2.6.26-2-xen-amd64 \
--debootstrap --dist=etch --mirror=http://ftp2.de.debian.org/debian/ --password

可以根据需要调整 /etc/xen-tools/xen-tools.conf

进入 guest

安装成功后需要增加给对应的虚拟机器增加一个 Xen 配置文件以便 Xen 能启动这个虚拟机:

# vi /etc/xen/vm01

kernel      = '/boot/vmlinuz-2.6.26-2-xen-amd64'
ramdisk     = '/boot/initrd.img-2.6.26-2-xen-amd64'
memory      = '512'
root        = '/dev/xvda2 ro'
disk        = [
                  'file:/vm/domains/vm01/swap.img,xvda1,w',
                  'file:/vm/domains/vm01/disk.img,xvda2,w',
              ]
name        = 'vm01'
vif         = [ 'ip=172.16.39.121,mac=00:16:3E:C0:21:DE' ]
on_poweroff = 'destroy'
on_reboot   = 'restart'
on_crash    = 'restart'

启动刚安装的 Debian 虚拟机后就可以登录了,

# xm create vm01
# xm console vm01

如果要退出 guest 的话,用 Ctrl + ],就会回到 host。

如果想每次启动 host 时自动启动 guest 的话:

# ln -s /etc/xen/vm01 /etc/xen/auto

更懒的办法

如果觉得安装 guest 操作系统太麻烦,可以到 http://stacklet.com/ 下载一个已经装好的镜像文件,调整 Xen guest 的配置文件,然后在 host 下启动 guest 镜像就可以了,这里这里有更详细的介绍。

增加 swap

如何给 guest 系统(domU)增加 swap,这里有介绍。

让 Xen dom0 得到足够 CPU 处理 IO

默认情况下 Xen 使用的是 Credit-Based CPU Scheduler,一种基于权重的 CPU 调度算法。简单的说就是给每个虚拟机的 CPU 一个权重,权重多的得到和使用物理 CPU 的时间就会多,如果虚拟机1的 CPU(VCPU 1.0)权重是256,虚拟机2(VCPU 2.0)的权重是512,那么虚拟机2的 VCPU 2.0 得到物理 CPU 的使用时间就是虚拟机1的2倍。

Xen 给每个虚拟机(包括 dom0 和 domU)分配的默认权重都是 256,也就是说 Xen 上运行的所有 guest 操作系统,dom0 和 众多 domU 都是均分和共享 CPU 的,他们能得到 CPU 的时间和机会都是一样的。这看上去对虚拟机用户(domU)来说很公平,但这种大锅饭的方法对 dom0 来说可不合适,dom0 承担着艰巨的任务,要处理来自其他 domU 的 IO 请求,如果都平均享用 CPU 的话就会造成 dom0 常常因得不到足够的 CPU 时间而不能及时处理自己或来自 domU 的 IO,所以在各虚拟机 IO 负载重的情况下我们需要修改 dom0 的权重,以便它能及时处理 IO. IO 这个问题很重要,一旦 IO 处理不及时,所有虚拟机的 IO 都会等待,将会影响所有虚拟机用户。这也是为什么我们不提供 64MB VPS 的一个原因,64MB VPS 用户会明显感到内存不足,系统会大量频繁 swapping,大量 disk IO 请求会影响服务器整体性能和所有其他用户。可以在这篇:64MB 的 VPS 能支持多少访问量?看到 128MB 的 swap 就用了 75MB.

查看当前 dom0 的 CPU 权重:

# xm sched-credit -d Domain-0
{'cap': 0, 'weight': 256}

修改 dom0 的 CPU 权重:

# xm sched-credit -d Domain-0 -w 512

# xm sched-credit -d Domain-0
{'cap': 0, 'weight': 512}

随机生成 Xen 虚拟机的 MAC 地址

如果不在创建 Xen 虚拟机(domU)的时候指定 MAC 地址的话,Xen 就会随机生成一个 MAC 地址给虚拟机,这样管理员就没办法知道虚拟机的 MAC 地址了,不利于以后带宽的统计和虚拟机的管理,所以最好就在 Xen 虚拟机配置文件中直接指明虚拟机的 MAC 地址,比如:

# vi /etc/xen/vpsuser1
vif = [ "mac=00:16:3e:0c:11:53,ip=172.16.16.200,bridge=xenbr0" ]

IEEE OUI 为 Xen domU 保留了一段 MAC 地址,前3段是 “00-16-3e”,后3段是随机的,其中第1个随机段的第1个 bit 是0(IEEE OUI 给 VMware 保留的前3段地址是 “00-0c-29”,后3段随机)。我们在为用户分配 MAC 地址时候不想有规律的分配(虽然也不会有什么安全问题),所以 VPSee 写了一个简单的 Python 脚本用来随机生成符合 Xen 虚拟机标准的 MAC 地址:

#!/usr/bin/python 
# generates a MAC address for Xen domU
# http://www.vpsee.com
#

import random

mac = [ 0x00, 0x16, 0x3e, random.randint(0x00, 0x7f), 
random.randint(0x00, 0xff), random.randint(0x00, 0xff) ]
s = []
for item in mac:
        s.append(str("%02x" % item))
print ':'.join(s)