为 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),注释或删除以前的,加上 UUID=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 镜像

Hello World, OpenNebula Cloud API 编程

先报告一下我们云计算项目的进度。去年休假前订购的服务器和部件已经陆续到货了,计算节点采用的是 Dell PowerEdge M710HD 刀片服务器,特别为数据中心级虚拟应用设计,海量内存、密集 IO 吞吐等优势,特别适合云计算、虚拟机等应用。现在正在等 Dell 的售后技术人员过来安装服务器和存储阵列,有些电源和机柜问题需要解决,顺利的话下周服务器可以上线。

dell poweredge m710hd

OpenNebula 提供了 XML-RPC 的方式访问 OpenNebula Cloud Api (OCA),这样就允许不同操作系统、不同语言编写的客户端程序可以通过 XML-RPC 远程调用的方式来访问 OpenNebula 服务。下面通过两个不同语言编写的最简单例子抛砖引玉一下,来看看如何是如何与 OCA 打交道的。

OpenNebula 绝大部分是由 Ruby 编写的,其提供的 Ruby OCA API 实现当然是最丰富和完整的。先安装 Ruby OCA Bindings:

$ sudo gem install oca

用 Ruby 编写一小段代码试验一下,以下代码用来打印当前云里每个计算结点的 hostname:

#!/usr/bin/ruby

require 'rubygems'
require 'oca'

include OpenNebula

# OpenNebula credentials
CREDENTIALS = "oneadmin:vpsee"

# XML_RPC endpoint where OpenNebula is listening
ENDPOINT    = "http://localhost:2633/RPC2"

client = Client.new(CREDENTIALS, ENDPOINT)
host_pool = HostPool.new(client)
rc = host_pool.info

# Print all the hostname from the host pool
host_pool.each do |host|
     puts host.name
end

再来看看用 Python 如何编写上面类似功能的代码。安装 Python OCA Bindings:

$ sudo easy_install oca

用 Python 编写一小段代码看一下:

#!/usr/bin/python

import oca

# OpenNebula credentials
CREDENTIALS = "oneadmin:vpsee"

# XML_RPC endpoint where OpenNebula is listening
ENDPOINT    = "http://localhost:2633/RPC2"

client = oca.Client(CREDENTIALS, ENDPOINT)
host_pool = oca.HostPool(client)
host_pool.info()

# Print all the hostname from the host pool
for host in host_pool:
    print host.name

应该没人会想在这种情况下用 Java 或 C++ 吧,Programming Examples 里面提供的 Java OCA 和 C++ 例子比 Ruby, Python 复杂得多。

重置 OpenStack Nova 数据库

如果使用 OpenStack 的时候遇到莫名其妙的问题,或者直接操作 OpenStack 数据表的时候把里面的关系或记录搞砸了,或者使用一些从网上抄来连自己都不理解的命令把数据库记录弄乱了,或者自己想推倒重来等等,碰到这些问题的时候大家想到的第一个办法就是“重装系统,重装 OpenStack”,其实大部分时候都不必要重装,只需要重置一下数据库就可以了,避免重复劳动把操作命令整理到下面的简单脚本里:

#!/bin/bash
# Reset nova database and restart nova services
# written by vpsee.com

# Delete the database and create a new one
mysql -u root -ppassword -e "drop database nova;"
mysql -u root -ppassword -e "create database nova;"
mysql -u root -ppassword -e "set password for 'root'@'%'=password('password');"
mysql -u root -ppassword -e "grant all privileges on *.* to 'root'@'%';"

# Sync up the database scheme
nova-manage db sync

# Create a network
nova-manage network create private 10.0.1.0/24 1 256
nova-manage floating create 192.168.2.240/28

# Create a admin user and a project and assign the admin user to it
nova-manage user admin vpsee
nova-manage project create vpseecloud vpsee

# Restart all the services
restart libvirt-bin
restart nova-api
restart nova-scheduler
restart nova-network
restart nova-volume
restart nova-compute

# Create novarc
nova-manage project zipfile vpseecloud vpsee
unzip nova.zip
. novarc

# Allowing icmp and ssh access to instances
euca-authorize -P icmp -t -1:-1 default
euca-authorize -P tcp -p 22 default

# Create a keypair
euca-add-keypair vpsee > vpsee.priv
chmod 600 vpsee.priv

明年你准备采用 OpenStack 吗?

Zenoss 在最近的一次 OpenStack 会议和 Zenoss 开源社区做了一个调查,772份问卷调查结果显示约有75%的人正在考虑部署 OpenStack,其中40%的人明年就动手。大家选择 OpenStack 的理由主要是因为和 VMware vSphere 等商业云计算平台相比 OpenStack 能有效节约成本和避免被锁定在某个厂商。

openstack adoption survey

删除 OpenStack Nova Volume 时遇到的 error_deleting 问题

前段时间 VPSee 在 OpenStack Nova 上删除一个 volume 的时候(vol-00000002)报错,检查了一下 volume 的状态是 error_deleting 然后就无法删除了,不管用 euca-delete-volume 还是 nova-manage volume delete 都无法删除。

# euca-delete-volume vol-00000002
ApiError: ApiError: Volume status must be available

# euca-describe-volumes
VOLUME	vol-00000002  10  nova	error_deleting (mycloud, node01, None, None)	2011-08-30T13:15:24Z
VOLUME	vol-00000003  10  nova	available (mycloud, node01, None, None)	2011-08-30T13:20:04Z

查了一下要删除的 volume-00000002 的情况:

# lvdisplay
...
--- Logical volume ---
  LV Name                /dev/nova-volumes/volume-00000002
  VG Name                nova-volumes
  LV UUID                UgOwdr-W61E-MrdG-PrdY-IToa-LBi8-2XJjXF
  LV Write Access        read/write
  LV Status              available
  # open                 0
  LV Size                10.00 GiB
  Current LE             2560
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           251:2
...

既然用工具没法删除的话就干脆从数据库里直接删除,无非就是一条记录而已,先从 nova 数据库里找到这条 volume 记录并设置状态为 deleted,然后删除实际对应的 LVM. 从数据库里找到相应的表和记录后设置 status 为 deleted 状态:

# mysql -u root -p
Enter password:

mysql> use nova;

mysql> select status,id from volumes;
+----------------+----+
| status         | id |
+----------------+----+
| creating       |  1 |
| error_deleting |  2 |
| available      |  3 |
+----------------+----+
3 rows in set (0.00 sec)

mysql> update volumes set status='deleted' where id='2';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

退出 mysql 数据库操作回到命令行就会看到 vol-00000002 的状态是 deleted 的,然后用 lvmremove 命令删除:

# euca-describe-volumes
VOLUME	vol-00000002  10  nova	deleted (mycloud, node01, None, None)	2011-08-30T13:15:24Z

# ls /dev/nova-volumes/
volume-00000002 volume-00000003

# lvremove /dev/nova-volumes/volume-00000002
Do you really want to remove active logical volume volume-00000002? [y/n]: y
  Logical volume "volume-00000002" successfully removed

最后用 nova-manage 命令从数据库里彻底删除 vol-00000002(当然也可以直接在 mysql 里用 SQL 语句操作删除对应的记录 DELETE FROM volumes WHERE id=’2′;):

# nova-manage volume delete vol-00000002

# euca-describe-volumes
VOLUME	vol-00000003  10  nova	available (mycloud, node01, None, None)	2011-08-30T13:20:04Z

OpenStack Nova 的存储管理

OpenStack Nova 创建出来的 instance 不是所有的类型都有存储的,比如 m1.tiny: Memory: 512MB, VCPUS: 1, Storage: 0GB, FlavorID: 1, Swap: 0MB, RXTX Quota: 0GB, RXTX Cap: 0MB 的存储就是 0,也就是说关闭 m1.tiny 类型的 instance 后所有数据都会丢失。OpenStack Nova 使用 nova-volume 服务来管理存储,可以把这种服务看成云计算时代的 USB,可以随时 attach 到 instance 上做额外存储,其实现和 Amazon 的 Elastic Block Storage (EBS) 不同,nova-volume 提供的是一种基于 Linux LVM 的 iSCSI 解决方案。

Nova-volume 需要一个单独的分区做 LVM,如果系统上没有多余的分区做 LVM 的话可以用一个文件来充当硬盘,当然这种方法只能自己测试玩玩,应用到生产环境最好还是用物理硬盘上的分区做 LVM.

新建一个文件来做 LVM:

# dd if=/dev/zero of=/home/vpsee/nova-volumes.img bs=1M seek=100000 count=0
# losetup -f nova-volumes.img

# losetup -a
/dev/loop0: [fb00]:24120015 (/home/vpsee/nova-volumes.img)

# vgcreate nova-volumes /dev/loop0
  No physical volume label read from /dev/loop0
  Physical volume "/dev/loop0" successfully created
  Volume group "nova-volumes" successfully created

# pvscan
  PV /dev/sda5    VG node01         lvm2 [465.52 GiB / 48.00 MiB free]
  PV /dev/loop0   VG nova-volumes   lvm2 [97.65 GiB / 77.65 GiB free]
  Total: 2 [563.17 GiB] / in use: 2 [563.17 GiB] / in no VG: 0 [0   ]

默认情况下 iscsitarget 软件包安装后并没有自动启动,所以需要手动配置和启动 iscsitarget 服务:

# vi /etc/default/iscsitarget
ISCSITARGET_ENABLE=true

# service iscsitarget start
 * Starting iSCSI enterprise target service

新建一个大小为 10GB 的 volume,检查一下是否创建成功(available),并把刚创建的 volume 附加到正在运行的 instance 上,附加成功后再次检查 volume 的状态就变成 in-use 了:

# euca-create-volume -s 10 -z nova
VOLUME	vol-00000003	10	creating (mycloud, None, None, None)	2011-08-30T13:20:04Z

# euca-describe-volumes
VOLUME	vol-00000003	 10		nova	available (mycloud, node01, None, None)	2011-08-30T13:20:04Z

# euca-describe-instances
RESERVATION	r-i5927300	mycloud	default
INSTANCE	i-00000031	ami-00000006	172.16.39.224	172.16.39.224	running	mykey.priv (mycloud, node01)	0		m1.tiny	2011-08-26T07:12:57Z	nova		

# euca-attach-volume -i i-00000031 -d /dev/vdb vol-00000003
VOLUME	vol-00000003

# euca-describe-volumes
VOLUME	vol-00000003	 10		nova	in-use (mycloud, node01, i-00000031[node01], /dev/vdb)	2011-08-30T13:20:04Z

如果想从运行的 instance 上卸载 volume 的话用 euca-detach-volume,卸载成功的话就会看到 volume 的状态又变回 available 了:

# euca-detach-volume vol-00000003
VOLUME	vol-00000003

# euca-describe-volumes
VOLUME	vol-00000003	 10		nova	available (mycloud, node01, None, None)	2011-08-30T13:20:04Z

OpenStack Nova 安装后的 FlatManager 网络配置

这篇在 Ubuntu 上安装和配置 OpenStack Nova 的评论比较多,至少有6位网友遇到 ping 不通的问题,说实话 ping 不通的原因有很多(最常见的是 euca-authorize 授权问题),如果没有提供有用信息只是留下一句“ping 不通”很难判断问题所在,建议大家以后留言的时候尽量把自己的情况说清楚,尽量多的提供一些信息。OpenStack Nova 的网络设置很复杂,controller 上可以有多个网卡,compute 上也可以有多网卡,controller 和 compute 的网络设置还可以不同,并且每个设置还可以分为 FlatManager, FlatDHCPManager, VlanManager,每个 project 允许不同的网络设置,并且每个 user 可以创建多个 project 和 network,晕了吧-~

这里只介绍最简单的一种情况,只有一个网卡、一个 user 创建一个 project 和 network、直接使用现有的局域网 IP 地址不干扰现有网络。就是说把安装好的 OpenStack Nova Controller/Compute 并入到现有的局域网里,在 Nova 上创建的 instance 通过 bridge 使用现有局域网的 IP(而不是另建一个私有网络)。比如 VPSee 实验室现在已经有了 172.16.38.0/23 这个网络,如何利用这个网络和配置 OpenStack Nova 呢?

先检查一下 Nova 的配置文件:

$ sudo vi /etc/nova/nova.conf
--logdir=/var/log/nova
--state_path=/var/lib/nova
--lock_path=/var/lock/nova
--verbose
--s3_host=172.16.39.111
--rabbit_host=172.16.39.111
--cc_host=172.16.39.111
--ec2_url=http://172.16.39.111:8773/services/Cloud
--FAKE_subdomain=ec2
--sql_connection=mysql://root:vpsee@172.16.39.111/nova
--glance_host=172.16.39.111
--image_service=nova.image.glance.GlanceImageService
--my_ip=172.16.39.111
--network_manager=nova.network.manager.FlatManager
--fixed_range=172.16.38.0/23
--num_networks=1
--flat_injected=true

看看 bridge 网卡配置是否正确:

$ sudo vi /etc/network/interfaces
auto lo
iface lo inet loopback

auto br100
iface br100 inet static
address 172.16.39.111
netmask 255.255.254.0
gateway 172.16.38.1
bridge_ports eth0
bridge_stp off
bridge_maxwait 0
bridge_fd 0

如果修改了上面的配置需要重启 Nova 的各个模块和 Ubuntu 的网络,怕麻烦的话还是直接重启系统吧:

$ sudo reboot

如果 nova-manage network list 发现有以前留下的网络需要 delete 掉,删除所有以前残留的网络然后重新创建一个 172.16.38.0/23 新网络:

$ sudo nova-manage network delete 192.168.3.0/24 1 255

$ sudo nova-manage network create 172.16.38.0/23 1 512

$ sudo nova-manage network list
network           	netmask        	start address  	DNS
172.16.38.0/23    	255.255.254.0  	172.16.38.2    	8.8.4.4

因为有些 IP 地址是我们局域网正在用的,新建的 VM 不能占用这些 IP,所以需要划分一些 IP 留给 OpenStack Nova 用,需要进入数据库后修改 fixed_ips 这个表的 reserved 为 0,比如我们想把 172.16.39.222-226 这5个 IP 留给 OpenStack Nova instances:

$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 135
Server version: 5.1.54-1ubuntu4 (Ubuntu)

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use nova;
Database changed

mysql> update fixed_ips set reserved = '1';
Query OK, 6 rows affected (0.00 sec)
Rows matched: 1448  Changed: 6  Warnings: 0

mysql> update fixed_ips set reserved = '0' where address='172.16.39.222';
mysql> update fixed_ips set reserved = '0' where address='172.16.39.223';
mysql> update fixed_ips set reserved = '0' where address='172.16.39.224';
mysql> update fixed_ips set reserved = '0' where address='172.16.39.225';
mysql> update fixed_ips set reserved = '0' where address='172.16.39.226';

重启 OpenStack Nova 的各个模块,然后新建一个 ubuntu instance 测试一下是否得到了正确的 IP 并能 ping 通网关(172.16.38.1)。

在 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 了。启动和访问实例可以看这篇 的相关部分。

创建新的 OpenStack Nova 实例类型

正在准备这篇博客的时候有位朋友刚好在 在 Ubuntu 上安装和配置 OpenStack Nova 里问到一个类似的问题:

koory – July 19th, 2011 10:18 am
vpsee你好!实例资源如何修改,实例默认启动内存都是512M,我想修改成1G,怎么操作?

OpenStack Nova 默认提供了一些虚拟机配置的实例类型,比如:

$ sudo nova-manage instance_type list
m1.medium: Memory: 4096MB, VCPUS: 2, Storage: 40GB, FlavorID: 3, Swap: 0GB, RXTX Quota: 0GB, RXTX Cap: 0MB
m1.large: Memory: 8192MB, VCPUS: 4, Storage: 80GB, FlavorID: 4, Swap: 0GB, RXTX Quota: 0GB, RXTX Cap: 0MB
m1.tiny: Memory: 512MB, VCPUS: 1, Storage: 0GB, FlavorID: 1, Swap: 0GB, RXTX Quota: 0GB, RXTX Cap: 0MB
m1.xlarge: Memory: 16384MB, VCPUS: 8, Storage: 160GB, FlavorID: 5, Swap: 0GB, RXTX Quota: 0GB, RXTX Cap: 0MB
m1.small: Memory: 2048MB, VCPUS: 1, Storage: 20GB, FlavorID: 2, Swap: 0GB, RXTX Quota: 0GB, RXTX Cap: 0MB

新建一个云实例(云虚拟机或云 VPS)的时候就从这些实例配置类型里面选择一个配置,然后以这个配置来启动云实例,这些默认的实例类型是固定的,内存、CPU、硬盘等参数都是固定的,默认只有5个类型:m1.small, m1.tiny, m1.medium, m1.large 和 m1.xlarge. 如果我们需要一个 256MB,硬盘 10GB,VCPU 1个的云实例怎么办呢?可以用 nova-manage instance_type create 创建一个新的实例类型,比如创建一个名字为 m1.xtiny 的新类型:

$ sudo nova-manage instance_type create m1.xtiny 256 1 10 0 0 0
m1.xtiny created

上面 256 1 10 0 0 0 这一串分别表示:内存,VCPU,硬盘大小,SWAP 大小,RXTX quotas 和 RXTX cap. 如果不记得这些参数的顺序的话,可以看看联机的 nova-manage instance_type create 帮助说明:

$ sudo nova-manage instance_type create
Possible wrong number of arguments supplied
instance_type create: Creates instance types / flavors
           arguments: name memory vcpus local_gb flavorid [swap] [rxtx_quota]
                      [rxtx_cap]

然后查看一下 m1.xtiny 是否创建成功:

$ sudo nova-manage instance_type list
...
m1.xtiny: Memory: 256MB, VCPUS: 1, Storage: 10GB, FlavorID: 0, Swap: 0GB, RXTX Quota: 0GB, RXTX Cap: 0MB
...

如果想删除刚刚创建的 m1.xtiny 也很容易:

$ sudo nova-manage instance_type delete m1.xtiny
m1.xtiny deleted

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

OpenStack 基于 Web 的管理控制台 OpenStack Dashboard 是用 Python 和 Django 框架写的,部署到生产环境比较麻烦,没有基于 PHP 的 web 程序那么直观,不过 OpenStack Dashboard 项目正在快速开发中,还不稳定,一般不会用到生产环境,所以想试玩的话用 Django 自带的 web server 就可以了。如果想部署到生产环境建议用 apache + mod_wsgi 的方式,这也是 django 官方建议部署 django app 的方式。

安装版本控制工具和 python 虚拟环境:

$ sudo apt-get install -y git bzr
$ sudo easy_install virtualenv

下载 openstack dashboard 源代码并运行 run_tests.sh:

$ git clone https://github.com/4P/openstack-dashboard.git
$ cd openstack-dashboard
$ sudo sh run_tests.sh

如果上面的最新 git 代码不好用,需要找旧版本的 openstack dashboard,需要使用 bzr 从 launchpad 下载(今年6月份 openstack dashboard 项目从 launchpad 移到 github)。最新的 64 版本使用了最新的 django 1.3,安装没问题但是访问的时候显示 ViewDoesNotExist 错误,所以 VPSee 建议使用旧的 46 版本(django 1.2.4):

$ bzr init-repo .
$ bzr branch lp:openstack-dashboard
$ cd openstack-dashboard
$ bzr revert -r 46
$ sudo sh run_tests.sh

安装脚本里用到了 git,如果你的网络环境需要代理才能上网的话需要配置一下 git 使用 http 代理服务器

对照 在 Ubuntu 上安装和配置 OpenStack Nova 一文并在 /home/vpsee/creds/novarc 文件里找到 NOVA_ACCESS_KEY, NOVA_SECRET_KEY 等相关信息填写以下参数:

$ vi openstack-dashboard/local/local_settings.py
...
NOVA_DEFAULT_ENDPOINT = 'http://172.16.39.111:8773/services/Cloud'
NOVA_DEFAULT_REGION = 'nova'
NOVA_ACCESS_KEY = '22781cf0-b8b6-44e8-86c8-baf8d3827662:mycloud'
NOVA_SECRET_KEY = '2dc4007f-3425-417b-a598-33a190d2f995'
NOVA_ADMIN_USER = 'vpsee'
NOVA_PROJECT = 'mycloud'
...

同步数据库的时候需要创建一个 superuser 访问 django web:

$ source .dashboard-venv/bin/activate

$ sudo tools/with_venv.sh dashboard/manage.py syncdb
Creating table auth_permission
...
Creating table registration_registrationprofile

You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no):

$ sudo tools/with_venv.sh dashboard/manage.py runserver 172.16.39.111:8000
Validating models...
0 errors found

Django version 1.2.4, using settings 'dashboard.settings'
Development server is running at http://172.16.39.111:8000/
Quit the server with CONTROL-C.

现在打开浏览器输入 http://172.16.39.111:8000/ 就应该可以看到登录界面,输入刚才创建的 superuser 的用户名和密码后就可以进入控制台了。控制台的功能有限,没有命令行那么丰富,不过基本的创建、查看、关闭 instance 功能还是有的:

openstack dashboard