在 CentOS 6.2 上安装 Cobbler

每次給自己的电脑重装系统都是一件很无聊的事情,如果需要重装上百台虚拟机和服务器不但很无聊而且很耗时,面对现在云时代大量服务器和虚拟机的出现,运维必须要自动化。现在有很多开源工具可以帮助我们实现自动化安装系统,比如 FAI, Cobbler, Spacewalk, Ubuntu Orchestra 等,我们打算把 Cobbler 安装在某台虚拟机上,为我们新购的16台刀片服务器自动安装系统。

Cobbler 是一个系统启动服务(boot server),可以通过网络启动(PXE)的方式用来快速安装、重装物理服务器和虚拟机,支持安装不同的 Linux 发行版和 Windows. Cobbler 是个轻量级 Python 程序,总共大概1.5万行代码,还可以用来管理 DHCP, DNS, yum 源等。Cobbler 使用命令行方式管理,也提供了基于 Web 的界面管理工具(cobbler-web),不过命令行方式已经很方便,实在没有必要为了不实用的 Web 界面再添加一个 Web 服务器。

修改 DHCP 服务器配置

使用 Cobbler 最好配合现有局域网上的 DHCP 服务器一起使用,这样不会因为 Cobbler 干扰现有局域网。我们不打算用 Cobbler 来管理整个网络的 DHCP,因为我们已经有了 DHCP 服务器,所以只要在现有的 DHCP 服务器上做以下配置即可,下面记得调整 192.168.2.22 这个 IP 地址指向 Cobbler 服务器:

# for Cobbler setup
host cobbler {
    option host-name "cobbler";
    ddns-hostname "cobbler";
    hardware ethernet 00:0c:29:2d:2c:39; #MAC address of cobbler server
            fixed-address 192.168.2.22; #IP of Cobbler server
            allow booting;
    allow bootp;
    class "PXE" {
        match if substring(option vendor-class-identifier, 0, 9) = "PXEClient";
        next-server 192.168.2.22; #IP of Cobbler server
            filename "pxelinux.0";
    }
}

安装和配置 Cobbler

Cobbler 不在 CentOS 6.2 的基本源中,需要导入 EPEL 源:

# rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-5.noarch.rpm
Retrieving http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-5.noarch.rpm
warning: /var/tmp/rpm-tmp.lo2Hd0: Header V3 RSA/SHA256 Signature, key ID 0608b895: NOKEY
Preparing...                ########################################### [100%]
   1:epel-release           ########################################### [100%]

# yum update
# yum upgrade

安装 cobbler:

# yum install cobbler

修改配置,主要修改 cobbler 服务器所在的 IP 地址:

# vi /etc/cobbler/settings
...
next_server: 192.168.2.22 #IP of Cobbler server
server: 192.168.2.22 #IP of Cobbler server
...

启用 httpd, xinetd 和 cobbler 服务并确认已经加到系统自动启动服务中:

# /etc/init.d/httpd start
# /etc/init.d/xinetd start
# /etc/init.d/cobblerd start

# chkconfig httpd on
# chkconfig xinetd on
# chkconfig cobblerd on

修改 rsync 和 tftp 这两个服务的 xinetd 配置:

# vi /etc/xinetd.d/rsync
service rsync
{
        disable = no
...
}

# vi /etc/xinetd.d/tftp
service tftp
{
        ...
        disable = no
        ...
}

关闭防火墙和 SELinux 后重启系统:

# /etc/init.d/iptables stop
# chkconfig iptables off

# vi /etc/sysconfig/selinux
...
SELINUX=disabled
...

# reboot

检查和修改 Cobbler 配置

系统重启后用 cobbler check 检查发现3个配置信息问题,第一个是如果要部署 debian/ubuntu 系统需要 debmirror 软件包;第二个是需要修改 cobbler 的默认密码;第三个是可选,想使用电源管理功能的话需要安装 cman 或 fence-agents:

# cobbler get-loaders

# cobbler check
The following are potential configuration items that you may want to fix:

1 : debmirror package is not installed, it will be required to manage debian deployments and repositories
2 : The default password used by the sample templates for newly installed machines (default_password_crypted in /etc/cobbler/settings) is still set to 'cobbler' and should be changed, try: "openssl passwd -1 -salt 'random-phrase-here' 'your-password-here'" to generate new one
3 : fencing tools were not found, and are required to use the (optional) power management features. install cman or fence-agents to use them

Restart cobblerd and then run 'cobbler sync' to apply changes.

现在来修复上面三个问题,我们希望能让这台 cobbler 服务器能同时部署 CentOS/Fedora 和 Debian/Ubuntu 系统,所以需要安装 debmirror,安装 debmirror-20090807-1.el5.noarch.rpm 前需要先安装依赖包:

# yum install wget
# yum install ed patch perl perl-Compress-Zlib perl-Cwd perl-Digest-MD5 \
perl-Digest-SHA1 perl-LockFile-Simple perl-libwww-perl

# wget ftp://fr2.rpmfind.net/linux/epel/5/ppc/debmirror-20090807-1.el5.noarch.rpm

# rpm -ivh debmirror-20090807-1.el5.noarch.rpm 

修改 /etc/debmirror.conf 配置文件,注释掉 @dists 和 @arches 两行:

# vi /etc/debmirror.conf
...
#@dists="sid";
@sections="main,main/debian-installer,contrib,non-free";
#@arches="i386";
...

用 openssl 生成一串密码后加入到 cobbler 的配置文件(/etc/cobbler/settings)里,替换 default_password_crypted 字段:

# openssl passwd -1 -salt 'www.vpsee.com' 'vpsee'
$1$www.vpsee$T5FgCHY2P0NDr6JmbN0Bl0

# vi /etc/cobbler/settings
default_password_crypted: "$1$www.vpsee$T5FgCHY2P0NDr6JmbN0Bl0"

安装 cman:

# yum install cman

修复完成,再用 cobbler check 检查一下,确认没问题后用 cobbler sync 做同步操作:

# cobbler check
No configuration problems found.  All systems go.

# cobbler sync

导入 ISO

挂载 CentOS-6.2-x86_64-bin-DVD1.iso 安装光盘然后导入到 cobbler(注意这个 iso 文件有 4GB 多,导入可能需要一段时间),导入成功后 cobbler list 查看一下:

# mount -o loop -t iso9660 CentOS-6.2-x86_64-bin-DVD1.iso /mnt

# cobbler import --path=/mnt --name=CentOS-6.2-x86_64-bin-DVD1 –arch=x86_64

# cobbler sync

# cobbler list
distros:
   CentOS-6.2-bin-DVD1-x86_64

profiles:
   CentOS-6.2-bin-DVD1-x86_64

systems:

repos:

images:

测试

最后创建一台虚拟机测试一下,把虚拟机设置成网络 PXE 启动(和 cobbler 在同一个网络),启动后就可以看到 Cobbler 引导界面,看到界面后选择 CentOS-6.2-bin-DVD1-x86_64 条目就可以顺利开始无人工干预安装系统,Cobbler 引导界面如下:

boot os from cobbler net pxe

安装完系统后默认的密码是啥呢?根据 sample.ks 的配置提示,这个密码 $default_password_crypted 就是我们上面用 openssl passwd -1 -salt ‘www.vpsee.com’ ‘vpsee’ 生成的密码,所以这里的 root 密码是 vpsee:

# cat /var/lib/cobbler/kickstarts/sample.ks
...
#Root password
rootpw --iscrypted $default_password_crypted

在 CentOS 6.2 上安装 Puppet 配置管理工具

puppet logo

云计算时代系统管理员会经常陷入一系列的重复任务中,创建虚拟机,安装或重装系统,升级软件包,管理配置文件,添加、管理和配置系统服务等。这些任务低效而且无聊,我们需要把他们自动化,于是就出现了系统管理员自己写的脚本,用定制脚本实现自动化,但是自己写的脚本要保证能顺利运行在不同的平台上不是一件轻松的工作,每次操作系统更新都需要重新测试定制脚本,耗费大量时间和精力,灵活性和功能也很难保证。而且脚本语言虽然简单,但是自己写的脚本不一定别的管理员就能马上看懂,有时候自己看别人写的脚本或代码不是一件愉快的事情。所以出现了类似 Puppet, Chef 这样的自动化配置管理工具。为啥 Linode 只有19人就能应付上千服务器上万用户,这就是自动化带来的好处。

Puppet 是一个客户端/服务器(C/S)架构的配置管理工具,在中央服务器上安装 puppet-server 服务器(puppet master),在需要被管理的目标服务器上安装 puppet 客户端软件(puppet client)。当客户端连接上服务器后,定义在服务器上的配置文件会被编译,然后在客户端上运行。客户端每隔半小时主动会和服务器通信一次,确认配置信息的更新情况,如果有新的配置信息(或者配置有变化),配置文件将会被重新编译并分发到客户端执行。当然,也可以在服务器上主动触发更新指令来强制各客户端进行配置更新。

以下安装采用两台服务器,一台是 master.vpsee.com 用来安装 puppet-server 服务;一台是 client.vpsee.com 用来安装 puppet 客户端。

Puppet 要求所有机器有完整的域名(FQDN),如果没有 DNS 服务器提供域名的话,可以在两台机器上设置主机名(注意要先设置主机名再安装 Puppet,因为安装 Puppet 时会把主机名写入证书,客户端和服务端通信需要这个证书):

# vi /etc/hosts
192.168.2.10    master master.vpsee.com
192.168.2.11    client client.vpsee.com

Puppet 要求所有机器上的时钟保持同步,所以需要安装和启用 ntp 服务(如果采用 CentOS-6.2-x86_64-minimal.iso 最小化安装,需要额外安装这个软件包)。

# yum install ntp

# chkconfig ntpd on

# ntpdate pool.ntp.org
29 Feb 15:22:47 ntpdate[15867]: step time server 196.25.1.1 offset 98.750417 sec

# service ntpd start
Starting ntpd:                                             [  OK  ]

安装 puppet 服务

Puppet 需要 Ruby 的支持,如果要查看命令行帮助的话需要额外 ruby-rdoc 这个软件包:

# yum install ruby ruby-libs ruby-rdoc

Puppet 不在 CentOS 的基本源中,需要加入 PuppetLabs 提供的官方源:

# yum -y install wget

# wget http://yum.puppetlabs.com/el/6/products/x86_64/puppetlabs-release-6-1.noarch.rpm

# yum install puppetlabs-release-6-1.noarch.rpm

# yum update

在 master 上安装和启用 puppet 服务:

# yum install puppet-server

# chkconfig puppet on

# service puppetmaster start
Starting puppetmaster:                                     [  OK  ]

关闭 iptables:

# /etc/init.d/iptables stop
iptables: Flushing firewall rules:                         [  OK  ]
iptables: Setting chains to policy ACCEPT: filter          [  OK  ]
iptables: Unloading modules:                               [  OK  ]

安装 puppet 客户端

在 client 上安装 puppet 客户端:

# yum install puppet

Puppet 客户端使用 HTTPS 和服务端(master)通信,为了和服务器端通信必须有合法的 SSL 认证,第一次运行 puppet 客户端的时候会生成一个 SSL 证书并指定发给 Puppet 服务端。

# puppet agent --no-daemonize --onetime --verbose --debug --server=master.vpsee.com

Puppet 服务端接受到客户端的证书后必须签字(sign)才能允许客户端接入,sign 后用 puppet cert list –all 查看会发现 client.vpsee.com 前面多了一个 + 后,表示 “加入” 成功:

# puppet cert list --all
  client.vpsee.com (65:3C:20:82:AE:F6:23:A8:0A:0B:09:EF:05:64:1D:BB)
+ master.vpsee.com   (AF:A0:32:78:D4:EB:D3:EE:02:1C:62:1C:83:3C:46:EC) (alt names: DNS:master, DNS:master.vpsee.com)

# puppet cert --sign client.vpsee.com
notice: Signed certificate request for client.vpsee.com
notice: Removing file Puppet::SSL::CertificateRequest client.vpsee.com at '/var/lib/puppet/ssl/ca/requests/client.vpsee.com.pem'

# puppet cert list --all
+ client.vpsee.com (65:3C:20:82:AE:F6:23:A8:0A:0B:09:EF:05:64:1D:BB)
+ master.vpsee.com   (AF:A0:32:78:D4:EB:D3:EE:02:1C:62:1C:83:3C:46:EC) (alt names: DNS:master, DNS:master.vpsee.com)

这样,客户端和服务端就配置好了,双方可以通信了。

Hello, world

现在可以在服务端写个小例子来测试一下。这个例子作用很简单,用来在客户端的 /tmp 目录下新建一个 helloworld.txt 文件,内容为 hello, world. 在服务端编写代码:

# vi /etc/puppet/manifests/site.pp
node default {
        file {
                "/tmp/helloworld.txt": content => "hello, world";
        }
}

在客户端上执行 puppet,运行成功后会在 /tmp 看到新生成的 helloworld.txt:

$ puppet agent --test --server=master.vpsee.com
warning: peer certificate won't be verified in this SSL session
info: Caching certificate for client.vpsee.com
info: Caching certificate_revocation_list for ca
info: Caching catalog for client.vpsee.com
info: Applying configuration version '1330668451'
notice: /Stage[main]//Node[default]/File[/tmp/helloworld.txt]/ensure: defined content as '{md5}e4d7f1b4ed2e42d15898f4b27b019da4'
info: Creating state file /home/vpsee/.puppet/var/state/state.yaml
notice: Finished catalog run in 0.03 seconds

$ cat /tmp/helloworld.txt 
hello, world

如果想偷懒,可以直接使用 Example42 的开源 Puppet 模块

为 OpenStack Nova 制作 CentOS 镜像

做 CentOS 镜像的过程和去年写的那篇为 OpenStack Nova 制作 Ubuntu 镜像的步骤差不多,不过这半年 OpenStack 发展神速,比以前要稳定多了,有些步骤可以省了,而且有些命令工具、参数、功能都有改动,比如以前的 uec-publish-image 改成了现在的 cloud-publish-image,功能也有变化。下面的制作镜像步骤在 Ubuntu 11.10 + OpenStack Diablo Release 上完成。

安装 CentOS 镜像

下载要安装的 CentOS 版本,这里选用最新的 CentOS 6.2:

$ wget http://mirrors.kernel.org/centos/6.2/isos/x86_64/CentOS-6.2-x86_64-minimal.iso

创建一个 10GB 大小的 “硬盘”(raw 格式),最好用一个较小的 “硬盘”,体积太大提交到云里会花很长时间,而且每次运行实例也会花很长时间:

$ kvm-img create -f raw centos.img 10G
Formatting 'centos.img', fmt=raw size=10737418240

使用刚才下载的 CentOS “安装盘” 和刚创建的 “硬盘” 引导启动系统,用 -vnc 参数打开 vnc 访问,这样可以从其他机器登录到这个界面安装系统:

$ sudo kvm -m 512 -cdrom CentOS-6.2-x86_64-minimal.iso \
-drive file=centos.img -boot d -net nic -net tap -nographic -vnc :0

用 vncviewer 登录后按照屏幕提示完成 CentOS 安装。需要注意的是在分区阶段把 10GB 硬盘全部划分成一个 ext4 root 分区,不要创建多个分区也不要创建 swap 区:

$ vncviewer 172.16.39.111:5900

安装完后会自动重启,如果没有重启的话按照下面的命令启动刚刚安装好的虚拟机镜像 centos.img,如果出现 failed to find romfile “pxe-rtf8139.bin” 的错误提示可以通过安装 kvm-pxe 解决:

$ sudo kvm -m 512 -drive file=centos.img -boot c -net nic -net tap \
-nographic -vnc :0
kvm: pci_add_option_rom: failed to find romfile "pxe-rtl8139.bin"

$ sudo apt-get install kvm-pxe

再次用 vnc 登录虚拟机镜像,安装一些必要工具(因为这个镜像将会是模板,所以最好保持最简最小化):

$ vncviewer 172.16.39.111:5900

# yum update
# yum upgrade
# yum install openssh-server
# chkconfig sshd on

修改分区加载表(/etc/fstab),注释或删除以前的,加上 LABEL=cec-rootfs 一行:

# vi /etc/fstab
#UUID=47a90bea-2d88-4c82-a335-09c1533b1538 / ext4 defaults 1 1
LABEL=cec-rootfs                           / ext4 defaults 0 0

在网络接口配置里面注释或删除这行 #HWADDR= 一行,启用 DHCP:

# vi /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE="eth0"
#HWADDR="00:11:22:12:34:56"
#NM_CONTROLLED="yes"
BOOTPROTO=dhcp
ONBOOT="yes"

注射 ssh key 以便外界可以用 ssh -i mykey.priv root@host 的形式无密码登录到虚拟机实例,在 /etc/rc.local 文件中加入下面这些:

# vi /etc/rc.local
...
mkdir -p /root/.ssh
echo >> /root/.ssh/authorized_keys
curl -m 10 -s http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key
| grep 'ssh-rsa' >> /root/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
echo "AUTHORIZED_KEYS:"
echo "--------------------"
cat /root/.ssh/authorized_keys
echo "--------------------"

别忘了还需要修改 sshd 的配置实现无密码登录:

# vi /etc/ssh/sshd_config
...
RSAAuthentication yes
PubkeyAuthentication yes
PermitRootLogin without-password
ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM no

需要关闭 SELINUX,否则即使上面 ssh 设定允许 root 无密码登录也无效:

# vi /etc/selinux/config
SELINUX=disabled
SELINUXTYPE=targeted

70-persistent-net.rules 会自动添加其他的网络接口,需要删除这个文件避免自动添加除了 eth0 以外的接口,关闭虚拟机准备发布镜像:

# rm -rf /etc/udev/rules.d/70-persistent-net.rules

# shutdown -h now

发布 CentOS 镜像

CentOS 镜像已经做好了,现在可以发布到云里了:

$ cloud-publish-image amd64 centos.img mybucket
ami-00000007    mybucket/centos.img.manifest.xml

等待一段时间后出现 ami-00000008 mybucket/centos.img.manifest.xml 表示我们刚制作的 CentOS 镜像已经正式发布到云里,以后就可以以这个镜像为模板来快速生成虚拟机实例(instance)。可以通过 euca-describe-images 来查看:

$ euca-describe-images
IMAGE	ami-00000008	images/centos.img.manifest.xml		available	private		x86_64	machine	 	 	instance-store

第一个 CentOS 虚拟机实例

有了 CentOS 镜像(模板)以后我们就可以以这个 “镜像” 为模板来为云计算用户创建 n 个 CentOS 虚拟机(操作系统)实例,不过在运行实例之前需要 key:

$ euca-add-keypair mykey > mykey.priv
$ chmod 600 mykey.priv 

$ euca-describe-keypairs
KEYPAIR	mykey	76:7d:93:88:a0:e5:3e:5d:4b:62:cd:85:c5:23:7a:05

$ euca-run-instances -k mykey -t m1.small ami-00000008
RESERVATION	r-hzwwif81	vpseecloud	default
INSTANCE	i-0000002a	ami-00000008	pending	vpsee (vpseecloud, None)	0		m1.small	2012-02-01T14:26:51Z	unknown zone	aki-00000001	ami-00000000

上面使用 euca-run-instances 创建一个实例后可以用 nova-manage 命令看到:

$ euca-describe-instances 
RESERVATION	r-z973l7mm	vpseecloud	default
INSTANCE	i-0000002a	ami-00000008	172.16.39.200	172.16.39.200	running	vpsee (vpseecloud, cloud00)	0		m1.small	2012-02-01T13:56:02Z	nova	ami-00000000	ami-00000000

还记得在 Ubuntu 上安装和配置 OpenStack Nova 的创建网络部分吗?看看现在云里面 IP 的分配情况:

$ sudo nova-manage network list
id   	IPv4              	IPv6           	start address  	DNS1           	DNS2           	VlanID         	project        	uuid           
1    	172.16.38.0/23    	None           	172.16.38.2    	8.8.4.4        	None           	None           	None           	None

刚才用 euca-run-instances 启动的一个 ubuntu 虚拟机实例的 IP 就是从 172.16.38.2 开始的,目前分配的 IP 是 172.16.39.200(从 euca-describe-instances 可以看出来),所以 ssh 登录这个 IP 就登上了我们的 CentOS 云虚拟机:

$ ssh -i mykey.priv root@172.16.39.200
[root@server-25 ~]# 

想制作 Windows 虚拟机镜像的话可以看这篇:为 OpenStack Nova 制作 Windows 镜像

服务器出现 server kernel: ip_conntrack: table full, dropping packet. 问题

昨天上午挂在 VPSee 桌子旁边墙壁上的老古董 IBM TP600E 终于发挥作用,连续报警,监视显示某台服务器丢包非常严重,甚至大多时候不能访问,终端登录系统后检查日志发现 ip_conntrack: table full, dropping packet. 错误:

# vi /var/log/messages
...
Nov  8 08:54:58 server kernel: ip_conntrack: table full, dropping packet.
Nov  8 08:55:03 server kernel: printk: 49 messages suppressed.
Nov  8 08:55:03 server kernel: ip_conntrack: table full, dropping packet.
Nov  8 08:55:08 server kernel: printk: 49 messages suppressed.
...

查看当前 ip_conntrack 记录,已经有 36271,超过了系统设置的 16640 (ip_conntrack_max 默认设置为系统内存(MB 为单位)的 16倍):

$ head /proc/slabinfo 
slabinfo - version: 2.1
# name                 : tunables    : slabdata   
ip_conntrack_expect      0      0    192   20    1 : tunables  120   60    8 : slabdata      0      0      0
ip_conntrack        36271  36216    384   10    1 : tunables   54   27    8 : slabdata   1612   1612    108

# cat /proc/sys/net/ipv4/ip_conntrack_max
16640

kernel 用 ip_conntrack 模块来记录 iptables 网络包的状态,并保存到 table 里(这个 table 在内存里),如果网络状况繁忙,比如高连接,高并发连接等会导致逐步占用这个 table 可用空间,一般这个 table 很大不容易占满并且可以自己清理,table 的记录会一直呆在 table 里占用空间直到源 IP 发一个 RST 包,但是如果出现被攻击、错误的网络配置、有问题的路由/路由器、有问题的网卡等情况的时候,就会导致源 IP 发的这个 RST 包收不到,这样就积累在 table 里,越积累越多直到占满,满了以后 iptables 就会丢包,出现外部无法连接服务器的情况。

知道问题就好办了,要么增加 table 容量以便能记录更多的连接信息(会消耗一点内存),要么就卸载 ip_conntrack 模块。

查看当前 ip_conntrack_max 设置,然后增加两倍到 131072:

# cat /proc/sys/net/ipv4/ip_conntrack_max
16640

# echo 131072 > /proc/sys/net/ipv4/ip_conntrack_max
或者
# sysctl -w  net.ipv4.netfilter.ip_conntrack_max=131072

还有一个参数 ip_conntrack_tcp_timeout_established 需要注意,默认情况下 timeout 是5天(432000秒),需要的话可以减半:

# cat /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_established 
432000

# sysctl -w net.ipv4.netfilter.ip_conntrack_tcp_timeout_established=216000
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 216000

综合一下,最好把这些内核参数加到 sysctl.conf 文件以便系统启动后自动读取中:

# vi /etc/sysctl.conf
...
net.ipv4.netfilter.ip_conntrack_max = 131072
net.nf_conntrack_max = 131072
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 216000

还有一种办法就是直接卸载 ip_conntrack 模块,这个办法最简单,到在 /etc/sysconfig/iptables-config 文件里删除或者注释掉 ip_conntrack_netbios_ns 后重启系统:

# vi /etc/sysconfig/iptables-config
#IPTABLES_MODULES="ip_conntrack_netbios_ns"

# shutdown -r now

在 CentOS 上安装和配置 OpenStack Nova

因为 Python 的版本问题,在 CentOS 5.6 上安装 OpenStack 不是件容易的事情,因为 OpenStack 是 Python 2.6 写的,CentOS 5.6 上默认的是 Python 2.4 的环境,一些关键工具(比如 yum 等)和依赖关系都需要 2.4,不容易直接升级到 2.6,所以要在 CentOS 上安装 OpenStack 的话简单的办法是直接用 CentOS 6.0(默认是 Python 2.6). OpenStack 的基本介绍以及如何在 Ubuntu 上安装 OpenStack Nova 可以看:在 Ubuntu 上安装和配置 OpenStack Nova. 对云计算平台感兴趣的朋友可以看看另一个开源的云计算系统:在 CentOS 上安装和配置 OpenNebula.

安装和配置基本系统

在安装完基本的 CentOS 6.0 系统后(最小化安装)升级和更新整个系统,然后关闭 SELINUX 后重启,为了简单方便最好也关闭 iptables:

# yum update
# yum upgrade

# vi /etc/sysconfig/selinux
SELINUX=disabled

# chkconfig iptables off
# service iptables stop

# shutdown -r now

安装 OpenStack Nova

下载和安装 OpenStack 源:

# wget http://yum.griddynamics.net/yum/diablo-3/openstack/openstack-repo-2011.3-0.3.noarch.rpm
# rpm -ivh openstack-repo-2011.3-0.3.noarch.rpm

OpenStack Nova 需要在控制结点(Cloud Controller)和计算结点(Cloud Compute)上都安装和启用 libvirtd:

# yum install libvirt
# chkconfig libvirtd on
# service libvirtd start

如果服务器用来做 Cloud Controller 结点需要安装(OpenStack Nova 云里至少要有一台服务器作为控制结点):

# yum install euca2ools openstack-nova-node-full unzip

如果服务器只是做 Cloud Compute 结点则需要在每个计算结点上都安装(理论上 OpenStack Nova 云里可以有无数个计算结点):

# yum install openstack-nova-node-compute

配置 MySQL 数据库

OpenStack Nova 需要数据库的支持,这里用的是 MySQL:

# service mysqld start
# chkconfig mysqld on
# service rabbitmq-server start
# chkconfig rabbitmq-server on

修改 MySQL 绑定地址,以便其他的节点服务器也能访问这个数据库:

# vi /etc/my.cnf
...
#bind-address           = 127.0.0.1
bind-address            = 0.0.0.0
...

# service mysql restart

创建一个名为 nova 的数据库,并设置 root 从任何 IP 访问的权限和密码:

# mysql -uroot -ppassword -e 'CREATE DATABASE nova;'
# mysql -uroot -ppassword -e "GRANT ALL PRIVILEGES ON *.* TO \
'root'@'%' WITH GRANT OPTION;"
# mysql -uroot -ppassword -e "SET PASSWORD FOR \
'root'@'%' = PASSWORD('password');"

配置 Nova:

$ sudo vi /etc/nova/nova.conf
--verbose=false
--ec2_url=http://172.16.39.111:8773/services/Cloud
--s3_host=172.16.39.111
--cc_host=172.16.39.111
--rabbit_host=172.16.39.111
--sql_connection=mysql://nova:nova@172.16.39.111/nova
--glance_api_servers=172.16.39.111:9292
--use_s3=true
--libvirt_type=kvm
--use_syslog=false
--node_availability_zone=nova
--logdir=/var/log/nova
--logging_context_format_string=%(asctime)s %(name)s: %(levelname)s [%(request_id)s %(user)s %(project)s] %(message)s
--logging_default_format_string=%(asctime)s %(name)s: %(message)s
--logging_debug_format_suffix=
--use_cow_images=true
--auth_driver=nova.auth.dbdriver.DbDriver
--network_manager=nova.network.manager.VlanManager
--scheduler_driver=nova.scheduler.zone.ZoneScheduler
--image_service=nova.image.glance.GlanceImageService
--use_ipv6=false
--ca_path=/var/lib/nova/CA
--keys_path=/var/lib/nova/keys
--images_path=/var/lib/nova/images
--buckets_path=/var/lib/nova/buckets
--instances_path=/var/lib/nova/instances
--networks_path=/var/lib/nova/networks
--dhcpbridge_flagfile=/etc/nova/nova.conf
--dhcpbridge=/usr/bin/nova-dhcpbridge
--injected_network_template=/usr/share/nova/interfaces/
--libvirt_xml_template=/usr/share/nova/libvirt.xml.template
--vpn_client_template=/usr/share/nova/client.ovpn.template
--credentials_template=/usr/share/nova/novarc.template
--state_path=/var/lib/nova
--lock_path=/var/lib/nova/tmp
--vnc_enabled=true
--vncproxy_url=http://172.16.39.111:6080
--vncserver_host=0.0.0.0
--vnc_token_ttl=300

每次重启一堆服务很麻烦,写个脚本方便重启 nova 所有服务:

# vi nova-restart-all.sh
#!/bin/bash
for n in api compute network objectstore scheduler vncproxy; do service openstack-nova-$n restart; done
service openstack-glance-api restart
service openstack-glance-registry restart

# chmod +x nova-restart-all.sh

# ./nova-restart-all.sh

使用 Nova

接下来的步骤和在 Ubuntu 上安装和配置 OpenStack Nova 差不多,这里就不再赘述:

# nova-manage db sync
# nova-manage network create 192.168.0.0/24 1 255
# nova-manage floating create 10.10.10.2 10.10.10.224/27
# nova-manage user admin vpsee
# nova-manage project create mycloud vpsee

导出权限信息:

# mkdir /home/vpsee/creds
# nova-manage project zipfile mycloud vpsee /home/vpsee/creds/novacreds.zip

# cd /home/vpsee/creds
# unzip novacreds.zip
# chown -R vpsee:vpsee /home/vpsee/creds/

# source /home/vpsee/creds/novarc

再次重启 nova 相关的所有服务:

# ./nova-restart-all.sh

如果一切正常的话,应该可以看到下面的类似信息,这样 OpenStack Nova 就成功安装了:

# euca-describe-availability-zones verbose
AVAILABILITYZONE	nova	available
AVAILABILITYZONE	|- node00	
AVAILABILITYZONE	| |- nova-network	enabled :-) 2011-08-16 19:28:13
AVAILABILITYZONE	| |- nova-compute	enabled :-) 2011-08-16 19:28:22
AVAILABILITYZONE	| |- nova-scheduler	enabled :-) 2011-08-16 19:28:14

启动第一个实例

启动实例之前需要先上传一个系统模版(称之为镜像 image),自己制作 image 有点麻烦,可以参考:为 OpenStack Nova 制作 Ubuntu 镜像为 OpenStack Nova 制作 Windows 镜像

有了 image 后就可以启动实例了,就像在 C++/Java 等面向对象语言里面有了类(class)以后可以创建实例(instance)一样,这里有了 OS image 以后就可以创建 OS instance 了。启动和访问实例可以看这篇 的相关部分。

安装 OpenNebula 基于 Web 的管理控制台

我们一般用 onehost/onevm/onevnet 这些命令行工具来管理 OpenNebula 云计算平台,不过有个项目组开发了 OpenNebula Management Console 管理工具,基于 PHP 和 MySQL,安装和配置也不是很复杂,和配置普通 CMS 系统差不多。上周我们在两台服务器上安装和配置了一个最小的 OpenNebula 云计算平台,我们将在生产环境测试一段时间 OpenNebula,争取能用 OpenNebula 替换我们自己的脚本,并逐步用这个平台来统一管理我们的 Xen 服务器。VPSee 周末试了试这个基于 Web 界面的 OpenNebula 管理工具,界面简单清晰,使用也很方便。这个控制台管理工具(onemc)只能安装在前端(Front-End)服务器上。

安装必备软件包

onemc 是基于 PHP 和 MySQL 的,需要安装一些必要的软件包:

# yum install php php-mysql mysql-server php-curl php-xmlrpc httpd \
php-pear php-devel php-adodb

下载 onemc

下载和解压 onemc-1.0.0.tar.gz 后直接放在 apache 的默认目录里(懒得改 httpd.conf):

# cd /var/www/html
# wget http://dev.opennebula.org/attachments/download/128/onemc-1.0.0.tar.gz
# tar zxvf onemc-1.0.0.tar.gz
# cd onemc

配置数据库

# mysql -uroot -p
Enter password: 
mysql> create database onemc;
mysql> create user 'oneadmin'@'localhost' identified by 'oneadmin';
mysql> grant all privileges on onemc.* to 'oneadmin'@'localhost';
mysql> \q

# mysql -u oneadmin -p onemc < /var/www/html/onemc/include/mysql.sql

配置 onemc

# vi /var/www/html/onemc/include/config.php
...
// vmm: kvm or xen
$vmm = "xen";
...
// ADODB settings
$adodb_type = "mysql";
$adodb_server = "localhost";
$adodb_user = "oneadmin";
$adodb_pass = "oneadmin";
$adodb_name = "onemc";
...

登录

如果系统设置了 http_proxy 环境变量的话一定要先关闭,然后重启 one 和 httpd:

# unset http_proxy
# one stop; one start
# /etc/init.d/httpd restart

打开 http://172.16.39.110/onemc/index.php 页面后就会显示登录信息(172.16.39.110 是 OpenNebula 前端的 IP 地址),用户名和密码是安装和配置 OpenNebula 的时候在 one_auth 中设置的密码(cat "oneadmin:password" > one_auth)。

opennebula management console

在 CentOS 上安装和配置 OpenNebula

我们提到的云计算一般有三种类型:软件即服务(Software as a Service, SaaS),平台即服务(Platform as a Service, PaaS)和基础架构即服务(Infrastructure as a Service, IaaS)。云概念刚出来的时候被人说的云里雾里摸不着头,现在云技术已经深入人心,也许你正在使用云而自己没有察觉呢,比如每天使用的 Gmail 就在 Google 大云上。为了更好理解这三种不同的云,我们可以拿 Google 来举例,刚好这家公司提供了三种形式的云服务,首先看 SaaS,Google Gmail/Docs/Gtalk/Maps 这些 Apps 都运行在 Google 云上,所以他们为普通用户提供了 “软件即服务”;Google 同时提供面向开发人员的 AppEngine,可以让开发人员在他们的平台(Platform)上使用 Python, Java 等语言和他们提供的 API 开发软件和服务,所以他们为开发人员提供了 “平台即服务”;Google 自己内部构建了基于 GFS, BigTable, MapReduce 之上的庞大基础云设施,为自己内部人员提供了 “基础架构即服务”,这就是三种不同类型的云。

OpenNebula 是一套开源的云计算基础管理工具,用来方便管理员在数据中心统一部署、创建、分配和管理大量的虚拟机,企业数据中心可以利用这套工具搭建自己的私有云,为自己内部提供 IaaS 服务,类似的开源产品还有 OpenStack, CloudStack, Eucalyptus, openQRM 等等。以下的安装过程在 VPSee 的两台装有 CentOS 5.5 系统的服务器上完成,一台服务器做 OpenNebula 前端(node00),另一台服务器用来做节点(node01),搭建一个最小的 “云”,如果想扩展这个云的话,只需要逐步增加节点(node02, node03, …)就可以了。如果对其他类似的开源云计算平台感兴趣的话可以看看:在 Ubuntu 上安装和配置 OpenStack Nova,最新的 OpenNebula 4.0 安装看这里:在 CentOS 6.4 上安装和配置 OpenNebula 4.0.

安装和配置前端(Front-End)

增加 CentOS Karan 源:

# cd /etc/yum.repos.d
# wget http://centos.karan.org/kbsingh-CentOS-Extras.repo
# yum update

安装 OpenNebula 需要的软件包以及编译 OpenNebula 源代码所需的工具:

# yum install gcc gcc-c++ make openssl-devel flex bison

# yum install ruby ruby-devel ruby-docs ruby-ri ruby-irb ruby-rdoc
# yum install rubygems
# gem install nokogiri rake xmlparser

# yum install scons
# yum install xmlrpc-c xmlrpc-c-devel

CentOS 自带的 sqlite 版本不行,需要下载和编译 sqlite 3.6.17 版本:

# wget http://www.sqlite.org/sqlite-amalgamation-3.6.17.tar.gz
# tar xvzf sqlite-amalgamation-3.6.17.tar.gz
# cd sqlite-3.6.17/
# ./configure; make; make install

下载和编译 opennebula 2.0.1 源码包后,解压、编译和安装:

# tar zxvf opennebula-2.0.1.tar.gz
# cd opennebula-2.0.1
# scons
# ./install.sh -d /srv/cloud/one

# ls /srv/cloud/one/
bin  etc  include  lib  share  var

启动 OpenNebula 前需要配置 ONE_AUTH 环境变量,这个环境变量从 $HOME/.one/one_auth 这个文件读取,所以要先创建 one_auth 这个文件后再启动 one(OpenNebula 服务程序):

# cd /root/
# mkdir .one
# cd .one/
# echo "oneadmin:password" > one_auth

# one start

OpenNebula 支持 KVM, Xen 和 VMware 三种虚拟技术,我们还需要告诉 OpenNebula 我们想用哪种,并重启 one 以便配置生效:

# vi /etc/one/oned.conf
...
IM_MAD = [
    name       = "im_xen",
    executable = "one_im_ssh",
    arguments  = "xen" ]

VM_MAD = [
    name       = "vmm_xen",
    executable = "one_vmm_ssh",
    arguments  = "xen",
    default    = "vmm_ssh/vmm_ssh_xen.conf",
    type       = "xen" ]
...

# one stop
# one start

安装和配置节点(Compute Node)

需要在每个 node 上都安装 Xen 或 KVM 的虚拟环境,具体请参考:在 CentOS 上安装和配置 Xen在 CentOS 上安装和配置 KVM,还需要 ruby 运行环境:

# yum install ruby 

交换 SSH Key

因为 OpenNebula Front 和 Nodes 之间是通过 SSH 通讯的,所以 front 和 nodes 之间要设置成 SSH 无密码登录避免 front 运行 node 上脚本或克隆镜像的时候输入密码,首先在 front 和 nodes 上配置 sshd:

# vi /etc/ssh/sshd_config
RSAAuthentication yes
PubkeyAuthentication yes

# /etc/init.d/sshd restart

在 front (node00) 上创建 key 后拷贝到 node (node01):

# ssh-keygen -t rsa
# ssh-copy-id -i ~/.ssh/id_rsa.pub node01

在1个 node (node01) 上创建 key 后拷贝到 front (node00):

# ssh-keygen -t rsa
# ssh-copy-id -i ~/.ssh/id_rsa.pub node00

onehost

front 和 每个 node 都能无密码 ssh 沟通后,就可以在 front 上 onehost create 命令来逐个加入 node,并用 onehost list 来查看是否创建成功:

# onehost create node01 im_xen vmm_xen tm_ssh

# onehost list
  ID NAME              CLUSTER  RVM   TCPU   FCPU   ACPU    TMEM    FMEM STAT
  1 node01     default    0    400    400    400    3.8G    383M   on

如果执行 onehost create 报错,查看 oned.log 日志发现 sudo: sorry, you must have a tty to run sudo 字样,原因则是 OpenNebula 需要远程 ssh/sudo 执行命令,而 CentOS 的 sudo 选项 requiretty 是默认打开的,ssh 需要一个 tty 才能执行,所以远程 sudo 就会出错,:

# onehost create node01 im_xen vmm_xen tm_ssh

# tail /var/log/one/oned.log 
Tue Feb 22 11:08:58 2011 [InM][I]: Command execution fail: 'if [ -x "/var/tmp/one/im/run_probes" ]; then /var/tmp/one/im/run_probes xen 172.16.39.111; else                              exit 42; fi'
Tue Feb 22 11:08:58 2011 [InM][I]: STDERR follows.
Tue Feb 22 11:08:58 2011 [InM][I]: sudo: sorry, you must have a tty to run sudo
Tue Feb 22 11:08:58 2011 [InM][I]: Error executing xen.rb
...

解决办法就是关闭(注释掉) requiretty 这行:

# chmod 600 /etc/sudoers
# vi /etc/sudoers
#Defaults    requiretty

因为 VPSee 的这两台服务器使用了 HTTP 代理上网,所以 OpenNebula 读取了系统的 http_proxy 环境变量,在 sched.log 日志里发现了 HTTP response 错误,这时候需要关闭 http_proxy:

# cat /var/log/one/sched.log
Tue Feb 22 14:27:39 2011 [HOST][E]: Exception raised: Unable to transport XML to server and get XML response back.  HTTP response: 504
Tue Feb 22 14:27:39 2011 [POOL][E]: Could not retrieve pool info from ONE

# unset http_proxy

onevnet

创建和编辑虚拟网络配置文件,然后创建一个 OpenNebula 虚拟网络:

# vi small_network.net
NAME = "Small network"
TYPE = FIXED

BRIDGE = br0
LEASES = [ IP="192.168.0.5"]
LEASES = [ IP="192.168.0.6"]
LEASES = [ IP="192.168.0.7"]

# onevnet create small_network.net 

# onevnet list
  ID USER     NAME              TYPE BRIDGE P #LEASES
   0 oneadmin Small network    Fixed    br0 N       0

onevm

创建和编辑虚拟机的启动配置文件,这里的 centos.5.5.x86.img 可以从 http://stacklet.com/ 下载(收费)或者自己利用 Xen 工具创建一个:

# wget http://stacklet.com/sites/default/files/centos/
centos.5.5.x86.img.tar.bz2
# tar jxvf centos.5.5.x86.img.tar.bz2
# mv centos.5.5.x86.img /srv/cloud/one/var/images/

# vi centos.one 
NAME   = centos
CPU    = 1
MEMORY = 256

DISK = [
  source   = "/srv/cloud/one/var/images/centos.5.5.x86.img",
  target   = "sda1",
  clone    = "yes",
  readonly = "no" ]

NIC = [ MAC = "00:16:3E:00:02:64", bridge = br0 ]

OS = [ bootloader     = "/usr/bin/pygrub" ]

用 onevm create 命令启动上面的 VM 配置文件,就会在 node01 上创建一个虚拟机,用 onevm list 查看会看到 prol 状态,表示正在创建过程中,创建完毕后状态会变成 runn:

# onevm create centos.one

# onevm list
   ID     USER     NAME STAT CPU     MEM  HOSTNAME        TIME
    1 oneadmin   centos prol   0      0K  node01   00 00:09:09

# onevm list
   ID     USER     NAME STAT CPU     MEM  HOSTNAME        TIME
    1 oneadmin   centos runn   0      0K  node01   00 00:22:17

就这样,我们在 node00 (front) 和 node01 (node) 这两台服务器上部署了一个最小的云,并且在 node01 上运行了一个基于 Xen 的虚拟机实例。

在 CentOS 上安装和配置 OpenVZ

经常有人问到 OpenVZ 和 Xen 哪个好,事实上 OpenVZ 和 Xen 不是同一层面的技术,OpenVZ 是操作系统层面(Operating system-level virtualization)的虚拟产品,和 FreeBSD Jail, Solaris Zone, Linux-VServer 等类似;而 Xen 和 VMware, KVM, Hyper-V 等产品站在同一阵营。OpenVZ VPS 实际上提供的是一个虚拟环境(Virtual Environment/VE),也叫容器(Container);而 Xen VPS 提供的是基于 Hypervisor 的虚拟机(Virtual Machine),这是本质上的不同,现在大家已经习惯用 VPS 这个名字把这两种不同的产品和技术混为一谈了。比起 Xen 专注于企业虚拟化和云计算领域,OpenVZ 最大的应用可能就在低端 VPS 市场,有无数的 VPS 服务商都使用 OpenVZ 提供10美元以下的 VPS 产品。了解一下 OpenVZ 的安装和配置也会对使用 OpenVZ VPS 有所帮助,以下的安装和配置操作在 VPSee 的一台空闲 PC 和 CentOS 5.5 上完成。对 Xen 和 KVM 感兴趣的童鞋请看:在 CentOS 上安装和配置 Xen在 CentOS 上安装和配置 KVM.

安装 OpenVZ

首先加入 openvz 源、升级系统、安装 openvz 内核和 vzctl, vzquota 等工具:

# cd /etc/yum.repos.d
# wget http://download.openvz.org/openvz.repo
# rpm --import http://download.openvz.org/RPM-GPG-Key-OpenVZ
# yum update

# yum install ovzkernel
# yum install vzctl vzquota

调整内核参数

为了能让 VE/VPS 访问外部网络,我们必须启动 ip forwarding;如果内核出错或者运行很慢,我们希望能用特殊按键 dump 一些信息到控制台并结合 log 排错,所以建议打开 kernel.sysrq:

# vi /etc/sysctl.conf
...
net.ipv4.ip_forward = 1
kernel.sysrq = 1
...

为了减少麻烦最好关闭 selinux,selinux 带来的麻烦往往比得到的好处多:

# vi /etc/sysconfig/selinux
...
SELINUX=disabled
...

检查 vz 服务是否自动启动,并重启机器进入 openvz 内核:

# chkconfig --list vz 
vz             	0:off	1:off	2:on	3:on	4:on	5:on	6:off

# reboot

创建和安装 guest

Perl 语言之父 Larry Wall 说过真正优秀的程序员有三大优良品质:偷懒,没有耐性和骄傲自大。所以能利用别人的劳动成果就不要自己重造轮子。我们可以到 http://download.openvz.org/template/precreated/ 下载已经安装好的模版,有 centos, debian, ubuntu, fedora, suse 等几个模版可以选择:

# cd /vz/template/cache
# wget http://download.openvz.org/template/precreated/ubuntu-10.04-x86.tar.gz

有了 ubuntu 10.04 的模版以后就可以用这个模版来创建 guest 系统(VE/VPS)了,以刚下载的 ubuntu-10.04-x86 为模版创建一个 ID 为 1 的 Virtual Environment (VE),并指定 IP 地址、DNS 服务器地址、主机名、磁盘空间等,创建成功后启动 ID 为 1 的 VE,最后修改 root 密码:

# vzctl create 1 --ostemplate ubuntu-10.04-x86

# vzctl set 1 --onboot yes --save
# vzctl set 1 --ipadd 172.16.39.110 --save
# vzctl set 1 --nameserver 8.8.8.8 --save
# vzctl set 1 --hostname vps01.vpsee.com --save
# vzctl set 1 --diskspace 10G:10G --save

# vzctl start 1
# vzctl exec 1 passwd

启动、重启、关闭和断电关闭 ID 为 1 的 VE/VPS:

# vzctl start 1
# vzctl restart 1
# vzctl stop 1
# vzctl destroy 1

查看正在运行中的 VE/VPS:

# vzlist
      CTID      NPROC STATUS    IP_ADDR         HOSTNAME
         1          8 running   172.16.39.110   vps01.vpsee.com

计算 ID 为 1 的 VE/VPS 用到的资源:

# vzcalc -v 1
Resource     Current(%)  Promised(%)  Max(%)
Low Mem          0.06       1.44       1.44
Total RAM        0.19        n/a        n/a 
Mem + Swap       0.08       1.30        n/a
Alloc. Mem       0.11       1.62       3.09
Num. Proc        0.01        n/a       0.32
--------------------------------------------
Memory           0.19       1.62       3.09

进入 guest

VE 成功启动后就可以进入系统了,相当于 xen 的 xm console,不过从 VE 退出来不需特殊按键直接 exit 就可以:

# vzctl enter 1
entered into CT 1
root@vps01:/# exit
logout
exited from CT 1

在 CentOS 5.5 上升级 Xen 到 Xen 3.4.3

2008年 RedHat 收购 Qumranet 以后就一直在家搞他的 KVM,没有对 Xen 做任何升级,RHEL/CentOS 5.5 上默认的 Xen 依旧是很老很老的公元2007年发布的 Xen 3.1.2 版本。更糟糕的是 RedHat 在后续的 RedHat Enterprise Linux 6 里彻底放弃了 Xen. 如果以后想在新版本的 RHEL/CentOS 上用 Xen 的话就需要使用第三方源或者自己动手编译 Xen 源代码。自己编译源代码问题多多,看看前面那篇文章留下的150多个评论就知道会遇到多少麻烦了,所以没有特殊要求的话,VPSee 还是建议直接使用第三方源。

# cd /etc/yum.repos.d/
# wget http://www.gitco.de/repo/GITCO-XEN3.4.3_x86_64.repo
# yum update
# reboot

如果上面的 yum update 没问题的话重启系统就可以了进入 xen 3.4.3 了,如果有问题导致一些依赖需要解决的话可以彻底删除 xen 后重新升级安装:

# yum groupremove Virtualization
# yum groupinstall Virtualization
# reboot

在重启之前最好检查一下 grub 是否配置正确、默认启动是否是 xen.gz-3.4.3:

# vi /boot/grub/menu.lst
...
title CentOS (2.6.18-194.26.1.el5xen)
        root (hd0,0)
        kernel /xen.gz-3.4.3
        module /vmlinuz-2.6.18-194.26.1.el5xen ro root=LABEL=/
        module /initrd-2.6.18-194.26.1.el5xen.img
...

在 CentOS 上安装和配置 KVM

RedHat 的下一代旗舰产品 RedHat Enterprise Linux 6 将只包含 KVM,这一点 RedHat 官方已经在很久以前、在不同场合都确认过,也可以从 RHEL 6 的 Beta 版本中得到证实。KVM 发展很快,稳定性有了很大提高,随着 RHEL 6 的正式到来,KVM 应用到生产环境的日子应该不远了。VPSee 曾经测试过 KVM,也看过一些 KVM 的学术论文,在网络性能、扩展、稳定性方面 KVM 不如 Xen,这些因素是做 VPS 的关键,所以现在很少看到 KVM VPS,不知道 RHEL 6 以后会不会多起来,目前 KVM 应用比较少的还有一个原因就是对硬件要求高(CPU 需要 Intel VT 或 AMD SVM 的支持),硬件发展速度很快,以后应该不会有这个问题。由于 KVM 支持全虚拟,所以可以在上面安装各类操作系统,和 Xen HVM 一样。在 VPSee 看来,KVM 更适合做桌面一些,Xen 更适合做数据中心解决方案。以下操作在 SUN Fire X2100 服务器和 CentOS 5.5 上完成。对 OpenVZ 和 Xen 感兴趣的童鞋可以看:在 CentOS 上安装和配置 OpenVZ在 CentOS 上安装和配置 Xen.

检查 CPU

和 Xen 不同,KVM 需要有 CPU 的支持(Intel VT 或 AMD SVM),在安装 KVM 之前检查一下 CPU 是否提供了虚拟技术的支持:

# egrep 'vmx|svm' /proc/cpuinfo
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca 
cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt 
rdtscp lm 3dnowext 3dnow pni cx16 lahf_lm cmp_legacy svm 
extapic cr8_legacy
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca 
cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt 
rdtscp lm 3dnowext 3dnow pni cx16 lahf_lm cmp_legacy svm 
extapic cr8_legacy

安装 KVM

安装 KVM 所需要的软件包:

# yum install kvm kmod-kvm qemu kvm-qemu-img virt-viewer virt-manager \
libvirt libvirt-python python-virtinst

或者

# yum groupinstall KVM

安装完后重启系统,然后确认一下是否安装成功:

# reboot

# lsmod | grep kvm
kvm_amd                69416  0 
kvm                   226208  1 kvm_amd

# ls -l /dev/kvm 
crw-rw---- 1 root kvm 10, 232 Jun 25 15:56 /dev/kvm

安装虚拟机

用 virt-install 安装,这里以安装 FreeBSD 8.0 为例,os-variant 可以选择 freebsd7:

# virt-install \
--name freebsd \
--ram 512 \
--vcpus=1 \
--disk path=/home/vpsee/freebsd.img,size=4 \
--network network:default \
--os-variant=freebsd7 \
--accelerate \
--cdrom /home/vpsee/8.0-RELEASE-i386-disc1.iso \
--vnc

如果需要获得 virt-install 命令的更多选项和参数,可以查看在线帮助:

# man virt-install

用 virt-viewer 打开控制台连上 FreeBSD 的安装界面:

# virt-viewer freebsd

也可以直接用 virt-manager 图形化安装,安装过程很简单,KVM 中没有 Xen dom0, domU 的概念,更容易理解和使用,任何用过 VMware 和 VirtualBox 的人都会很容易上手,启动 virt-manager 图形界面创建一个虚拟机,创建硬盘、配置内存网络、指定安装光盘 iso 等,一步一步傻瓜操作:

# virt-manager

Tips

安装完 KVM 和上面的 FreeBSD 以后,以后就可以通过 virsh 命令行工具来启动、关闭、重启、进入控制台的工具来操作虚拟机了,就和在 Xen 里使用 xm 一样:

# virsh --connect qemu:///system
start freebsd
console freebsd
quit

如果你在客户端使用 Mac 或者 Linux 的话,而且没有 vnc viewer 之类的工具的话,可以直接用 ssh 和 X 连接到正在安装 FreeBSD 的那个控制台上:

# ssh -X -C root@172.16.20.1
# virt-viewer freebsd

freebsd kvm console