在 KVM 上访问 FreeBSD 虚拟机终端

在移植旧的物理服务器到虚拟机的时候还剩一些非 Linux 系统没有移,主要是 FreeBSD 和 Solaris 系统,还有几台 OpenBSD 的,这些系统大部分运行在很古老的机器上,有的甚至比我的 FreeBSD on IBM TP600E 还老,需要问一下管理员这些机器在干嘛,是否能合并到虚拟机,管理员刚好这周请假去了 WWDC 现场。

提到今年的 WWDC,看完发布会视频又要扯一下了,比较激动的是那个 2880×1800 屏幕的 MacBook Pro,码农实在太需要关怀了,任何每天看电脑8小时以上的人都需要好显示器,Life is short,对自己好点,Get a Mac:)

做了 FreeBSD for KVM 的镜像以后需要能在 KVM 上像访问 Linux 虚拟机终端那样访问 FreeBSD 的虚拟机终端,步骤和在 Linux 上差不多。

在 FreeBSD Guest 上配置

登陆 FreeBSD 后添加和编辑 loader.conf 文件:

# vi /boot/loader.conf
console="comconsole"

在 /etc/ttys 最后加上 ttyd0 一行:

# vi /etc/ttys
...
# Serial terminals
#ttyu0   "/usr/libexec/getty std.9600"   dialup   off secure
ttyu0   "/usr/libexec/getty std.9600"   vt100   on secure
...

重启 FreeBSD:

# reboot

确定 virsh edit 有下面这几行:

# virsh edit freebsd
...
    <serial type='pty'>
      <target port='0'/>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <video>
      <model type='cirrus' vram='9216' heads='1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>
...

必要时重启 libvirtd:

# /etc/init.d/libvirtd restart
Stopping libvirtd daemon:                                  [  OK  ]
Starting libvirtd daemon:                                  [  OK  ]

freebsd console on kvm

迟到的 “软文”:42区 VPS

4月7日,我们(vpsee.com + 42qu.com)正式向外发布了北京机房(东直门双线数据中心)。从不认识张沈鹏、收第一封邮件、邮件讨论可行性、邮件继续讨论、选机房、租用机柜、讨论服务器配置、购买服务器、服务器上线、安装系统、优化和配置 Xen 环境、整理客户数据到开通第一个 VPS 只用了4天~

发布当天我正忙着去外地开会,已经 check in 正排队登机,忽然手机提示收到一封邮件,多背一公斤的朋友从我们的加州 OC 机房换到刚开的北京机房后出现问题,VPS 的文件系统只读不能写,囧,赶快跑到前面和空姐 mm 打个招呼,处理一点急事,打开 Mac 连上服务器以后没发现啥问题,没时间细看赶紧给 plan 留言,plan 确认后我就盖上 Mac 登机了。下机后,手机收到 plan 的邮件说已经解决,晚上回到 hotel 后再次检查了 VPS 情况,一切正常。发布的第一天很平静,没有想的那么忙,没有新客户:(

大概介绍一下我们的服务器、机房、团队、开发、⋯⋯

服务器

我们北京 VPS 的服务对象主要面向初创公司,所以北京机房服务器(host)的配置很强悍,全部采用 Dell 服务器:

型号:Dell PowerEdge R710
CPU:2x Intel Xeon CPU E5645 @2.40GHz
硬盘:6x 1TB SAS (15K), Hardware RAID 10

机房

服务器托管在北京东直门数据中心和北京石景山七线数据中心。

北京东直门数据中心是占地约7000平方米的电信级宽带数据中心机房,在北京地区处于专业 IDC 市场领先地位,也是当当网等知名网站托管的机房。

北京石景山七线数据中心是北京少见的 BGP 七线机房 , 由北京数据家联合北京市政府和北京市发改委出资2个亿共同搭建联通、电信属于内网,在联通和电信线路上,与中国西单电报大楼机房50G内部直联,与中国电信和中国铁通分别是 42G 和 40G 直联核心交换层,骨干延迟小于10ms,8G直联清华大学教育网骨干核心节点,仅1跳路由,与赛尔网同级别,是各大运营商中与教育网的最大直联带宽。内部直联15G独立国际出口带宽直插国际局,良好的国外访问。机房经典客户:PPlive、新浪网、赛迪网、开心网、土豆网。

团队

有必要给大家简单介绍一下我们的团队。42区是一家创业公司,专注于创业社交网络,分享心得、经验、数据、文章,找到给你答案的人。(另:42区的源代码是开源的,有兴趣的同学可以在自己的服务器/VPS 上搭建一个运行平台。)

张沈鹏(42qu.com 的作者和创始人,前豆瓣程序员)
plan(前阿里云程序员,前百度运维)
vpsee(你懂的~)

开发

vps.42qu.com:后台的用户注册、自助购买、自动开通、自助续费和重装、IP 管理、提成链接等功能已开发完成并已上线运行,还有一些功能比如:自助管理等功能还在陆续开发中。因为团队里除了 VPSee 是打酱油的其他的队友都是 Python 高手,所以 Python 也是我们的首选语言,采用 Tornado 轻量级 Web 框架,使用 Thrift 通讯。

vpsee.com:删除了第三方商业客户管理系统 WHMCS,这套系统不适合中国人的使用习惯,ticket 基本没人用,客户都喜欢用 Gtalk/Gmail/QQ/MSN 即时通信的方式寻求技术帮助和处理问题。新的 VPS 后台管理程序已投入运行,5月底重启了美国机房的所有 VPS 开始使用新的管理程序。

服务

现在,我们可以利用我们的跨时区优势为客户提供真正意义上的 24×7 技术响应和服务,并提供手机、电话等方式。试着北京时间凌晨3点给我们 42qu 技术支持丢一封邮件 (^_-)

成长

3月20日收到张沈鹏的一封邮件,略去来来回回几千字的邮件,开始着手做这件事;
3月24日北京机房第一台服务器上架运行,同一天,开通第一个 VPS;
4月7日正式对外发布 VPS 产品,并在 V2EX 上发布广告;
5月9日增加北京石景山七线数据中心;
6月9日北京机房运行中的 VPS 达到100台,绝大部分是 2G VPS 客户。

42qu VPS 第一台服务器:

42qu vps first server, dell r710

在 KVM 上访问 Linux 虚拟机终端

用 OpenNebula 制作 Ubuntu 镜像后可以用这个镜像当作模版来创建 OpenNebula 虚拟机,发现一个问题是,这个 KVM 虚拟机(guest)无法在母机(host)上用 virsh console 登陆和显示终端,这是因为那个模板没有引入 console 需要的参数,而且虚拟机里面也没有做相关的设置。解决办法分两步,首先登陆到虚拟机修改一些配置;然后在运行这个虚拟机的 KVM 节点(host)上修改虚拟机的 xml 配置文件。以下介绍虚拟机是 Ubuntu 和 CentOS 的两种配置情况,FreeBSD 配置情况可以参考:在 KVM 上访问 FreeBSD 虚拟机终端

在 Ubuntu Guest 上配置

登陆 ubuntu 虚拟机增加 ttyS0.conf 文件及其内容:

$ sudo vi /etc/init/ttyS0.conf
# ttyS0 - getty
#
# This service maintains a getty on ttyS0 from the point the system is
# started until it is shut down again.
start on stopped rc RUNLEVEL=[2345]
stop on runlevel [!2345]
respawn
exec /sbin/getty -L 38400 ttyS0 vt102

如果不只是希望 Linux login 后看到终端,也希望看到 Linux 的启动过程的话需要在 /etc/default/grub 加入 GRUB_CMDLINE_LINUX 一行,记得运行 update-grub2 自动配置 grub:

$ sudo vi /etc/default/grub
...
GRUB_CMDLINE_LINUX_DEFAULT="console=ttyS0"
...

$ sudo update-grub2

在 CentOS Guest 上配置

在 /etc/securetty 文件末尾追加 ttyS0 一行:

# echo “ttyS0″ >> /etc/securetty

在 /etc/grub.conf 文件里的 kernel 一行增加 console=ttyS0:

# vi /etc/grub.conf
...
title CentOS (2.6.32-220.el6.x86_64)
        root (hd0,0)
        kernel /vmlinuz-2.6.32-220.el6.x86_64 ro root=/dev/mapper/VolGroup-lv_roo
ot rd_NO_LUKS LANG=en_US.UTF-8 rd_NO_MD rd_LVM_LV=VolGroup/lv_swap SYSFONT=latarr
cyrheb-sun16 rhgb crashkernel=auto quiet rd_LVM_LV=VolGroup/lv_root  KEYBOARDTYPP
E=pc KEYTABLE=us rd_NO_DM console=ttyS0
        initrd /initramfs-2.6.32-220.el6.x86_64.img
...

在 /etc/inittab 中增加 ttyS0 一行:

# vi /etc/inittab
...
S0:12345:respawn:/sbin/agetty ttyS0 115200

在 KVM Host 上配置

登陆 KVM 母机(host)用 virsh edit 修改虚拟机的 KVM 启动配置文件,在 device 下面加上 serial 一栏:

# virsh list
Id Name State
----------------------------------
49 one-28 running

# virsh edit one-28
...
<device>
...
    <serial type='pty'>
        <target port='0'/>
    </serial>
    <console type='pty'>
        <target type='serial' port='0'/>
    </console>
...
</devices>

修改后重启 libvirtd,并手动关闭和启动虚拟机:

# /etc/init.d/libvirtd restart
Stopping libvirtd daemon:                                  [  OK  ]
Starting libvirtd daemon:                                  [  OK  ]

# virsh shutdown one-28
# virsh start one-28

在 CentOS 6.2 上安装和配置 Foreman

服务器(物理机器和虚拟机)多了以后需要工具来管理,经常登陆系统后不知是在虚拟机上还是在物理机上?如果在虚拟机上这个虚拟机运行在哪个服务器节点(host)上?如果在物理机上运行在什么配置的物理机上?运行在 Dell 刀片服务器上还是 IBM 超级计算机上,SUN 服务器上还是普通 PC 上?这个系统 IP 是多少?域名是啥?有几个网卡?分别走的哪个交换机?有没有连到 SAN 存储等等?无数问题,我们需要一个统一查看和管理所有机器(物理机和虚拟机)的这么一套工具。Foreman 就是这么一个集成了 Puppet 的统一机器生命周期管理工具。

Foreman 功能很强大,可以解决硬件或虚拟机上线到运行 Puppet 之间的一切问题,比如安装操作系统、配置网络、配置 DNS、Puppet 客户端安装认证等等,完成必要的上线工作后,Foreman 就把剩下的工作交给了 Puppet,Puppet 完成剩下的服务器和服务配置工作,这样就完美的完成了从服务器上线到服务上线的全过程,而且是自动的。这里主要介绍用 Foreman 获取(配合 Puppet Facts)和查看服务器信息。

加入 foreman 官方源后安装软件包:

# cat > /etc/yum.repos.d/foreman.repo << EOF
[foreman]
name=Foreman Repo
baseurl=http://yum.theforeman.org/stable
gpgcheck=0
enabled=1
EOF

# yum install foreman

拷贝 foreman 里面的 report 例子到 puppet 下,并更改 $foreman_url 指向这台安装 foreman 的服务器:

# cp /usr/share/foreman/extras/puppet/foreman/templates/foreman-report.rb.erb \
/usr/lib/ruby/site_ruby/1.8/puppet/reports/foreman.rb

# vi /usr/lib/ruby/site_ruby/1.8/puppet/reports/foreman.rb
...
$foreman_url='http://foreman.vpsee.com:3000/'
...

配置 puppetmaster 服务端,编辑 puppet.conf 配置文件:

# vi /etc/puppet/puppet.conf
[main]
...
    reports=log, foreman
...

# /etc/init.d/puppetmaster restart

配置 puppet 客户端,编辑 puppet.conf 配置文件,确保 report 是 true:

# vi /etc/puppet/puppet.conf
...
report = true
...

初始化 foreman 数据库(这里 foreman 默认使用 sqlite,简单、不用任何配置,如果想用 mysql 的话可以参考官方帮助文件):

# cd /usr/share/foreman
# RAILS_ENV=production rake db:migrate

启动 foreman:

# /etc/init.d/foreman start

我们把 foreman 和 puppetmaster 安装在同一个机器上,每次运行这个脚本都会导入新的 facts:

# cd /usr/share/foreman
# rake puppet:import:hosts_and_facts RAILS_ENV=production
(in /usr/share/foreman)
Importing from /var/lib/puppet/yaml/facts
Importing monitor.vpsee.com
Importing dev.vpsee.com
Importing intranet.vpsee.com
Importing datasrv.vpsee.com
Importing rocket.vpsee.com
Importing grid.vpsee.com
Importing proxy.vpsee.com
Importing mail.vpsee.com

导入成功后打开浏览器访问 http://foreman.vpsee.com:3000 就可以看到 foreman 界面了:
foreman

修改 OpenNebula 虚拟机实例的内存大小

OpenNebula 创建虚拟机(实例)以后将不能直接更改虚拟机的配置参数,如 CPU、内存等。如果创建虚拟机以后发现内存给的太大,想改小怎么办呢?如何给 OpenNebula 上的虚拟机修改内存呢?(注:OpenNebula 没有直接操作的命令,需要到节点上用 virsh setmem 动态修改。)让人不可思议的是,OpenNebula 推荐的方法是删除原有虚拟机以后重新创建一个配置合适的虚拟机,一些云计算平台认为虚拟机(计算资源)应该像自来水一样打开就用,不用就关闭。个人觉得云计算应该至少能随时改变计算资源(配置),而不是删除+创建。

比如下面这个 id 为28的虚拟机实例用了 2GB 内存,想修改到 1GB:

# onevm list
ID USER     GROUP    NAME         STAT CPU     MEM        HOSTNAME        TIME
...
14 root     oneadmin queue        runn   3      1G         cloud06 40 20:38:50
18 root     oneadmin grid03       runn 144     24G         cloud18 39 00:47:01
19 root     oneadmin grid02       runn 143     32G         cloud21 39 00:26:26
28 root     oneadmin monitor      runn   9      2G         cloud03 05 22:04:14
...

首先找到这个28号虚拟机实例所在的 OpenNebula 计算节点(node),从上面的 HOSTNAME 看出 monitor 运行在 cloud03 这个节点上,我们 ssh 到这个节点操作发现这台 OpenNebula ID 为28的虚拟机实例在这个节点上名字为 one-28:

# ssh root@cloud03

# virsh list
 Id Name                 State
----------------------------------
 39 one-20               running
 42 one-25               running
 45 one-28               running

可以动态修改 one-28 的内存参数为 1GB,但是这种办法重启后就会丢失配置重回到 2GB:

# virsh setmem one-28 1048576

所以最好关闭 one-28 后再修改 one-28 配置文件,改动 memory 部分为 1048576(1GB),修改完毕后启动虚拟机:

# virsh shutdown one-28

# virsh edit one-28
...
1048576
...

# virsh start one-28

修改完后 onevm list 会发现 one-28 内存大小依然是 2GB,没有变,这是因为这部分纪录在 OpenNebula 的数据库里,需要修改数据库,先 select 一下发现 OpenNebula 把 VM 的 XML 配置文件写在数据库里,这容易办,用 SQL 语句的 update 操作更新一下数据库:

# sqlite3 /var/lib/one/one.db

sqlite> select * from vm_pool where oid='28';
28|monitor|...2097152...|0|0|1337014904|3|3|1|0|0

sqlite> update vm_pool set body="...1048576..." where oid="28";

然后 onevm list 就会得到正确的、修改过内存的虚拟机实例了:

# onevm list
ID USER     GROUP    NAME         STAT CPU     MEM        HOSTNAME        TIME
...
14 root     oneadmin queue        runn   3      1G         cloud06 40 23:44:51
18 root     oneadmin grid03       runn 144     24G         cloud18 39 03:47:01
19 root     oneadmin grid02       runn 143     32G         cloud21 39 03:32:27
28 root     oneadmin monitor      runn   9   1024M         cloud03 05 01:10:15
...

使用 collectd 和 Graphite 监控服务器

Graphite 只是一个数据绘图工具,安装 Graphite 完以后啥也不能干,需要其他工具喂它数据,所以具体的数据采集工作是由第三方工具完成,Graphite 的设计体现了 Unix 的思想:只做一件事,把事情做好。Graphite 支持的第三方工具很多,Bucky, collectd, Collectl, Charcoal, Diamond, Ganglia, Host sFlow, statsd, Tasseo 等等。这里 VPSee 选用 collectd 来收集机器的各个性能参数,collectd 安装在需要被监控的机器上。

安装 collectd,创建一个 collectd.d 目录便于存放稍后会遇到的插件配置文件 graphite.conf,并在 collectd.conf 包含这个目录 :

$ sudo apt-get install collectd

$ sudo mkdir /etc/collectd/collectd.d
$ sudo vi /etc/collectd/collectd.conf
...
Include      "/etc/collectd/collectd.d"

安装 git 并下载 collectd-carbon 插件:

$ sudo apt-get install git

$ sudo git clone https://github.com/indygreg/collectd-carbon.git /opt/collectd-plugins

修改插件的配置文件的 ModulePath 部分,指向 carbon_writer.py 文件所在目录,并且修改 LineReceiverHost 部分:

$ sudo vi /etc/collectd/collectd.d/graphite.conf
<LoadPlugin "python">
    Globals true
</LoadPlugin>

<Plugin "python">
    # carbon_writer.py is at path /opt/collectd-plugins/carbon_writer.py
    ModulePath "/opt/collectd-plugins/"

    Import "carbon_writer"

    <Module "carbon_writer">
        LineReceiverHost "monitor.vpsee.com"
        LineReceiverPort 2003
        DifferentiateCountersOverTime true
        LowercaseMetricNames true
        TypesDB "/usr/share/collectd/types.db"
    </Module>
</Plugin>

修改好配置文件后重启服务:

$ sudo /etc/init.d/collectd restart

大功告成,等着客户端的 collectd 收集数据发送给监控服务器的 carbon(监听端口为 2003)吧,然后递交给 graphite 绘制图形。

在 Ubuntu 12.04 上安装 Graphite 监控工具

有几个朋友都跟我提过 Graphite,监控工具里面的新秀,一直都没时间关注,最近把 n 台物理服务器用 Puppet 代码化的任务完成后有了不少空闲时间,抽时间看了看 Graphite,先搜了一下中文想看看大家对这个工具有啥看法,居然没人提到这个工具,哪怕一篇博客一个帖子都没有??

常收到一些学生朋友来信,问到一些 Linux、计算机方面的学习建议,VPSee 能给的第一个建议是学好英语,优秀的技术人员必须能熟练的翻阅英文资料,大家也看到了,可用的中文资料真的不多,虽然英文会议我们可以不去、英文技术会议的视频也可以不看,但是平时的一些技术交流邮件、Github、Mailing list、经典技术书籍、文档、好的技术博客等都需要英文。Eric Steven Raymond 在他的那篇有名的 How To Become A Hacker 里也提到了:

If you don’t have functional English, learn it.

如果不能用英语交流,Linus Torvalds 写出来的 Linux 可能也就出不了芬兰,也不会有今天的成功。

废话打住,来看 Graphite.

Graphite 是一个(可运行在廉价硬件上的)企业级开源监控工具,用于采集服务器实时信息并进行统计,可采集 n 个服务器实时状态,如:用户请求消息,Memcached 命中率,RabbitMQ 消息服务器状态、操作系统负载、等等。Graphite 使用 Python 编写,采用 Django 框架,使用自己的简单文本协议通讯,服务平均每分钟有4800次更新操作,简单的文本协议和强大的绘图功能可以方便地扩展到任何需要监控的系统上。

和其他监控工具不同的是,Graphite 自己本身并不收集具体的数据,这些数据收集的具体工作通常由第三方工具或插件完成(如 Ganglia, collectd, statsd, Collectl 等,参考:使用 collectd 和 Graphite 监控服务器)。所以上面说 “Graphite 是一个系统监控工具” 的说法不完全正确,更准确的说法应该是 “Graphite 是一个数据绘图工具”,得到数据后绘图,它并不关心具体数据,你甚至可以把每天收到的邮件数当作参数传给 Graphite 制成图,然后一段时间后就生产一个漂亮的邮件繁忙展示图,并可以看出趋势。

简单的说,Graphite 做两件事:1、存储数据;2、按需绘图。

安装必要软件包:

$ sudo apt-get install apache2 libapache2-mod-wsgi python-django \
python-twisted python-cairo python-pip python-django-tagging

用 pip 安装 whisper (简单的存放和操作数据的库), carbon (监控数据的 Twisted 守护进程) 和 graphite-web (Django webapp):

$ sudo pip install whisper
$ sudo pip install carbon
$ sudo pip install graphite-web

初始化配置,直接用 example 文件里的默认配置就可以:

$ cd /opt/graphite/conf/

$ sudo cp carbon.conf.example carbon.conf
$ sudo cp storage-schemas.conf.example storage-schemas.conf
$ sudo cp graphite.wsgi.example graphite.wsgi

修改 apache 配置,增加一个 vhost 或者偷懒下载一个配置文件覆盖 default,覆盖后需要重新 reload 配置:

$ wget http://launchpad.net/graphite/0.9/0.9.9/+download/graphite-web-0.9.9.tar.gz
$ tar -zxvf graphite-web-0.9.9.tar.gz
$ cd graphite-web-0.9.9
$ sudo cp examples/example-graphite-vhost.conf /etc/apache2/sites-available/default

sockets 最好不要放在 /etc/httpd/ 下面(不同 Linux 发行版本对不同目录的权限问题很混淆人),ubuntu 版本可以放在 /var/run/apache2 下,所以修改 default 文件里的 WSGISocketPrefix 部分:

$ sudo vi /etc/apache2/sites-available/default
...
WSGISocketPrefix /var/run/apache2/wsgi
...

$ sudo /etc/init.d/apache2 reload

初始化 graphite 需要的数据库,修改 storage 的权限,用拷贝的方式创建 local_settings.py 文件:

$ cd /opt/graphite/webapp/graphite/

$ sudo python manage.py syncdb
$ sudo chown -R www-data:www-data /opt/graphite/storage/
$ sudo cp local_settings.py.example local_settings.py

$ sudo /etc/init.d/apache2 restart

启动 carbon:

$ cd /opt/graphite/

$ sudo ./bin/carbon-cache.py start

浏览器访问 IP 地址后就可以看到 graphite web 界面:
graphite

如何使用 Example42 的 Puppet 模块

现在我们差不多移植了100多台服务器到虚拟机,中间合并了很多功能类似的服务器(历史遗留问题)到同一虚拟机,并且整个配置过程完全用 Puppet 代码化,也就是说有一天我们实验室机房遭遇物理毁灭(刚看完 Battleship,有点激动~),只要再给我们合适的硬件设备(异地有备份数据)我们应该能在6小时内恢复整个基础设施(OS, DNS, DHCP, Provision, Firewall, Squid, Web, Database, LDAP, Email, VPN, Kerberos, NFS, HPC, Cloud, Monitor, Backup, …)。自从 Puppet/Chef 之类的自动化配置工具流行以后,现在甚至有了一个新职位叫做 DevOps.

安装好 Puppet 后,就可以开始自己写配置代码了,当然也可以在网上找到别人的配置代码直接拿过来用,更妙的是一些通用的 Puppet 配置代码,比如配置一台 Nginx/PHP/MySQL、配置 NFS、配置 DHCP、配置 DNS、配置 OpenNebula 等等已经有人写成模块了,直接拷过来就可以用了。Example42 就是这样的开源 Puppet 模块大集合,包含了众多常用的服务器配置。

首先去 Example42 下载 Puppet 模块代码:

$ git clone http://github.com/example42/puppet-modules.git

看看 Example42 包含了哪些模块吧,几乎常用的都有,不用自己亲自去写配置:

$ cd puppet-modules/
$ ls
DOCS		example42	mysql		puppi		synbak
Example42-tools	exim		nagios		rails		sysctl
LICENSE		firewall	network		redis		sysklogd
README.rdoc	foo		nfs		repo		syslog-ng
Rakefile	foreman		nginx		resolver	tftp
activemq	git		nrpe		rootmail	timezone
apache		haproxy		ntp		rpmbuild	tomcat
apt		hardening	openldap	rsync		trac
autofs		hosts		openntpd	rsyslog		users
backup		iptables	openssh		samba		vagrant
bind		jboss		openvpn		sarg		varnish
clamav		jenkins		oracle		selinux		virtualbox
cobbler		lighttpd	pam		sendmail	vmware
collectd	link		php		snmpd		vsftpd
common		logrotate	phpsyslogng	spamassassin	wordpress
concat		lsb		portmap		splunk		xinetd
controltier	mailscanner	postfix		sqlgrey		yum
cron		mailx		postgresql	squid		zip
dashboard	mcollective	powerdns	squirrelmail
dhcpd		monit		psad		ssh
dovecot		monitor		psick		ssmtp
drupal		munin		puppet		stdlib42

把上面的 Example42 代码移到 /etc/puppet 目录,然后修改 Puppet 服务器的配置,加上 puppet-modules 模块路径,别忘了重启 puppetmaster 服务:

# mv puppet-modules /etc/puppet

# vi /etc/puppet/puppet.conf
...
[master]
    modulepath = /etc/puppet/puppet-modules

# /etc/init.d/puppetmaster

写个配置文件测试一下,自动配置 PHP + Apache + MySQL:

# vi /etc/puppet/manifests/node.pp

node 'web.vpsee.com' {
    include apache

    include php
    include php::pear
    include php::apc
    php::module { mysql: }
    php::module { curl: }
    php::module { gd: }
    php::module { idn: }
    php::module { imagick: }
    php::module { imap: }
    php::module { mcrypt: }
    php::module { ming: }
    php::module { ps: }
    php::module { pspell: }
    php::module { recode: }
    php::module { snmp: }
    php::module { tidy: }
    php::module { xmlrpc: }
    php::module { xsl: }
    php::module { ldap: }

    include mysql
}

在要配置的机器上执行下面一条命令就自动装上 Apache/PHP/MySQL 了,再不用自己手动去安装配置了:

# puppet agent --test --server=master.vpsee.com

给 Xen 安装 Xen Shell 控制面板

安装完 Xen 后可能需要安装一个控制面板方便用户自己操作虚拟机(VPS)。可以在网上找到一些 Xen 的开源控制面板,有的是基于 Web 的,不过大多数 Xen 控制面板都不完善也不好用,有的还有漏洞,比如2010年的时候 HyperVM 就曝重大安全漏洞,导致多家 VPS 服务商的服务器被黑,客户数据全部丢失,有的服务商甚至因为这个关门了。今天介绍的这个 Xen Shell 控制面板是由 Perl 写的命令行式 Xen 管理工具,包含开启、关闭、重启、查看控制台等功能。

首先到 http://xen-tools.org/software/xen-shell/releases.html 下载最新的 xen-shell 源代码包,解压后安装:

# wget http://xen-tools.org/software/xen-shell/xen-shell-1.9.tar.gz
# tar zxvf xen-shell-1.9.tar.gz
# cd xen-shell-1.9
# make
# make install

修改 xen-shell 的配置文件,加上 banner 然后禁止一些不需要的命令:

# vi /etc/xen-shell/xen-shell.conf

banner = VPSee's VPS Shell
blacklist = version, uptime, shutdown, pause, serial, sysreq, unpause, top, whoami, author, quit

增加一个用户登陆 xen-login-shell 使用 xen-shell 控制面板:

# useradd vpsee
# passwd vpsee

# vi /etc/shells
/usr/bin/xen-login-shell

# chsh -s /usr/bin/xen-login-shell vpsee

在 Xen 虚拟机配置文件里修改 name, xen_shell, vif,如下:

# vi /etc/xen/vpsee

name = "vpsee"
xen_shell = 'vpsee'
bootloader = "/usr/bin/pygrub"
vcpus = 1
maxmem = "512"
memory = "512"
disk = [ "phy:sdb1,xvdb1,w", "phy:sdb2,xvdb2,w" ]
root = "/dev/sdb1 ro"
vif = [ "vifname=vpsee,bridge=xenbr0" ]
on_shutdown = "destroy"
on_poweroff = "destroy"
on_reboot = "restart"
on_crash = "restart"

用新建的用户登陆后运行 xen-shell 后会出现以下错误:

$ /usr/bin/xen-shell 

  There were no Xen configuration files found which matched the pattern:

   /etc/xen/*

  Please update /etc/xen-shell/xen-shell.conf

这是因为刚创建的用户没有权限读取 /etc/xen 目录及 /etc/xen/vpsee 配置文件,所以需要修改 /etc/xen 和 /etc/xen/vpsee 的权限:

# chmod 755 xen

刚创建的用户进入 xen-shell 后需要执行 xm 等相关操作,需要 root 权限,所以要把用户加到 sudoers 里面去:

# chmod 0640 /etc/sudoers
# vi /etc/sudoers
User_Alias   XENUSERS = vpsee
Cmnd_Alias   XEN      = /usr/sbin/xm
Cmnd_Alias   XENIMG   = /usr/bin/xen-create-image
XENUSERS     ALL      = NOPASSWD: XEN,XENIMG

# chmod 0440 /etc/sudoers

用户登陆后仍然不能执行 xm console 等操作,因为找不到路径,所以需要在用户主目录下把 xm 命令的路径包括进去:

# vi /home/vpsee/.bashrc
# User specific aliases and functions
export PATH=$PATH:/usr/sbin/

最后再执行 xen-shell 就可以顺利看到界面了。
vpsee vps shell

在 CentOS 6.2 上安装和配置 KVM

RHEL6 已经推出很久了,没想到在 RedHat 自家的 RHEL6 上安装 KVM 还有这么多问题,难道不应该是像 Apache/MySQL 那样安装完就可以用的么?(注:除去商标,CentOS 就是 RHEL,CentOS6 和 RHEL6 是一回事)。以下操作在 CentOS 6.2 最小化安装版本 CentOS-6.2-x86_64-minimal.iso 上完成,其他版本可能不会遇到本文提到的部分问题。

检查 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 mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm dca sse4_1 sse4_2 popcnt aes lahf_lm ida arat dts tpr_shadow vnmi flexpriority ept vpid

安装 KVM

安装 KVM 很容易,要正常运行的话还需要折腾一下:

# yum -y install qemu-kvm libvirt python-virtinst bridge-utils

安装完后关闭 selinux 并重启系统,然后确认一下是否 kvm 安装成功:

# vi /etc/sysconfig/selinux
SELINUX=disabled

# reboot

# lsmod | grep kvm
kvm_intel              50412  3 
kvm                   305988  1 kvm_intel

# stat /dev/kvm
  File: `/dev/kvm'
  Size: 0         	Blocks: 0          IO Block: 4096   character special file
Device: 5h/5d	Inode: 10584       Links: 1     Device type: a,e8
Access: (0666/crw-rw-rw-)  Uid: (    0/    root)   Gid: (   36/     kvm)
Access: 2012-04-18 16:00:46.276341129 +0200
Modify: 2012-04-18 16:00:46.276341129 +0200
Change: 2012-04-18 16:00:46.276341129 +0200

再来确认一下 libvirt 是否能正常启动和关闭。重启 libvirtd 服务的话会报错,查看日志发现 internal error Failed to create mDNS client 错误,这个问题容易改正,安装 avahi 即可,也可以去 /etc/libvirt/libvirtd.conf 设置 mdns_adv = 0,VPSee 这里采用安装 avahi 的方法:

# /etc/init.d/libvirtd restart
Stopping libvirtd daemon:                                  [FAILED]
Starting libvirtd daemon:                                  [  OK  ]

# tail /var/log/libvirt/libvirtd.log 
2012-04-18 13:51:03.032+0000: 18149: info : libvirt version: 0.9.4, package: 23.el6_2.7 (CentOS BuildSystem , 2012-04-16-14:12:59, c6b5.bsys.dev.centos.org)
2012-04-18 13:51:03.032+0000: 18149: error : virNetServerMDNSStart:460 : internal error Failed to create mDNS client: Daemon not running

# yum -y install avahi
# /etc/init.d/messagebus restart
# /etc/init.d/avahi-daemon restart

重启 libvirtd 服务继续报错,发现缺少 dmidecode 包,安装 dmidecode 后终于重启 libvirtd 成功 :

# /etc/init.d/libvirtd restart
Stopping libvirtd daemon:                                  [FAILED]
Starting libvirtd daemon:                                  [  OK  ]

# tail /var/log/libvirt/libvirtd.log 
2012-04-18 13:54:54.654+0000: 18320: info : libvirt version: 0.9.4, package: 23.el6_2.7 (CentOS BuildSystem , 2012-04-16-14:12:59, c6b5.bsys.dev.centos.org)
2012-04-18 13:54:54.654+0000: 18320: error : virSysinfoRead:465 : internal error Failed to find path for dmidecode binary

# yum -y install dmidecode

# /etc/init.d/libvirtd restart
Stopping libvirtd daemon:                                  [  OK  ]
Starting libvirtd daemon:                                  [  OK  ]

现在 kvm 和 libvirt 都安装成功和运行了,但并不表示可用了,问题接着来。

安装虚拟机

从 6 系列开始 RedHat 推荐使用 virt-install/virsh 系列工具操作 kvm,而不是直接使用 qemu-kvm,所以 qemu-kvm 被移到一个不起眼的地方 /usr/libexec/,做个链接:

# qemu-kvm
-bash: qemu-kvm: command not found

# ls /usr/libexec/qemu-kvm 
/usr/libexec/qemu-kvm

# ln -sf /usr/libexec/qemu-kvm /usr/bin/kvm

VPSee 采用 RedHat 推荐的方式(virt-install)安装虚拟机,这里以安装 ubuntu-11.10-server-amd64.iso 为例:

# virt-install \
--name ubuntu \
--ram 512 \
--vcpus=1 \
--disk path=/root/ubuntu.img,size=10 \
--accelerate \
--cdrom /root/ubuntu-11.10-server-amd64.iso \
--graphics vnc

开始安装,创建硬盘 ubuntu.img 后就报错,用的是 root 帐号居然还 Permission denied?!

Starting install...
Creating storage file ubuntu.img                                 | 10.0 GB     00:00     
ERROR    internal error Process exited while reading console log output: char device redirected to /dev/pts/1
qemu-kvm: -drive file=/root/ubuntu.img,if=none,id=drive-ide0-0-0,format=raw,cache=none: could not open disk image /root/ubuntu.img: Permission denied

Domain installation does not appear to have been successful.
If it was, you can restart your domain by running:
  virsh --connect qemu:///system start ubuntu
otherwise, please restart your installation.

修改 qemu.conf 配置,把下面几个地方的注释去掉,然后把 dynamic_ownership 的值改成0,禁止 libvirtd 动态修改文件的归属:

# vi /etc/libvirt/qemu.conf
...
user = "root"
group = "root"
dynamic_ownership = 0
...

重启 libvirtd 服务再用上面的 virt-install 命令安装就应该可以了。这个时候 vnc 默认绑定的是本机 127.0.0.1,如果其他机器想用 vnc 客户端访问这台 kvm 服务器正在安装的 ubuntu 的话需要把 vnc 绑定到服务器的 IP 地址或者绑定到全局 0.0.0.0. 修改 qemu.conf 文件取消 vnc_listen 一行前面的注释,记得重启 libvirtd:

# vi /etc/libvirt/qemu.conf
...
vnc_listen = "0.0.0.0"
...

在 CentOS 5.x 安装 KVM 可以看:在 CentOS 上安装和配置 KVM.

对 Xen 和 OpenVZ 感兴趣的同学可以参考以下一些文章:

Ubuntu 版本可以参看:在 Ubuntu 上安装和配置 Xen
Debian 版本参看:在 Debian 上安装和配置 Xen
OpenSolaris 版本参看:在 OpenSolaris 上安装和配置 Xen
NetBSD 版本参看:在 NetBSD 上安装和配置 Xen

安装 OpenVZ 参看:在 CentOS 上安装和配置 OpenVZ.