Debian 上 Xen 和 X 之间的 bug

上周五 VPSee 在一台新 PC 上安装 Debian 的时候遇到一堆问题,先是安装程序没有找到网卡,没有网卡就需要自己编译驱动,但是编译又需要一些编译包、头文件和库,没有网络就没法 apt-get(因为只下载了 cd1),所以不得不从另外一台机器上下载网卡驱动 e1000e-1.2.10.tar.gz(内核树里居然也没有发现这款网卡,需要从 Intel 官网下载)以及编译驱动所必须的软件包和依赖包。最后 dpkg -i 软件包到 Debian、编译驱动、modprobe 驱动到内核,终于找到网卡。好不容易配好了网络,开始装 X,配置 X Window 的时候居然没有找到鼠标,一查原因原来是 gpm 鼠标服务由于某种原因没起来。最后把 X Window 和窗口管理器装上又发现字体和渲染都很难看,然后又下载其他的字体更改 .fonts.conf. 好不容易可以用桌面了,却发现在 Debian 上安装完 Xen 后进入 Xen(2.6.26-1xen-amd64)内核启动 X Window 就报错:

$ uname -r
2.6.26-1-xen-amd64

$ tail /var/log/Xorg.0.log 
(==) intel(0): RGB weight 888
(==) intel(0): Default visual is TrueColor
(II) intel(0): Integrated Graphics Chipset: Intel(R) G33
(--) intel(0): Chipset: "G33"
(--) intel(0): Linear framebuffer at 0xC0000000
(--) intel(0): IO registers at addr 0xD0300000

Fatal server error:
xf86MapVidMem: Could not mmap framebuffer (0xd0300000,0x80000) (Invalid argument)

VPSee 发现只要用 Xen 内核启动就无法进入 X,但是用原来的内核启动就可以。Debian 用户组有人2008年就报告了这个 bug,原因是 Debian 自带的这个 Xen 内核 2.6.26-1-xen-amd64 在启动 X 调用 mmap () 的时候,CPU 和显卡之间作内存映射(MMIO)出错,导致 X Window 不能启动。这个 bug 居然到现在都没有解决,可能大家都用 Debian 做 Xen 服务器,很少拿 Debian 桌面和 Xen 一起用吧。目前最简单的解决办法是限制 dom0 的内存(小于 2GB 就可以):

# vi /boot/grub/menu.lst
...
kernel          /boot/xen-3.2-1-amd64.gz dom0_mem=1024mb
...

这个 bug 只存在使用共享显卡的机器上,如果使用独立显卡就不会有这个问题。

在 Debian 上源码编译和安装 Nginx+PHP+FastCGI+MySQL

前天有一位新客户购买我们的 VPS 后多次在上面源码编译和安装 Nginx+PHP+FastCGI+MySQL 不成功,遇到一些问题,总的来说分为两类,一个是包依赖问题,一个是 MySQL 目录的权限设置问题。昨天这位客户给我们发来一个论坛链接很细致的描述了他的安装过程和遇到的问题,可惜后面回帖的人都没说到重点,还有一位回帖人居然是我们的客户,呵呵,世界好小。VPSee 决定花点时间写个教程,可能对其他的 Linux/VPS 用户也有帮助。我们的 VPS 和那些使用 SolusVM 控制面板和模版的 VPS 服务商不同,我们自己制作 VPS 模版,采用最小化安装,不添加任何乱七八糟的东西,保持最简和干净,所以 VPS 上只装有必备的软件包和库,在编译 Nginx+PHP+FastCGI+MySQL 之前必须先安装一些编译时需要的软件包和库。

记得以前有位客户问过为什么我们的 VPS 上连基本的 gcc 工具都没有?为什么我们采用最小化安装?为什么我们没有提供那些都安装好的模版?有3个原因,1、不需要 gcc Linux 也可以运行,所以 gcc 不是必须的,这满足我们最小化的要求;2、安全,如果有人得到 Linux 普通用户帐号可以下载、通过 gcc 编译和运行一些后门代码以得到 root 权限或者干坏事,所以不是必要的话不推荐安装 gcc 等编译工具,同样的道理也适用我们对其他工具的要求;3、定制,每个人的要求是不同的,有的人喜欢 nginx,有的人喜欢 apache,所以我们采用最小化安装,把选择留给客户。我们认为最小化可以带来简单、安全和灵活。

下面的操作步骤在我们的 256MB Debian 5.0 VPS 上测试通过,Nginx/PHP/MySQL 都采用当前最新稳定源代码版本。

安装必备软件包

# aptitude install libtidy-dev curl libcurl4-openssl-dev libcurl3 \
libcurl3-gnutls zlib1g zlib1g-dev libxslt1-dev libzip-dev libzip1 \
libxml2 libsnmp-base libsnmp15 libxml2-dev libsnmp-dev libjpeg62 \
libjpeg62-dev libpng12-0 libpng12-dev zlib1g zlib1g-dev libfreetype6 \
libfreetype6-dev libbz2-dev libxpm-dev libmcrypt-dev libmcrypt4 \
sqlite3 bzip2 build-essential libreadline5-dev libedit-dev autoconf

编译和安装 MySQL

下载和编译 MySQL,但是先不要安装:

# wget http://mysql.mirror.rafal.ca/Downloads/MySQL-5.1/mysql-5.1.50.tar.gz
# tar zxvf mysql-5.1.50.tar.gz
# cd mysql-5.1.50

# ./configure \
 --prefix="/usr/local/mysql-5.1.50" \
 --enable-thread-safe-client \
 --with-extra-charsets=all
# make

需要改几个权限问题才能安装 MySQL,否则会出现 Access denied for user ‘root’@’localhost’ (using password: NO) 经典问题:

# groupadd mysql 
# useradd -g mysql mysql

# cp support-files/my-small.cnf /etc/my.cnf
# vi /etc/my.conf
...
[mysqld]
user = mysql 
...

# chown -R mysql:mysql /usr/local/mysql-5.1.50/
# chmod 777 /tmp

安装和启动 MySQl,修改 root 密码,登录 MySQL:

# cd mysql-5.1.50
# make install

# /usr/local/mysql-5.1.50/bin/mysql_install_db --user=mysql
# /usr/local/mysql-5.1.50/bin/mysqld_safe &
# /usr/local/mysql-5.1.50/bin/mysqladmin -u root password 'new-password'
# /usr/local/mysql-5.1.50/bin/mysql -u root -p

编译和安装 PHP

先下载 PHP 软件包,然后配置、编译,这里采用 php 5.2 分支的最新稳定代码:

# wget http://www.php.net/get/php-5.2.13.tar.bz2/from/us.php.net/mirror
# tar jxvf php-5.2.13.tar.bz2
# cd php-5.2.13

# ./configure \
 --prefix="/usr/local/php-5.2.13" \
 --with-mysql="/usr/local/mysql-5.1.50" \
 --with-gd \
 --with-ttf \
 --with-openssl \
 --enable-mbstring \
 --enable-fastcgi
# make && make install

编译和安装 Nginx

下载、配置和编译安装 nginx,注意编译 nginx 需要额外安装几个软件包:

# wget http://nginx.org/download/nginx-0.7.67.tar.gz
# tar zxvf nginx-0.7.67.tar.gz

# aptitude install libgcrypt11-dev libpcre3 libpcre3-dev libssl-dev

# cd nginx-0.7.67
# ./configure  --prefix="/usr/local/nginx-0.7.67"  --with-http_ssl_module
# make && make install

编译和安装 FastCGI

Nginx 需要 FastCGI 的支持才能运行 PHP 脚本,从 lighttpd 下载、编译和安装 spawn-fcgi:

# wget http://www.lighttpd.net/download/spawn-fcgi-1.6.2.tar.bz2
# tar jxvf spawn-fcgi-1.6.2.tar.bz2

# cd spawn-fcgi-1.6.2
# ./configure --prefix="/usr/local/php-5.2.13"
# make && make install

启动 FastCGI:

# /usr/local/php-5.2.13/bin/spawn-fcgi -a 127.0.0.1 -p 9000 \
-u www-data -g www-data -f /usr/local/php-5.2.13/bin/php-cgi \
-P /var/run/fastcgi-php.pid

编辑 Nginx 的配置文件,让 php 脚本被发送到 FastCGI 服务器由 FastCGI 处理,然后启动 nginx:

# vi /usr/local/nginx-0.7.67/conf/nginx.conf
...
        # fix nginx/php/fastcgi important security issue
        # http://cnedelcu.blogspot.com/2010/05/nginx-php-via-fastcgi-important.html
        location ~ \..*/.*\.php$ {
            return 403;
        }

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        location ~ \.php$ {
            #root           html;
            root           /usr/local/nginx-0.7.67/html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /usr/local/nginx-0.7.67/html$fastcgi_script_name;
            include        fastcgi_params;
        }
...

# /usr/local/nginx-0.7.67/sbin/nginx -c /usr/local/nginx-0.7.67/conf/nginx.conf

安装 Nginx+FastCGI+PHP 完后测试一下是否 PHP 页面能否被正确解析,在 html 下创建一个含有 phpinfo(); 函数的文件,最后打开浏览器检查下面的 index.php 能否被正确执行。:

# vi /usr/local/nginx-0.7.67/html/index.php
phpinfo();

编译源代码需要消耗大量内存,我们只建议 256MB 或以上 VPS 用户使用源码方式安装。

在 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

在 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,这里有介绍。

64MB VPS 上优化 Debian 5

debian

前几天看到 VPSLink 在打折就跑去注册了一个 64M VPS,(具体请看:VPS 主机试用:VPSLink),想看看 64MB 的 VPS 能不能跑一个小规模访问量的 WordPress 博客,这里的小规模是指每日500 PV 以下。然后分别试着跑了一下 Debian 和 CentOS,默认安装后跑Debian没有问题,但是运行 CentOS 时明显感到系统很慢。CentOS/RHEL 官方推荐的最小配置(不带图形界面)虽然是 64MB 内存,但是考虑到同时要跑 MySQL,PHP,Wordpress 等程序 64MB CentOS就有点吃力了。还有一个考虑就是运行一次 yum 需要比 apt-get 多得多的内存资源。所以按照我的 VPS 配置,64MB内存,128MB 交换,2.5GB 的硬盘,就只能选 Debian 了。

Debian 是一个古老,严谨,自由而且流行的 Linux 发行版,有 n 多的软件包可以用,有很好的稳定性和安全性,是各大 Linux hosting 服务商的主流系统之一,几乎所有 Linux VPS 都支持 Debian 版本。安装 Debian 的系统最低内存要求是 64MB,但是官方文档也说了真正的最低内存配置要比 64MB 低一些,根据不同的硬件体系安装在只有 48MB 的 i386 上也是可能的。

查看 VPS 配置

1、查看以下 VPS 的硬件信息,做到心中有数

# free
# cat /proc/cpuinfo


继续阅读 »