OpenStack模块代码结构
1.简介
在开始介绍各个OpenStack服务的Puppet模块前,先观察一下所有OpenStack module的目录结构,你会发现所有的模块的部分代码目录结构和命名方式几乎是一致的,这是经过了长期迭代和开发中形成的规范和统一,代码结构统一带来的好处有两点:
易于维护人员理解和管理
减少冗余代码,提高代码复用
那么我们就来看看一个OpenStack服务的Module中包含了哪些目录:
examples/ 放置示例代码
ext/ 放置external代码,和主要代码无关,但是一些有用的脚本
lib/ 放置library代码,例如自定义facter,resource type
manifests/ 放置puppet代码
releasenotes/ 放置releasenote
spec/ 放置class,unit,acceptance测试
tests/ 已弃用,使用examples替代
以上目录中最重要的是manifests目录,用于放置Puppet代码,在该目录下包含了以下通用代码文件:
名称
说明
init.pp
主类,也称为入口类,通常仅用于管理公共参数(如MQ参数)
params.pp
用于特定操作系统的参数值设置
client.pp
管理客户端的配置
config.pp
用于管理自定义的参数配置
policy.pp
policy设置
db/
支持多种数据库后端的配置
keystone/
keystone endpoint,service,user,role的设置
2.数据库管理
2.1 class <service>::db
class <service>::dbclass <service>::db用于管理各OpenStack服务中的数据库相关配置,<service>是OpenStack服务的名称,以Aodh为例:
class aodh::db管理了与数据库相关的配置项,其中通过调用oslo::db来实现,关于puppet-oslo模块,本书会在下一章节详细说明。
2.2 class <service>::db::mysql
class <service>::db::mysqlclass <service>::db::mysql用于创建相关服务的MySQL数据库,用户和授权等。以Aodh为例:
class aodh::db::mysql管理了MySQL aodh数据库的创建,aodh用户创建和密码设定,数据库编码,访问授权等。其调用了openstacklib::db::mysql来实现上述功能,关于puppet-openstacklib模块,本书会在下一章节详细说明。
2.3 class <service>::db::postgresql
class <service>::db::postgresqlclass <service>::db::mysql用于创建相关服务的PostgreSQL数据库,用户和授权等。以Aodh为例:
class aodh::db::postgresql完成了aodh数据库的创建,aodh用户创建和密码设定,数据库编码,访问授权等。其调用了openstacklib::db::postgresql来实现上述功能。
2.4 class <service>::db::sync
class <service>::db::syncclass aodh::db::sync用于执行数据库表的初始化和更新操作。以Aodh为例:
aodh::db::sync的实现是通过声明exec资源来调用aodh-dbsync命令行完成数据库初始化的操作。
3. Keystone初始化管理
在OpenStack部署工作中,与Keystone相关的初始化操作是集群正常运行必不可少的步骤:
创建Domain
创建Project
创建User,设置Password
创建并指定Role
创建Service
创建Endpoint
也包括在后期的运维中,指定user的password更新或者endpoint的更改等常见操作都可以在Puppet中完成。而这背后的工作是通过<service>::keystone::auth来完成的。
3.1 class <service>::keystone::auth
class <service>::keystone::auth<service>::keystone::auth用于创建OpenStack服务的user,service和endpoint,以Aodh为例:
实际上aodh::keystone::auth在声明define keystone::resource::service_identity的基础上,根据Aodh服务而重写了相关的参数。
下面来看一段代码,关于keystone::resource::service_identity如何实现service的管理:
通过函数ensure_resource调用了keystone_service自定义资源类型,并传入两个参数:
"${service_name_real}::${service_type}"
{'ensure' => $ensure, 'description' => $service_description,}
有细心的读者读到这里可能会好奇,把服务名称和服务类型作为一个参数传入keystone_service,它是怎么区分的?
先来看keystone_service.rb的代码片段(代码路径puppet-keystone/lib/puppet/type/keystone_service.rb):
title_patterns方法通过调用PuppetX::Keystone::CompositeNamevar.basic_split_title_patterns方法来得到:name和:type变量。
接着跳转到basic_split_title_patterns的定义(代码路径lib/puppet_x/keystone/composite_namevar.rb):
可以看到basic_split_title_patterns方法默认使用'::'作为分隔符,通过not_two_colon_regex函数进行正则匹配并切割字符串。 至此,我们从上到下地剖析了如何实现Keystone相关资源的初始化,以加深读者对于代码的理解。在实际使用中,对于终端用户来说,并不需要关心底层的Ruby代码。
3.2 class <service>::keystone::authtoken
class <service>::keystone::authtoken<service>::keystone::authtoken用于管理OpenStack各服务配置文件中的keystone_authtoken配置节。以Aodh服务为例:
aodh::keystone::authtoken定义中声明了define keystone::resource::authtoken,并重写了部分参数的默认值。 keystone::resource::authtoken中定义了hash类型变量$keystonemiddleware_options,涵盖了keystone_authtoken配置节下的所有参数, 最终通过调用create_resources函数,传入服务名称参数$name,从而完成指定服务配置文件中keystone_authtoken的配置。
4.维护不同Linux发行版之间的数据
PuppetOpenstack支持在Redhat, CentOS, Ubuntu等多个Linux发行版上部署OpenStack服务,然而在不同的Linux发行版中,同一个OpenStack服务的软件包的名称会有所不同。
例如,Nova API软件包的名称在Redhat下是'openstack-nova-api',在Debian下是'nova-api'。
而这些数据则通过各个模块的class <service>::params维护。
以keystone::params为例,可以看到不同的Linux发行版之间$package_name, $service_name等参数值也有所不同:
5. 管理自定义配置项的<service>::config
<service>::config模板是用于管理配置文件的常见方式,对于成熟的项目而言,模板是一种理想的管理配置文件方式。但对于快速迭代的项目如OpenStack,维护人员会非常痛苦,每增删一个配置项需要同时更新模板和manifets文件。
试想一个module的更新若都在参数的增添上,那对社区开发者来说是极大的成本。有没有一种办法可以不修改module,直接在hiera里定义来添加新配置项呢?
<service>::config类是由笔者在14年初提出的特性,目的是灵活地管理自定义配置项。
自定义配置项是指未被模块管理的参数。怎么理解?
以keystone::config为例,其核心是create_resources函数以及keystone_config/keystone_paste_init自定义资源:
若Keystone在某版本新增了参数new_param,在puppet-keystone模块里没有该参数,此时,只要使用keystone::config就可以轻松完成参数的管理。
在hiera文件中添加以下代码:
6.管理客户端 <service>::client
<service>::client<service>::client用于管理各OpenStack服务的Client端,完成客户端的安装。
以Nova为例,nova::client完成了python-novaclient软件包的安装:
7. 管理策略<service>::policy
<service>::policy<service>::policy用于管理Openstack各服务的策略文件policy.json。
以Cinder为例,下面是cinder::policy代码:
其中使用create_resources调用了openstacklib::policy::base,以及声明了oslo::policy定义。
Last updated
Was this helpful?