目标是安装一个最小化的 openstack 环境。通过这个过程了解一下构成 openstack 的基本组件都有哪些以及这些组件之间是如何相互配合的。
为了说明起来方便,所有的操作都是以 Ubuntu 12.04 为操作系统进行的。
部署基础服务
首先,openstack 重度依赖 Message Queue 和 Database 两种服务。这里我选择使用 RabbitMQ 和 MySQL 分别来承担相应的角色。
部署 RabbitMQ
RabbitMQ 是一个开源消息中间件。openstack 中很多子系统会依赖它来进行 RPC (Remote Procedure Call) 调用。
安装
- apt-get install rabbitmq-server
- service rabbitmq-server start
配置
RabbitMQ 默认的管理员账户和密码是 guest/guest 。但可以通过下面的命令修改 guest 账户的密码。例如:设置 guest 的密码为 =openstack=。
- rabbitmqctl change_password guest openstack
验证
使用 rabbitmqctl 工具检查 RabbitMQ 是否安装成功,若有状态输出则表示 RabbitMQ 启动成功了。
- rabbitmqctl status
部署 MySQL
MySQL 是最常用的开源数据库。openstack 中几乎所有系统和用户信息都是存储在数据库中的。
安装
由于后面需要编译 python 对 mysql 的支持模块。这里需要一并安装 libmysql++-dev
- apt-get install mysql-server mysql-client libmysql++-dev
- service mysql start
配置
MySQL 服务启动后,首先需要配置管理员(root)的密码。
- mysqladmin -u root password openstack
验证
登陆进 MySQL 跑一个 SQL 来验证安装是否正确,
- mysql -h localhost -u root -p -e 'select version();'
- +-----------------------------+
- | version() |
- +-----------------------------+
- | 5.5.31-0ubuntu0.13.04.1-log |
- +-----------------------------+
安装虚拟化软件
在安装 openstack 之前,还需要安装操作系统对虚拟化支持相关的服务,
- apt-get install libvirt-bin libvirt-dev qemu-kvm
部署 openstack
即使是安装最小化的 openstack 需要启动的服务也是非常多的。为了能够方便调试,要使用 screen 来启动每个服务。 screen 的便利之处在于不用把服务放在后台启动,可以随时 Ctrl+C 中断服务进行调整。
openstack 的源代码可以从他的 Git 仓库获取。代码分支上***选择稳定版本,例如目前的稳定版分支是 stable/grizzly 。选择稳定版本分支的好处是不用为了当前版本的 Bug 耽误时间。当然,如果以尝鲜为目的也可以尝试使用 master 分支进行部署。
在部署和运行这些 openstack 服务的时候,推荐使用 python 的 virtualenv来创建一个独立的 python 运行环境。这是因为 openstack 里面用到的一些 python 库 ubuntu 上可能没有打包,因此这类包就需要通过 pip 进行安装。建立独立 python 运行环境的目的就是为了这类包不干扰系统自身的 python 环境。
每个 openstack 服务都有自己的配置文件,源代码中会包含多个扩展名为 .sample 的例子文件。以这些例子作为基础会让配置简单很多。
#p#
下面开始正式的部署过程,
创建独立的 python 运行环境
- apt-get install virtualenv
- virtualenv openstack-python
- source openstack-python/bin/activate
部署: keystone
keystone 为整个 openstack 系统 AAA (Authentication, Authorization, and Accounting) 服务。在这个最小系统里 keystone 的作用有两个:
- [ ] 提供用户登陆所需的密码验证
- [ ] 通过 keystone 查询各个服务的 endpoint (访问地址)
安装
下载 keystone 源代码,并切换到 grizzly 版本。然后通过 pip 安装依赖的 python 库。
- git clone https://github.com/openstack/keystone.git
- cd keystone
- git checkout stable/grizzly
- pip install -r tools/pip-requires
- pip install mysql-python
配置及初始化
以源码包中的 keystone.conf.sample 为基础,稍作如下修改。并将修改后的文件保存成 keystone.conf 。
- [DEFAULT]
- admin_token = openstack
- debug = True
- verbose = True
- [sql]
- connection = mysql://root:openstack@localhost/keystone
- [signing]
- token_format=UUID
配置文件做好后,需要为 keystone 初始化数据库。
- mysql -h localhost -u root -p -e 'create database keystone';
- bin/keystone-manage --config-dir etc/ db_sync
启动服务
keystone 只有一个服务进程。通过下面的命令启动,
- bin/keystone-all --config-dir etc/
keystone 服务会监听两个端口。其中 5000 端口用于和其他 openstack 组件和 keystone 的交互,被称作 public_port ;另一个端口 35357 用于对 keystone 本身进行管理,被称作 admin_port 。
当 keystone-all 进程启动成功后,可以通过 netstat 检查 端口侦听是否正常。
- jianingy@ubuntu:~$ netstat -lntp | grep -E '5000|35357'
- tcp 0 0 0.0.0.0:5000 0.0.0.0:* LISTEN 9585/python
- tcp 0 0 0.0.0.0:35357 0.0.0.0:* LISTEN 9585/python
安装 keystone 客户端程序
在 keystone 部署完成后,后续有许多要用到他的地方。所以在这里先把 keystone 的客户端程序安装好,以备后用。
- pip install python-keystoneclient
#p#
创建管理员用户
openstack 用户体系简介
openstack 的用户管理是基于 keystone 。也就是说 keystone 的用户体系就是 openstack 的用户体系。
在这个体系里,最基本的单位是 user/(用户)。 /user 在 openstack 里面可以代表一个实际的人,也可以代表一个程序或是服务,也就是所谓的系统用户。无论代表什么 user 是进行登录验证、资源分配的最小实体。
user 对资源的访问通过两个维度来控制。***个维度是 tenant 。 tenant 在 openstack 里面代表用户和资源的集合。一个 tenant 下面可以容纳多个 user ,而这些 user 只有可能访问这个 tenant 里面的资源(虚拟机、镜像、磁盘卷等等)。第二个维度是 role ,role 定义了承载了一组权利。一旦将 role 附加给了一个 user 这个 user 就具备了 role 所具备的权利。两个维度是逻辑与的关系,在一起共同决定 user 是否能访问一个资源。
service 指的是 openstack 里承载具体功能的服务。例如:
- Compute (Nova)
- Object Storage (Swift)
- Image Service (Glance)
- etc …
每一个 openstack 服务通常包含一个或多个 endpoint 。 endpoint 是一个网络上可访问的地址,通常是一个 URL 。这个 URL 指出了对应服务的 API 入口。
配置 openstack 环境变量
openstack 所有其他服务的客户端都需要通过环境变量来获知认证服务(也就是 keystone )的位置以及用于认证的用户信息。为了方便使用,需要写一个包含这些环境变量的脚本 openstackrc 并通过 source 命令引入这些环境变量。
- #!/bin/sh
- export OS_SERVICE_ENDPOINT="http://localhost:35357/v2.0"
- export OS_SERVICE_TOKEN=openstack
- export OS_AUTH_URL="http://localhost:5000/v2.0/"
- export OS_USERNAME=admin
- export OS_PASSWORD=admin
- export OS_TENANT_NAME=admin
这几个参数的作用是:
OS_SERVICE_ENDPOINT
keystone 的管理地址,通常是 35357 端口
OS_SERVICE_TOKEN
验证密令,也就是 keystone 配置文件里的 =admin_token=。相当于进行后台管理用的一个验证码。
OS_AUTH_URL
其他服务调用 keystone 的地址,通常是 5000 端口
OS_USERNAME
普通用户调用 openstack 接口时用的用户名
OS_PASSWORD
与上面 OS_USERNAME 配对使用的密码
OS_TENANT_NAME
用户所要操作 Tenant 的名称
创建用户
通常情况下通过 keystone 创建用户的基本流程是这样的,
keystone-create-user-activity
然而,***次使用 keystone 时还没有 tenant 和 role 存在。因此,在执行上述过程之前还需要先通过 keystone tenant-create来创建一个 tenant ;通过 keystone role-create 来创建一个 role 。openstack 有一个默认的约定:名为 admin 的 role 具备管理权限。
创建用户会是今后经常性的操作并且步骤较多相对繁琐。这里给出一个脚本来简化这些的重复劳动,
- #!/bin/bash
- # filename : keystone-add-user.sh
- # created at : 2013-08-30 16:27:56
- # author : Jianing Yang <a href="mailto:jianingy%40unitedstack.com"><jianingy@unitedstack.com></a>
- until [ -z "$1" ]; do
- case "$1" in
- --tenant)
- shift
- opt_tenant=${1:-service}
- ;;
- --role)
- shift
- opt_role=${1:-admin}
- ;;
- --name)
- shift
- opt_name=$1
- ;;
- esac
- shift
- done
- # find tenant id, create a new one if not exist
- tenant_id=$(keystone tenant-get "$opt_tenant" | awk "/id/{print $4}")
- if [ -z "$tenant_id" ]; then
- keystone tenant-create --name "$opt_tenant" || exit 11
- tenant_id=$(keystone tenant-get "$opt_tenant" | awk "/id/{print $4}")
- [ -z "$tenant_id" ] && exit 11
- fi
- # find role id, create a new one if not exist
- role_id=$(keystone role-get "$opt_role" | awk "/id/{print $4}")
- if [ -z "$role_id" ]; then
- keystone role-create --name "$opt_role" || exit 22
- role_id=$(keystone role-get "$opt_role" | awk "/id/{print $4}")
- [ -z "$role_id" ] && exit 22
- fi
- # find user id, create a new user if not exist
- user_id=$(keystone user-get "$opt_name" | awk "/id/{print $4}")
- if [ -z "$user_id" ]; then
- keystone user-create --name "$opt_name" --pass "$opt_name" --email "$opt_name@localhost" --tenant_id "$tenant_id" || exit 33
- user_id=$(keystone user-get "$opt_name" | awk "/id/{print $4}")
- [ -z "$user_id" ] && exit 33
- fi
- # attach role to user
- keystone user-role-add --user_id "$user_id" --role_id "$role_id" --tenant_id "$tenant_id" | exit 44
使用这个脚本可以轻松地创建出***个用户即管理员用户,
- ./keystone-add-user.sh --tenant admin --role admin --name admin
注册***个服务:keystone
每一个 openstack 的服务都要向 keystone 注册自己的服务地址即 endpoint/。就连 /keystone 自身也不例外。这个注册的过程需通过 keystone 客户端来完成。
- pip install python-keystoneclient
- source openstackrc
- keystone service-create --name=keystone --type=identity --description="Identity Service"
- export KEYSTONE_SERVICE_ID=$(keystone service-list | awk '/keystone/{print $2}')
- keystone endpoint-create
- --region RegionOne
- --service-id=$KEYSTONE_SERVICE_ID
- --publicurl=http://localhost:5000/v2.0
- --internalurl=http://localhost:5000/v2.0
- --adminurl=http://localhost:35357/v2.0
#p#
TODO 部署计算服务: nova
nova 可以说是整个 openstack 系统的核心。负责整个虚拟机生命周期的管理以及周边资源的调度。
安装 nova
与 keystone 的安装过程一样,从 git 仓库中下载源代码并切换至稳定的 stable/grizzly 分支。
- git clone http://github.com/openstack/nova.git
- cd nova
- git checkout stable/grizzly
- pip install -r tools/pip-requires
配置及初始化
正如之前在 openstack 用户体系的描述中提到的, nova 作为一个服务也需要创建一个与之对应的用户,
- ./keystone-add-user.sh --tenant service --role admin --name nova
接下来将用户的登录信息写入配置文件: etc/nova/api-paste.ini 。请对比下列内容进行修改。选项 auth_* 关系到keystone API 的访问。 admin_* 则提供了用户认证所需的信息。
- [filter:authtoken]
- paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory
- auth_host = 127.0.0.1
- auth_port = 35357
- auth_protocol = http
- admin_tenant_name = service
- admin_user = nova
- admin_password = nova
- signing_dir = /tmp/keystone-signing
下面该配置 nova 本身了。以源码包中的 etc/nova/nova.conf.sample 为基础进行配置。将配置好的文件另存为=etc/nova/nova.conf= 。这里我们选用刚刚安装的 libvirt 作为虚拟化后端。
- [DEFAULT]
- auth_strategy=keystone
- compute_driver = libvirt.LibvirtDriver
- sql_connection=mysql://root:openstack@localhost/nova
- debug=true
- verbose=true
- rabbit_host=localhost
- rabbit_port=5672
- rabbit_hosts=$rabbit_host:$rabbit_port
- rabbit_use_ssl=false
- rabbit_userid=guest
- rabbit_password=openstack
- rabbit_virtual_host=/
- rootwrap_config=etc/nova/rootwrap.conf
nova 中的很多操作需要 root 权限来执行。/nova/ 会使用 sudo 来执行这些操作。处于安全考虑 nova 使用被称为 rootwrap 的机制来控制哪些命令可以被 sudo 以 root 权限执行。具体的规则源码中的配置文件已经写好,这里只需要修改下规则文件存放的路径即可。请对比下列配置修改 etc/nova/rootwrap.conf 。
- [DEFAULT]
- # List of directories to load filter definitions from (separated by ',').
- # These directories MUST all be only writeable by root !
- filters_path=etc/nova/rootwrap.d,/usr/share/nova/rootwrap
***,初始化 nova 的数据库,
- mysql -u root -p -e 'create database nova';
- bin/nova-manage --config-dir etc/ --config-file etc/nova/nova.conf db sync
注册 nova 服务
为了让其他服务能找到 nova 的所在,需要在 keystone 里注册 nova 的 endpoint ,
- keystone service-create --name nova --type compute --description 'OpenStack Compute Service'
- export NOVA_SERVICE_ID=$(keystone service-list | awk '/nova/{print $2}')
- keystone endpoint-create --region RegionOne --service-id $NOVA_SERVICE_ID --publicurl 'http://127.0.0.1:8774/v2/%(tenant_id)s' --adminurl 'http://127.0.0.1:8774/v2/%(tenant_id)s' --internalurl 'http://127.0.0.1:8774/v2/%(tenant_id)s'
启动服务
- bin/nova-api --config-dir etc/ --config-file etc/nova/nova.conf
- bin/nova-compute --config-dir etc/ --config-file etc/nova/nova.conf
- bin/nova-conductor --config-dir etc/ --config-file etc/nova/nova.conf
TODO 部署 openstack 管理前端:horizon
安装
- git clone https://github.com/openstack/horizon
- cd horizon
- git checkout stable/grizzly
- pip install -r tools/pip-requires
配置及初始化
horizon 是一个基于 django 写成的前端程序,其配置方式遵循 django 习惯。 horizon 的配置文件位于其源码目录下的openstack_dashboard/local/local_settings.py 。该文件可以基于同目录下的 local_settings.py.example 进行配置。
- cd openstack_dashboard/local
- cp -v local_settings.py{.example,}
启动服务
- python ./manage.py runserver 0.0.0.0:8000
服务启动后就可以通过浏览器进行访问了。